ES: extract 'java.execution' features IDEA-187832

Extract task debugger, JavaRunConfigurationExtensionManager usages, LanguageLevelModuleExtension usages and CompilerConfiguration setup.
Fix ExternalSystemTaskActivator to use ProjectTaskManager listener

GitOrigin-RevId: 27f6369e2a18ab599ec888f634facf9faca4d5d2
This commit is contained in:
Vladislav.Soroka
2019-06-11 18:20:01 +03:00
committed by intellij-monorepo-bot
parent 06362f0446
commit 589035d638
23 changed files with 380 additions and 143 deletions
@@ -22,6 +22,7 @@
<orderEntry type="library" name="intellij-test-discovery" level="project" />
<orderEntry type="library" scope="RUNTIME" name="precompiled_jshell-frontend" level="project" />
<orderEntry type="module" module-name="intellij.platform.externalSystem" />
<orderEntry type="module" module-name="intellij.platform.externalSystem.impl" />
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="library" name="jackson" level="project" />
<orderEntry type="library" name="miglayout-swing" level="project" />
@@ -0,0 +1,77 @@
// 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.execution;
import com.intellij.execution.configurations.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemProcessHandler;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfigurationExtension;
import com.intellij.openapi.options.SettingsEditorGroup;
import org.jdom.Element;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ApiStatus.Experimental
public class ExternalSystemRunConfigurationJavaExtension implements ExternalSystemRunConfigurationExtension {
private static final Logger LOG = Logger.getInstance(ExternalSystemRunConfigurationJavaExtension.class);
@Override
public void readExternal(@NotNull ExternalSystemRunConfiguration configuration, @NotNull Element element) {
JavaRunConfigurationExtensionManager javaRunConfigurationExtensionManager = JavaRunConfigurationExtensionManager.getInstanceOrNull();
if (javaRunConfigurationExtensionManager != null) {
javaRunConfigurationExtensionManager.readExternal(configuration, element);
}
}
@Override
public void writeExternal(@NotNull ExternalSystemRunConfiguration configuration, @NotNull Element element) {
JavaRunConfigurationExtensionManager javaRunConfigurationExtensionManager = JavaRunConfigurationExtensionManager.getInstanceOrNull();
if (javaRunConfigurationExtensionManager != null) {
javaRunConfigurationExtensionManager.writeExternal(configuration, element);
}
}
@Override
public void appendEditors(@NotNull ExternalSystemRunConfiguration configuration,
@NotNull SettingsEditorGroup<ExternalSystemRunConfiguration> group) {
JavaRunConfigurationExtensionManager javaRunConfigurationExtensionManager = JavaRunConfigurationExtensionManager.getInstanceOrNull();
if (javaRunConfigurationExtensionManager != null) {
javaRunConfigurationExtensionManager.appendEditors(configuration, group);
}
}
@Override
public void attachToProcess(@NotNull ExternalSystemRunConfiguration configuration,
@NotNull ExternalSystemProcessHandler processHandler,
@Nullable RunnerSettings settings) {
JavaRunConfigurationExtensionManager javaRunConfigurationExtensionManager = JavaRunConfigurationExtensionManager.getInstanceOrNull();
if (javaRunConfigurationExtensionManager != null) {
javaRunConfigurationExtensionManager.attachExtensionsToProcess(configuration, processHandler, settings);
}
}
@Override
public void updateVMParameters(@NotNull ExternalSystemRunConfiguration configuration,
@NotNull SimpleJavaParameters javaParameters,
@Nullable RunnerSettings settings,
@NotNull Executor executor) {
final JavaParameters extensionsJP = new JavaParameters();
for (RunConfigurationExtension ext : RunConfigurationExtension.EP_NAME.getExtensionList()) {
try {
ext.updateJavaParameters(configuration, extensionsJP, settings, executor);
}
catch (ExecutionException e) {
LOG.error(e);
}
}
copy(extensionsJP.getVMParametersList(), javaParameters.getVMParametersList());
}
private static void copy(@NotNull ParametersList from, @NotNull ParametersList to) {
to.addAll(from.getParameters());
for (ParamsGroup group : from.getParamsGroups()) {
to.addParamsGroup(group);
}
}
}
@@ -31,12 +31,6 @@ public class AttachExternalProjectAction extends AnAction {
@Override
public void update(@NotNull AnActionEvent e) {
Presentation presentation = e.getPresentation();
// todo [Vlad, IDEA-187835]: provide java subsystem independent implementation
if (!ExternalSystemApiUtil.isJavaCompatibleIde()) {
presentation.setEnabledAndVisible(false);
return;
}
ProjectSystemId externalSystemId = e.getData(ExternalSystemDataKeys.EXTERNAL_SYSTEM_ID);
if (externalSystemId != null) {
String name = externalSystemId.getReadableName();
@@ -85,7 +85,7 @@ public class PackagingModifiableModelImpl implements PackagingModifiableModel {
@Override
public void dispose() {
if (myModifiableArtifactModel != null) {
myModifiableArtifactModel.commit();
myModifiableArtifactModel.dispose();
}
}
@@ -547,10 +547,15 @@
<stepsBeforeRunProvider implementation="com.intellij.packaging.impl.run.BuildArtifactsBeforeRunTaskProvider"
order="after compileBeforeRunNoErrorCheck"/>
<externalSystem.beforeRunTaskImporter implementation="com.intellij.compiler.options.CompileStepBeforeRunImporter"/>
<externalSystemConfigurationHandler
implementation="com.intellij.openapi.externalSystem.service.project.settings.CompilerConfigurationHandler"/>
<externalSystemConfigurationHandler implementation="com.intellij.openapi.externalSystem.service.project.settings.ArtifactsImporter"/>
<externalSystem.moduleDataServiceExtension implementation="com.intellij.openapi.externalSystem.service.project.ModuleDataServiceJavaExtension"/>
<externalSystem.runConfigurationExtension implementation="com.intellij.execution.ExternalSystemRunConfigurationJavaExtension"/>
<applicationService serviceInterface="com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkProvider"
serviceImplementation="com.intellij.openapi.externalSystem.service.execution.ExternalSystemJavaSdkProvider"
overrides="true"/>
<programRunner implementation="com.intellij.openapi.externalSystem.service.execution.ExternalSystemTaskDebugRunner"/>
<programRunner id="defaultRunRunner" implementation="com.intellij.execution.impl.DefaultJavaProgramRunner"/>
@@ -0,0 +1,49 @@
// 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.openapi.externalSystem.service.project;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.service.project.manage.ModuleDataServiceExtension;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleTypeId;
import com.intellij.openapi.roots.LanguageLevelModuleExtension;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.pom.java.LanguageLevel;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ApiStatus.Experimental
public class ModuleDataServiceJavaExtension implements ModuleDataServiceExtension {
private static final Logger LOG = Logger.getInstance(ModuleDataServiceJavaExtension.class);
@Override
public void importModule(@NotNull IdeModifiableModelsProvider modelsProvider, @NotNull Module module, @NotNull ModuleData data) {
if (ModuleTypeId.JAVA_MODULE.equals(module.getModuleTypeName())) {
ModifiableRootModel modifiableRootModel = modelsProvider.getModifiableRootModel(module);
setLanguageLevel(modifiableRootModel, data);
setBytecodeTargetLevel(module, data);
}
}
private static void setLanguageLevel(@NotNull ModifiableRootModel modifiableRootModel, ModuleData data) {
LanguageLevel level = LanguageLevel.parse(data.getSourceCompatibility());
if (level != null) {
try {
modifiableRootModel.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(level);
}
catch (IllegalArgumentException e) {
LOG.debug(e);
}
}
}
private static void setBytecodeTargetLevel(@NotNull Module module, @NotNull ModuleData data) {
String targetLevel = data.getTargetCompatibility();
if (targetLevel != null) {
CompilerConfiguration configuration = CompilerConfiguration.getInstance(module.getProject());
configuration.setBytecodeTargetLevel(module, targetLevel);
}
}
}
@@ -24,7 +24,6 @@
<orderEntry type="module" module-name="intellij.java.testFramework" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.configurationStore.impl" />
<orderEntry type="module" module-name="intellij.platform.testExtensions" scope="TEST" />
<orderEntry type="module" module-name="intellij.java.execution.impl" />
<orderEntry type="module" module-name="intellij.java.compiler.tests" scope="TEST" />
<orderEntry type="library" name="kotlin-reflect" level="project" />
<orderEntry type="module" module-name="intellij.platform.objectSerializer" />
@@ -3,7 +3,6 @@ package com.intellij.openapi.externalSystem.service;
import com.intellij.CommonBundle;
import com.intellij.configurationStore.StorageUtilKt;
import com.intellij.debugger.ui.DebuggerView;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
@@ -116,7 +115,6 @@ public class RemoteExternalSystemCommunicationManager implements ExternalSystemC
List<String> classPath = new ArrayList<>(PathManager.getUtilClassPath());
ContainerUtil.addIfNotNull(classPath, PathUtil.getJarPathForClass(ProjectBundle.class));
ContainerUtil.addIfNotNull(classPath, PathUtil.getJarPathForClass(PlaceHolder.class));
ContainerUtil.addIfNotNull(classPath, PathUtil.getJarPathForClass(DebuggerView.class));
ExternalSystemApiUtil.addBundle(params.getClassPath(), "messages.ProjectBundle", ProjectBundle.class);
ContainerUtil.addIfNotNull(classPath, PathUtil.getJarPathForClass(PsiBundle.class));
ContainerUtil.addIfNotNull(classPath, PathUtil.getJarPathForClass(Alarm.class));
@@ -11,7 +11,6 @@ import com.intellij.diagnostic.logging.LogConfigurationPanel;
import com.intellij.execution.*;
import com.intellij.execution.configurations.*;
import com.intellij.execution.console.DuplexConsoleView;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.impl.ConsoleViewImpl;
import com.intellij.execution.impl.ExecutionManagerImpl;
import com.intellij.execution.process.ProcessHandler;
@@ -34,6 +33,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.FoldingModel;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.ExternalSystemManager;
import com.intellij.openapi.externalSystem.execution.ExternalSystemExecutionConsoleManager;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
@@ -58,6 +58,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScopes;
import com.intellij.util.ArrayUtil;
@@ -83,12 +84,16 @@ import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHel
import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.DEBUG_SETUP_PREFIX;
import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.convert;
import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.getConsoleManagerFor;
import static com.intellij.openapi.util.text.StringUtil.nullize;
/**
* @author Denis Zhdanov
*/
public class ExternalSystemRunConfiguration extends LocatableConfigurationBase implements SearchScopeProvidingRunProfile,
SMRunnerConsolePropertiesProvider {
private static final ExtensionPointName<ExternalSystemRunConfigurationExtension> EP_NAME
= ExtensionPointName.create("com.intellij.externalSystem.runConfigurationExtension");
public static final Key<InputStream> RUN_INPUT_KEY = Key.create("RUN_INPUT_KEY");
public static final Key<Class<? extends BuildProgressListener>> PROGRESS_LISTENER_KEY = Key.create("PROGRESS_LISTENER_KEY");
@@ -132,10 +137,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
if (e != null) {
mySettings = XmlSerializer.deserialize(e, ExternalSystemTaskExecutionSettings.class);
}
JavaRunConfigurationExtensionManager javaRunConfigurationExtensionManager = JavaRunConfigurationExtensionManager.getInstanceOrNull();
if (javaRunConfigurationExtensionManager != null) {
javaRunConfigurationExtensionManager.readExternal(this, element);
}
EP_NAME.forEachExtensionSafe(extension -> extension.readExternal(this, element));
}
@Override
@@ -155,10 +157,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
}
}
}));
JavaRunConfigurationExtensionManager javaRunConfigurationExtensionManager = JavaRunConfigurationExtensionManager.getInstanceOrNull();
if (javaRunConfigurationExtensionManager != null) {
javaRunConfigurationExtensionManager.writeExternal(this, element);
}
EP_NAME.forEachExtensionSafe(extension -> extension.writeExternal(this, element));
}
@NotNull
@@ -172,10 +171,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
SettingsEditorGroup<ExternalSystemRunConfiguration> group = new SettingsEditorGroup<>();
group.addEditor(ExecutionBundle.message("run.configuration.configuration.tab.title"),
new ExternalSystemRunConfigurationEditor(getProject(), mySettings.getExternalSystemId()));
JavaRunConfigurationExtensionManager javaRunConfigurationExtensionManager = JavaRunConfigurationExtensionManager.getInstanceOrNull();
if (javaRunConfigurationExtensionManager != null) {
javaRunConfigurationExtensionManager.appendEditors(this, group);
}
EP_NAME.forEachExtensionSafe(extension -> extension.appendEditors(this, group));
group.addEditor(ExecutionBundle.message("logs.tab.title"), new LogConfigurationPanel<>());
return group;
}
@@ -183,8 +179,9 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
@Nullable
@Override
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) {
MyRunnableState runnableState =
new MyRunnableState(mySettings, getProject(), DefaultDebugExecutor.EXECUTOR_ID.equals(executor.getId()), this, env);
// DebugExecutor ID - com.intellij.execution.executors.DefaultDebugExecutor.EXECUTOR_ID
String debugExecutorId = ToolWindowId.DEBUG;
MyRunnableState runnableState = new MyRunnableState(mySettings, getProject(), debugExecutorId.equals(executor.getId()), this, env);
copyUserDataTo(runnableState);
return runnableState;
}
@@ -313,10 +310,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
progressListenerClazz != null ? ServiceManager.getService(myProject, progressListenerClazz)
: createBuildView(task.getId(), executionName, task.getExternalProjectPath(), consoleView);
JavaRunConfigurationExtensionManager javaRunConfigurationExtensionManager = JavaRunConfigurationExtensionManager.getInstanceOrNull();
if (javaRunConfigurationExtensionManager != null) {
javaRunConfigurationExtensionManager.attachExtensionsToProcess(myConfiguration, processHandler, myEnv.getRunnerSettings());
}
EP_NAME.forEachExtensionSafe(extension -> extension.attachToProcess(myConfiguration, processHandler, myEnv.getRunnerSettings()));
ApplicationManager.getApplication().executeOnPooledThread(() -> {
final String startDateTime = DateFormatUtil.formatTimeWithSeconds(System.currentTimeMillis());
@@ -341,9 +335,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
new BuildViewSettingsProviderAdapter((BuildViewSettingsProvider)consoleView) : null;
progressListener.onEvent(id,
new StartBuildEventImpl(new DefaultBuildDescriptor(id, executionName, workingDir, eventTime), "running...")
.withProcessHandler(processHandler, view -> {
foldGreetingOrFarewell(consoleView, greeting, true);
})
.withProcessHandler(processHandler, view -> foldGreetingOrFarewell(consoleView, greeting, true))
.withContentDescriptorSupplier(() -> myContentDescriptor)
.withRestartAction(rerunTaskAction)
.withRestartActions(restartActions)
@@ -426,16 +418,10 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
@Nullable
private String getJvmAgentSetup() throws ExecutionException {
// todo [Vlad, IDEA-187832]: extract to `external-system-java` module
if(!ExternalSystemApiUtil.isJavaCompatibleIde()) return null;
final JavaParameters extensionsJP = new JavaParameters();
for (RunConfigurationExtension ext : RunConfigurationExtension.EP_NAME.getExtensionList()) {
ext.updateJavaParameters(myConfiguration, extensionsJP, myEnv.getRunnerSettings(), myEnv.getExecutor());
}
final SimpleJavaParameters extensionsJP = new SimpleJavaParameters();
EP_NAME.forEachExtensionSafe(
extension -> extension.updateVMParameters(myConfiguration, extensionsJP, myEnv.getRunnerSettings(), myEnv.getExecutor()));
String jvmAgentSetup;
if (myDebugPort > 0) {
jvmAgentSetup = DEBUG_SETUP_PREFIX + myDebugPort;
if (getForkSocket() != null) {
@@ -456,7 +442,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
}
jvmAgentSetup = parametersList.getParametersString();
}
return jvmAgentSetup;
return nullize(jvmAgentSetup);
}
private BuildProgressListener createBuildView(ExternalSystemTaskId id,
@@ -0,0 +1,30 @@
// 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.openapi.externalSystem.service.execution;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.configurations.SimpleJavaParameters;
import com.intellij.openapi.options.SettingsEditorGroup;
import org.jdom.Element;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ApiStatus.Experimental
public interface ExternalSystemRunConfigurationExtension {
void readExternal(@NotNull ExternalSystemRunConfiguration configuration, @NotNull Element element);
void writeExternal(@NotNull ExternalSystemRunConfiguration configuration, @NotNull Element element);
void appendEditors(@NotNull ExternalSystemRunConfiguration configuration,
@NotNull SettingsEditorGroup<ExternalSystemRunConfiguration> group);
void attachToProcess(@NotNull ExternalSystemRunConfiguration configuration,
@NotNull ExternalSystemProcessHandler processHandler,
@Nullable RunnerSettings settings);
void updateVMParameters(@NotNull ExternalSystemRunConfiguration configuration,
@NotNull SimpleJavaParameters javaParameters,
@Nullable RunnerSettings settings,
@NotNull Executor executor);
}
@@ -24,17 +24,10 @@ import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ProjectModelExternalSource;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.packaging.artifacts.*;
import com.intellij.packaging.elements.CompositePackagingElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
public class IdeModifiableModelsProviderImpl extends AbstractIdeModifiableModelsProvider {
@@ -1,7 +1,6 @@
// 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.openapi.externalSystem.service.project.manage;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.configurationStore.StateStorageManagerKt;
import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
@@ -11,10 +10,12 @@ import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
import com.intellij.openapi.externalSystem.model.project.*;
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkProvider;
import com.intellij.openapi.externalSystem.service.project.IdeModelsProvider;
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider;
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
@@ -23,7 +24,6 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
import com.intellij.openapi.module.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.*;
@@ -38,7 +38,6 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.ui.CheckBoxList;
import com.intellij.ui.JBColor;
import com.intellij.ui.ScrollPaneFactory;
@@ -77,6 +76,9 @@ public abstract class AbstractModuleDataService<E extends ModuleData> extends Ab
private static final Logger LOG = Logger.getInstance(AbstractModuleDataService.class);
private final static ExtensionPointName<ModuleDataServiceExtension> EP_NAME =
ExtensionPointName.create("com.intellij.externalSystem.moduleDataServiceExtension");
@Override
public void importData(@NotNull final Collection<DataNode<E>> toImport,
@Nullable ProjectData projectData,
@@ -104,10 +106,7 @@ public abstract class AbstractModuleDataService<E extends ModuleData> extends Ab
ModifiableRootModel modifiableRootModel = modelsProvider.getModifiableRootModel(module);
syncPaths(module, modifiableRootModel, node.getData());
if(ModuleTypeId.JAVA_MODULE.equals(module.getModuleTypeName()) && ExternalSystemApiUtil.isJavaCompatibleIde()) {
// todo [Vlad, IDEA-187832]: extract to `external-system-java` module
setLanguageLevel(modifiableRootModel, node.getData());
}
EP_NAME.forEachExtensionSafe(extension -> extension.importModule(modelsProvider, module, node.getData()));
setSdk(modifiableRootModel, node.getData());
}
}
@@ -409,7 +408,6 @@ public abstract class AbstractModuleDataService<E extends ModuleData> extends Ab
if (orderAwareMap != null) {
rearrangeOrderEntries(orderAwareMap, modelsProvider.getModifiableRootModel(module));
}
setBytecodeTargetLevel(project, module, moduleDataNode.getData());
moduleDataNode.putUserData(MODULE_KEY, null);
moduleDataNode.putUserData(ORDERED_DATA_MAP_KEY, null);
}
@@ -475,18 +473,6 @@ public abstract class AbstractModuleDataService<E extends ModuleData> extends Ab
return idx;
}
private void setLanguageLevel(@NotNull ModifiableRootModel modifiableRootModel, E data) {
LanguageLevel level = LanguageLevel.parse(data.getSourceCompatibility());
if (level != null) {
try {
modifiableRootModel.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(level);
}
catch (IllegalArgumentException e) {
LOG.debug(e);
}
}
}
private void setSdk(@NotNull ModifiableRootModel modifiableRootModel, E data) {
String skdName = data.getSdkName();
if (skdName != null) {
@@ -496,16 +482,8 @@ public abstract class AbstractModuleDataService<E extends ModuleData> extends Ab
modifiableRootModel.setSdk(sdk);
}
else {
modifiableRootModel.setInvalidSdk(skdName, JavaSdk.getInstance().getName());
modifiableRootModel.setInvalidSdk(skdName, ExternalSystemJdkProvider.getInstance().getJavaSdkType().getName());
}
}
}
private void setBytecodeTargetLevel(@NotNull Project project, @NotNull Module module, @NotNull E data) {
String targetLevel = data.getTargetCompatibility();
if (targetLevel != null) {
CompilerConfiguration configuration = CompilerConfiguration.getInstance(project);
configuration.setBytecodeTargetLevel(module, targetLevel);
}
}
}
@@ -1,14 +1,11 @@
// 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.openapi.externalSystem.service.project.manage;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.RunManager;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.compiler.CompileContext;
import com.intellij.openapi.compiler.CompileTask;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.ProjectSystemId;
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
@@ -27,6 +24,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.task.ModuleBuildTask;
import com.intellij.task.ProjectTaskContext;
import com.intellij.task.ProjectTaskManager;
import com.intellij.task.ProjectTaskResult;
import com.intellij.task.impl.ProjectTaskManagerImpl;
import com.intellij.task.impl.ProjectTaskManagerListener;
import com.intellij.task.impl.ProjectTaskScope;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FactoryMap;
@@ -55,27 +59,22 @@ public class ExternalSystemTaskActivator {
}
public void init() {
CompilerManager compilerManager = CompilerManager.getInstance(myProject);
// todo extract to "java" external system module
if (compilerManager == null) {
return;
}
class MyCompileTask implements CompileTask {
private final boolean myBefore;
MyCompileTask(boolean before) {
myBefore = before;
ProjectTaskManagerImpl projectTaskManager = (ProjectTaskManagerImpl)ProjectTaskManager.getInstance(myProject);
projectTaskManager.addListener(new ProjectTaskManagerListener() {
@Override
public void beforeRun(@NotNull ProjectTaskContext context) throws ExecutionException {
if (!doExecuteBuildPhaseTriggers(true, context)) {
throw new ExecutionException("Before build triggering task failed");
}
}
@Override
public boolean execute(@NotNull CompileContext context) {
return doExecuteCompileTasks(myBefore, context);
public void afterRun(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult result) throws ExecutionException {
if (!doExecuteBuildPhaseTriggers(false, context)) {
throw new ExecutionException("After build triggering task failed");
}
}
}
compilerManager.addBeforeTask(new MyCompileTask(true));
compilerManager.addAfterTask(new MyCompileTask(false));
});
fireTasksChanged();
}
@@ -97,25 +96,43 @@ public class ExternalSystemTaskActivator {
return StringUtil.join(result, ", ");
}
private boolean doExecuteCompileTasks(boolean myBefore, @NotNull CompileContext context) {
List<String> modules = ReadAction.compute(
() -> ContainerUtil.mapNotNull(context.getCompileScope().getAffectedModules(),
module -> ExternalSystemApiUtil.getExternalProjectPath(module)));
private boolean doExecuteBuildPhaseTriggers(boolean myBefore, @NotNull ProjectTaskContext context) {
ProjectTaskScope taskScope = context.getUserData(ProjectTaskScope.KEY);
if (taskScope == null) {
return true;
}
final Collection<Phase> phases = new ArrayList<>();
Set<String> modulesToBuild = new LinkedHashSet<>();
Set<String> modulesToRebuild = new LinkedHashSet<>();
for (ModuleBuildTask task : taskScope.getRequestedTasks(ModuleBuildTask.class)) {
String projectPath = ExternalSystemApiUtil.getExternalProjectPath(task.getModule());
if (projectPath == null) continue;
if (task.isIncrementalBuild()) {
modulesToBuild.add(projectPath);
}
else {
modulesToRebuild.add(projectPath);
}
}
boolean result = true;
if (myBefore) {
if(context.isRebuild()) {
phases.add(Phase.BEFORE_REBUILD);
if (!modulesToBuild.isEmpty()) {
result = runTasks(modulesToBuild, Phase.BEFORE_COMPILE);
}
if (result && !modulesToRebuild.isEmpty()) {
result = runTasks(modulesToRebuild, Phase.BEFORE_COMPILE, Phase.BEFORE_REBUILD);
}
phases.add(Phase.BEFORE_COMPILE);
}
else {
phases.add(Phase.AFTER_COMPILE);
if(context.isRebuild()) {
phases.add(Phase.AFTER_REBUILD);
if (!modulesToBuild.isEmpty()) {
result = runTasks(modulesToBuild, Phase.AFTER_COMPILE);
}
if (result && !modulesToRebuild.isEmpty()) {
result = runTasks(modulesToRebuild, Phase.AFTER_COMPILE, Phase.AFTER_REBUILD);
}
}
return runTasks(modules, phases.toArray(new Phase[0]));
return result;
}
public boolean runTasks(@NotNull String modulePath, @NotNull Phase... phases) {
@@ -0,0 +1,13 @@
// 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.openapi.externalSystem.service.project.manage;
import com.intellij.openapi.externalSystem.model.project.ModuleData;
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider;
import com.intellij.openapi.module.Module;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ApiStatus.Experimental
public interface ModuleDataServiceExtension {
void importModule(@NotNull IdeModifiableModelsProvider modelsProvider, @NotNull Module module, @NotNull ModuleData data);
}
@@ -15,10 +15,7 @@ import com.intellij.build.events.impl.SuccessResultImpl;
import com.intellij.build.events.impl.*;
import com.intellij.execution.*;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.rmi.RemoteUtil;
@@ -85,6 +82,7 @@ import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowEP;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
@@ -131,7 +129,9 @@ public class ExternalSystemUtil {
static {
RUNNER_IDS.put(DefaultRunExecutor.EXECUTOR_ID, ExternalSystemConstants.RUNNER_ID);
RUNNER_IDS.put(DefaultDebugExecutor.EXECUTOR_ID, ExternalSystemConstants.DEBUG_RUNNER_ID);
// DebugExecutor ID - com.intellij.execution.executors.DefaultDebugExecutor.EXECUTOR_ID
String debugExecutorId = ToolWindowId.DEBUG;
RUNNER_IDS.put(debugExecutorId, ExternalSystemConstants.DEBUG_RUNNER_ID);
}
private ExternalSystemUtil() {
@@ -849,17 +849,13 @@ public class ExternalSystemUtil {
}
@Override
public void processStarted(@NotNull final String executorIdLocal,
@NotNull final ExecutionEnvironment environmentLocal,
@NotNull final ProcessHandler handler) {
public void processTerminated(@NotNull String executorIdLocal,
@NotNull ExecutionEnvironment environmentLocal,
@NotNull ProcessHandler handler,
int exitCode) {
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
handler.addProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(@NotNull ProcessEvent event) {
result.set(event.getExitCode() == 0);
targetDone.up();
}
});
result.set(exitCode == 0);
targetDone.up();
}
}
});
@@ -892,6 +888,14 @@ public class ExternalSystemUtil {
callback.onFailure();
}
}
if (!result.get()) {
ApplicationManager.getApplication().invokeLater(() -> {
ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(environment.getExecutor().getToolWindowId());
if (window != null) {
window.activate(null, false, false);
}
}, project.getDisposed());
}
}
};
@@ -1,6 +1,8 @@
// 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.task.impl;
import com.intellij.execution.ExecutionException;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -20,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
@@ -36,6 +39,7 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
private static final Logger LOG = Logger.getInstance("#com.intellij.task.ProjectTaskManager");
private final ProjectTaskRunner myDummyTaskRunner = new DummyTaskRunner();
private final ProjectTaskListener myEventPublisher;
private final List<ProjectTaskManagerListener> myListeners = new CopyOnWriteArrayList<>();
public ProjectTaskManagerImpl(@NotNull Project project) {
super(project);
@@ -146,23 +150,51 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
};
visitTasks(projectTask instanceof ProjectTaskList ? (ProjectTaskList)projectTask : Collections.singleton(projectTask), taskClassifier);
context.putUserData(ProjectTaskScope.KEY, new ProjectTaskScope() {
@NotNull
@Override
public <T extends ProjectTask> List<T> getRequestedTasks(@NotNull Class<T> instanceOf) {
List<T> tasks = new ArrayList<>();
//noinspection unchecked
toRun.forEach(pair -> pair.second.stream().filter(instanceOf::isInstance).map(task -> (T)task).forEach(tasks::add));
return tasks;
}
});
myEventPublisher.started(context);
if (toRun.isEmpty()) {
sendSuccessNotify(new ListenerNotificator(context, callback));
return;
}
ProjectTaskResultsAggregator callbacksCollector =
new ProjectTaskResultsAggregator(new ListenerNotificator(context, callback), toRun.size());
for (Pair<ProjectTaskRunner, Collection<? extends ProjectTask>> pair : toRun) {
callback = new ProjectTaskRunnerNotification(pair.second, callbacksCollector);
if (pair.second.isEmpty()) {
sendSuccessNotify(callback);
// do not run before tasks on EDT
ApplicationManager.getApplication().executeOnPooledThread(() -> {
for (ProjectTaskManagerListener listener : myListeners) {
try {
listener.beforeRun(context);
}
catch (ExecutionException e) {
sendAbortedNotify(new ListenerNotificator(context, callback));
return;
}
}
else {
pair.first.run(myProject, context, callback, pair.second);
if (toRun.isEmpty()) {
sendSuccessNotify(new ListenerNotificator(context, callback));
return;
}
}
ProjectTaskResultsAggregator callbacksCollector =
new ProjectTaskResultsAggregator(new ListenerNotificator(context, callback), toRun.size());
for (Pair<ProjectTaskRunner, Collection<? extends ProjectTask>> pair : toRun) {
ProjectTaskRunnerNotification notification = new ProjectTaskRunnerNotification(pair.second, callbacksCollector);
if (pair.second.isEmpty()) {
sendSuccessNotify(notification);
}
else {
ApplicationManager.getApplication().invokeLater(() -> pair.first.run(myProject, context, notification, pair.second));
}
}
});
}
public final void addListener(@NotNull ProjectTaskManagerListener listener) {
myListeners.add(listener);
}
private static void sendSuccessNotify(@Nullable ProjectTaskNotification notification) {
@@ -171,6 +203,12 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
}
}
private static void sendAbortedNotify(@Nullable ProjectTaskNotification notification) {
if (notification != null) {
notification.finished(new ProjectTaskResult(true, 0, 0));
}
}
private static void visitTasks(@NotNull Collection<? extends ProjectTask> tasks,
@NotNull Consumer<? super Collection<? extends ProjectTask>> consumer) {
for (ProjectTask child : tasks) {
@@ -220,16 +258,39 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
@Nullable private final ProjectTaskNotification myDelegate;
@NotNull private final ProjectTaskContext myContext;
private ListenerNotificator(@NotNull ProjectTaskContext context, @Nullable ProjectTaskNotification delegate) {
private ListenerNotificator(@NotNull ProjectTaskContext context,
@Nullable ProjectTaskNotification delegate) {
myContext = context;
myDelegate = delegate;
}
@Override
public void finished(@NotNull ProjectTaskResult executionResult) {
if (!executionResult.isAborted() && executionResult.getErrors() == 0) {
// do not run after tasks on EDT
ApplicationManager.getApplication().executeOnPooledThread(() -> {
try {
for (ProjectTaskManagerListener listener : myListeners) {
listener.afterRun(myContext, executionResult);
}
notify(myContext, executionResult);
}
catch (ExecutionException e) {
LOG.debug(e);
notify(myContext, new ProjectTaskResult(
false, executionResult.getErrors() + 1, executionResult.getWarnings(), executionResult.getTasksState()));
}
});
}
else {
notify(myContext, executionResult);
}
}
private void notify(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult executionResult) {
GuiUtils.invokeLaterIfNeeded(() -> {
if (!myProject.isDisposed()) {
myEventPublisher.finished(myContext, executionResult);
myEventPublisher.finished(context, executionResult);
}
if (myDelegate != null) {
myDelegate.finished(executionResult);
@@ -0,0 +1,15 @@
// 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.task.impl;
import com.intellij.execution.ExecutionException;
import com.intellij.task.ProjectTaskContext;
import com.intellij.task.ProjectTaskResult;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ApiStatus.Experimental
public interface ProjectTaskManagerListener {
void beforeRun(@NotNull ProjectTaskContext context) throws ExecutionException;
void afterRun(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult result) throws ExecutionException;
}
@@ -0,0 +1,16 @@
// 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.task.impl;
import com.intellij.openapi.util.Key;
import com.intellij.task.ProjectTask;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@ApiStatus.Experimental
public interface ProjectTaskScope {
Key<ProjectTaskScope> KEY = Key.create("project task scope");
@NotNull
<T extends ProjectTask> List<T> getRequestedTasks(@NotNull Class<T> instanceOf);
}
@@ -8,6 +8,10 @@
interface="com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService"/>
<extensionPoint qualifiedName="com.intellij.externalSystem.modifiableModelsProvider"
interface="com.intellij.openapi.externalSystem.service.project.ModifiableModelsProviderExtension"/>
<extensionPoint qualifiedName="com.intellij.externalSystem.moduleDataServiceExtension"
interface="com.intellij.openapi.externalSystem.service.project.manage.ModuleDataServiceExtension"/>
<extensionPoint qualifiedName="com.intellij.externalSystem.runConfigurationExtension"
interface="com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfigurationExtension"/>
<extensionPoint qualifiedName="com.intellij.externalSystemConfigurationHandler"
interface="com.intellij.openapi.externalSystem.service.project.settings.ConfigurationHandler"/>
<extensionPoint qualifiedName="com.intellij.externalSystem.runConfigurationImporter"
@@ -43,8 +43,6 @@
<postStartupActivity implementation="com.intellij.openapi.externalSystem.service.project.manage.ReprocessContentRootDataActivity"/>
<externalSystemConfigurationHandler
implementation="com.intellij.openapi.externalSystem.service.project.settings.CompilerConfigurationHandler"/>
<externalSystemConfigurationHandler
implementation="com.intellij.openapi.externalSystem.service.project.settings.CodeStyleConfigurationHandler"/>
<externalSystemConfigurationHandler
@@ -66,7 +64,6 @@
<!--Execution-->
<programRunner implementation="com.intellij.openapi.externalSystem.service.execution.ExternalSystemTaskRunner"/>
<programRunner implementation="com.intellij.openapi.externalSystem.service.execution.ExternalSystemTaskDebugRunner"/>
<streamProviderFactory implementation="com.intellij.openapi.externalSystem.configurationStore.ExternalSystemStreamProviderFactory"/>