mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Build: do not use JPS compilation directly when building modules/artifacts of running JEE applications IDEA-210338
GitOrigin-RevId: 7e065541303104d3e8a8e5fd17a29554e8068d8d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
22a62b553a
commit
20e27b7d8e
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* 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-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.compiler.actions;
|
||||
|
||||
import com.intellij.history.LocalHistory;
|
||||
@@ -21,6 +7,7 @@ import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.compiler.CompilerBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.task.ProjectTaskContext;
|
||||
import com.intellij.task.ProjectTaskManager;
|
||||
import com.intellij.task.ProjectTaskNotification;
|
||||
import com.intellij.task.ProjectTaskResult;
|
||||
@@ -31,7 +18,7 @@ public class CompileProjectAction extends CompileActionBase {
|
||||
protected void doAction(DataContext dataContext, final Project project) {
|
||||
ProjectTaskManager.getInstance(project).rebuildAllModules(new ProjectTaskNotification() {
|
||||
@Override
|
||||
public void finished(@NotNull ProjectTaskResult executionResult) {
|
||||
public void finished(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult executionResult) {
|
||||
if (executionResult.isAborted() || project.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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-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.
|
||||
|
||||
/*
|
||||
* @author: Eugene Zhuravlev
|
||||
@@ -25,7 +11,10 @@ import com.intellij.compiler.ProblemsView;
|
||||
import com.intellij.compiler.progress.CompilerTask;
|
||||
import com.intellij.execution.impl.ExecutionManagerImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.*;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerMessage;
|
||||
import com.intellij.openapi.compiler.CompilerMessageCategory;
|
||||
import com.intellij.openapi.compiler.CompilerPaths;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
@@ -33,7 +22,6 @@ import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.Navigatable;
|
||||
@@ -43,7 +31,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CompileContextImpl extends UserDataHolderBase implements CompileContextEx {
|
||||
public static final Key<CompileContext> CONTEXT_KEY = Key.create("jps_compile_context");
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileContextImpl");
|
||||
private final Project myProject;
|
||||
private final CompilerTask myBuildSession;
|
||||
|
||||
+10
-15
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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-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.packaging.impl.compiler;
|
||||
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
@@ -21,6 +7,9 @@ import com.intellij.openapi.compiler.Compiler;
|
||||
import com.intellij.openapi.compiler.CompilerManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.task.ProjectTaskContext;
|
||||
import com.intellij.task.impl.JpsBuildData;
|
||||
import com.intellij.task.impl.JpsProjectTaskRunner;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -66,4 +55,10 @@ public class ArtifactsCompiler implements Compiler {
|
||||
public static Set<String> getWrittenPaths(@NotNull CompileContext context) {
|
||||
return context.getUserData(WRITTEN_PATHS_KEY);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Set<String> getWrittenPaths(@NotNull ProjectTaskContext context) {
|
||||
JpsBuildData jpsBuildData = context.getUserData(JpsProjectTaskRunner.JPS_BUILD_DATA_KEY);
|
||||
return jpsBuildData == null ? null : jpsBuildData.getArtifactsWrittenPaths();
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 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-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.packaging.impl.run;
|
||||
|
||||
import com.intellij.execution.BeforeRunTaskProvider;
|
||||
@@ -125,7 +125,7 @@ public abstract class BuildArtifactsBeforeRunTaskProviderBase<T extends BuildArt
|
||||
|
||||
final ProjectTaskNotification callback = new ProjectTaskNotification() {
|
||||
@Override
|
||||
public void finished(@NotNull ProjectTaskResult executionResult) {
|
||||
public void finished(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult executionResult) {
|
||||
result.set(!executionResult.isAborted() && executionResult.getErrors() == 0);
|
||||
finished.up();
|
||||
}
|
||||
@@ -138,7 +138,9 @@ public abstract class BuildArtifactsBeforeRunTaskProviderBase<T extends BuildArt
|
||||
ProjectTask artifactsBuildProjectTask = createProjectTask(myProject, artifacts);
|
||||
finished.down();
|
||||
Object sessionId = ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env);
|
||||
ProjectTaskManager.getInstance(myProject).run(new ProjectTaskContext(sessionId), artifactsBuildProjectTask, callback);
|
||||
ProjectTaskContext projectTaskContext = new ProjectTaskContext(sessionId);
|
||||
env.copyUserDataTo(projectTaskContext);
|
||||
ProjectTaskManager.getInstance(myProject).run(projectTaskContext, artifactsBuildProjectTask, callback);
|
||||
}, ModalityState.NON_MODAL);
|
||||
|
||||
finished.waitFor();
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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.compiler.CompileContext;
|
||||
import com.intellij.task.ProjectTaskContext;
|
||||
import com.intellij.task.ProjectTaskManager;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* {@link JpsBuildData} is available via the {@link ProjectTaskContext}.
|
||||
* It provides aggregated details for the multiple invocations of the "JPS" builds during the single run session of a {@link ProjectTaskManager}.
|
||||
* This data was introduced for compatibility reasons with the code which still depends on the internal context of "JPS" builder.
|
||||
* And shouldn't be used by plugins or new code.
|
||||
*
|
||||
* @see ProjectTaskContext
|
||||
* @see JpsProjectTaskRunner#JPS_BUILD_DATA_KEY
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public interface JpsBuildData {
|
||||
Set<String> getArtifactsWrittenPaths();
|
||||
|
||||
List<CompileContext> getFinishedBuildsContexts();
|
||||
}
|
||||
@@ -1,21 +1,6 @@
|
||||
/*
|
||||
* 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-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.compiler.impl.CompileContextImpl;
|
||||
import com.intellij.compiler.impl.CompileDriver;
|
||||
import com.intellij.compiler.impl.CompileScopeUtil;
|
||||
import com.intellij.compiler.impl.CompositeScope;
|
||||
@@ -29,23 +14,23 @@ import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectModelBuildableElement;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.KeyWithDefaultValue;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
|
||||
import com.intellij.packaging.impl.compiler.ArtifactsCompiler;
|
||||
import com.intellij.packaging.impl.compiler.ArtifactsWorkspaceSettings;
|
||||
import com.intellij.task.*;
|
||||
import com.intellij.ui.GuiUtils;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -54,6 +39,9 @@ import java.util.stream.Stream;
|
||||
*/
|
||||
public class JpsProjectTaskRunner extends ProjectTaskRunner {
|
||||
private static final Logger LOG = Logger.getInstance(JpsProjectTaskRunner.class);
|
||||
@ApiStatus.Internal
|
||||
public static final Key<JpsBuildData> JPS_BUILD_DATA_KEY = KeyWithDefaultValue.create("jps_build_data", MyJpsBuildData::new);
|
||||
@ApiStatus.Internal
|
||||
public static final Key<Object> EXECUTION_SESSION_ID_KEY = ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY;
|
||||
|
||||
@Override
|
||||
@@ -61,6 +49,7 @@ public class JpsProjectTaskRunner extends ProjectTaskRunner {
|
||||
@NotNull ProjectTaskContext context,
|
||||
@Nullable ProjectTaskNotification callback,
|
||||
@NotNull Collection<? extends ProjectTask> tasks) {
|
||||
context.putUserData(JPS_BUILD_DATA_KEY, new MyJpsBuildData());
|
||||
MessageBusConnection connection = project.getMessageBus().connect(project);
|
||||
connection.subscribe(CompilerTopics.COMPILATION_STATUS, new CompilationStatusListener() {
|
||||
@Override
|
||||
@@ -68,27 +57,22 @@ public class JpsProjectTaskRunner extends ProjectTaskRunner {
|
||||
context.fileGenerated(outputRoot, relativePath);
|
||||
}
|
||||
});
|
||||
CompileStatusNotification compileNotification = (aborted, errors, warnings, compileContext) -> {
|
||||
context.putUserData(CompileContextImpl.CONTEXT_KEY, compileContext);
|
||||
if (callback != null) {
|
||||
callback.finished(new ProjectTaskResult(aborted, errors, warnings));
|
||||
}
|
||||
connection.disconnect();
|
||||
};
|
||||
|
||||
Map<Class<? extends ProjectTask>, List<ProjectTask>> taskMap = groupBy(tasks);
|
||||
GuiUtils.invokeLaterIfNeeded(() -> {
|
||||
runModulesResourcesBuildTasks(project, context, compileNotification, taskMap);
|
||||
runModulesBuildTasks(project, context, compileNotification, taskMap);
|
||||
runFilesBuildTasks(project, compileNotification, taskMap);
|
||||
runEmptyBuildTask(project, context, compileNotification, taskMap);
|
||||
runArtifactsBuildTasks(project, context, compileNotification, taskMap);
|
||||
try (MyNotificationCollector notificationCollector = new MyNotificationCollector(context, callback, () -> connection.disconnect())) {
|
||||
runModulesResourcesBuildTasks(project, context, notificationCollector, taskMap);
|
||||
runModulesBuildTasks(project, context, notificationCollector, taskMap);
|
||||
runFilesBuildTasks(project, notificationCollector, taskMap);
|
||||
runEmptyBuildTask(project, context, notificationCollector, taskMap);
|
||||
runArtifactsBuildTasks(project, context, notificationCollector, taskMap);
|
||||
}
|
||||
}, ModalityState.defaultModalityState(), project.getDisposed());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRun(@NotNull ProjectTask projectTask) {
|
||||
return projectTask instanceof ModuleBuildTask || projectTask instanceof EmptyCompileScopeBuildTask ||
|
||||
return projectTask instanceof ModuleBuildTask || projectTask instanceof EmptyCompileScopeBuildTask ||
|
||||
(projectTask instanceof ProjectModelBuildTask && ((ProjectModelBuildTask)projectTask).getBuildableElement() instanceof Artifact);
|
||||
}
|
||||
|
||||
@@ -105,33 +89,33 @@ public class JpsProjectTaskRunner extends ProjectTaskRunner {
|
||||
|
||||
private static void runModulesBuildTasks(@NotNull Project project,
|
||||
@NotNull ProjectTaskContext context,
|
||||
@NotNull CompileStatusNotification compileNotification,
|
||||
@NotNull MyNotificationCollector notificationCollector,
|
||||
@NotNull Map<Class<? extends ProjectTask>, List<ProjectTask>> tasksMap) {
|
||||
Collection<? extends ProjectTask> buildTasks = tasksMap.get(ModuleBuildTask.class);
|
||||
if (ContainerUtil.isEmpty(buildTasks)) return;
|
||||
|
||||
ModulesBuildSettings modulesBuildSettings = assembleModulesBuildSettings(buildTasks);
|
||||
CompilerManager compilerManager = CompilerManager.getInstance(project);
|
||||
|
||||
|
||||
if (modulesBuildSettings.isRebuild()){
|
||||
compilerManager.rebuild(compileNotification);
|
||||
compilerManager.rebuild(new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
else {
|
||||
CompileScope scope = createScope(
|
||||
compilerManager, context, modulesBuildSettings.modules, modulesBuildSettings.includeDependentModules, modulesBuildSettings.includeRuntimeDependencies
|
||||
);
|
||||
if (modulesBuildSettings.isIncrementalBuild) {
|
||||
compilerManager.make(scope, compileNotification);
|
||||
compilerManager.make(scope, new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
else {
|
||||
compilerManager.compile(scope, compileNotification);
|
||||
compilerManager.compile(scope, new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void runEmptyBuildTask(@NotNull Project project,
|
||||
@NotNull ProjectTaskContext context,
|
||||
@NotNull CompileStatusNotification compileNotification,
|
||||
@NotNull Map<Class<? extends ProjectTask>, List<ProjectTask>> tasksMap) {
|
||||
@NotNull ProjectTaskContext context,
|
||||
@NotNull MyNotificationCollector notificationCollector,
|
||||
@NotNull Map<Class<? extends ProjectTask>, List<ProjectTask>> tasksMap) {
|
||||
Collection<? extends ProjectTask> buildTasks = tasksMap.get(EmptyCompileScopeBuildTask.class);
|
||||
if (ContainerUtil.isEmpty(buildTasks)) return;
|
||||
|
||||
@@ -140,16 +124,16 @@ public class JpsProjectTaskRunner extends ProjectTaskRunner {
|
||||
// this will effectively run all before- and after- compilation tasks registered within CompilerManager
|
||||
EmptyCompileScopeBuildTask task = (EmptyCompileScopeBuildTask)buildTasks.iterator().next();
|
||||
if (task.isIncrementalBuild()) {
|
||||
compilerManager.make(scope, compileNotification);
|
||||
compilerManager.make(scope, new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
else {
|
||||
compilerManager.compile(scope, compileNotification);
|
||||
compilerManager.compile(scope, new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
}
|
||||
|
||||
private static void runModulesResourcesBuildTasks(@NotNull Project project,
|
||||
@NotNull ProjectTaskContext context,
|
||||
@NotNull CompileStatusNotification compileNotification,
|
||||
@NotNull MyNotificationCollector notificationCollector,
|
||||
@NotNull Map<Class<? extends ProjectTask>, List<ProjectTask>> tasksMap) {
|
||||
Collection<? extends ProjectTask> buildTasks = tasksMap.get(ModuleResourcesBuildTask.class);
|
||||
if (ContainerUtil.isEmpty(buildTasks)) return;
|
||||
@@ -165,10 +149,10 @@ public class JpsProjectTaskRunner extends ProjectTaskRunner {
|
||||
CompileScopeUtil.setResourcesScopeForExternalBuild(scope, moduleNames);
|
||||
|
||||
if (modulesBuildSettings.isIncrementalBuild) {
|
||||
compilerManager.make(scope, compileNotification);
|
||||
compilerManager.make(scope, new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
else {
|
||||
compilerManager.compile(scope, compileNotification);
|
||||
compilerManager.compile(scope, new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,20 +247,20 @@ public class JpsProjectTaskRunner extends ProjectTaskRunner {
|
||||
}
|
||||
|
||||
private static void runFilesBuildTasks(@NotNull Project project,
|
||||
@NotNull CompileStatusNotification compileNotification,
|
||||
@NotNull MyNotificationCollector notificationCollector,
|
||||
@NotNull Map<Class<? extends ProjectTask>, List<ProjectTask>> tasksMap) {
|
||||
Collection<? extends ProjectTask> filesTargets = tasksMap.get(ModuleFilesBuildTask.class);
|
||||
if (!ContainerUtil.isEmpty(filesTargets)) {
|
||||
VirtualFile[] files = filesTargets.stream()
|
||||
.flatMap(target -> Stream.of(((ModuleFilesBuildTask)target).getFiles()))
|
||||
.toArray(VirtualFile[]::new);
|
||||
CompilerManager.getInstance(project).compile(files, compileNotification);
|
||||
CompilerManager.getInstance(project).compile(files, new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
}
|
||||
|
||||
private static void runArtifactsBuildTasks(@NotNull Project project,
|
||||
@NotNull ProjectTaskContext context,
|
||||
@NotNull CompileStatusNotification compileNotification,
|
||||
@NotNull MyNotificationCollector notificationCollector,
|
||||
@NotNull Map<Class<? extends ProjectTask>, List<ProjectTask>> tasksMap) {
|
||||
|
||||
Collection<? extends ProjectTask> buildTasks = tasksMap.get(ProjectModelBuildTask.class);
|
||||
@@ -296,22 +280,116 @@ public class JpsProjectTaskRunner extends ProjectTaskRunner {
|
||||
}
|
||||
}
|
||||
|
||||
buildArtifacts(project, toMake, context.getSessionId(), compileNotification, false);
|
||||
buildArtifacts(project, toCompile, context.getSessionId(), compileNotification, true);
|
||||
buildArtifacts(project, toMake, context.getSessionId(), notificationCollector, false);
|
||||
buildArtifacts(project, toCompile, context.getSessionId(), notificationCollector, true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildArtifacts(@NotNull Project project,
|
||||
@NotNull List<? extends Artifact> artifacts,
|
||||
@Nullable Object sessionId,
|
||||
@Nullable CompileStatusNotification compileNotification,
|
||||
@NotNull MyNotificationCollector notificationCollector,
|
||||
boolean forceArtifactBuild) {
|
||||
if (!artifacts.isEmpty()) {
|
||||
final CompileScope scope = ArtifactCompileScope.createArtifactsScope(project, artifacts, forceArtifactBuild);
|
||||
ArtifactsWorkspaceSettings.getInstance(project).setArtifactsToBuild(artifacts);
|
||||
ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.set(scope, sessionId);
|
||||
//in external build we can set 'rebuild' flag per target type
|
||||
CompilerManager.getInstance(project).make(scope, compileNotification);
|
||||
CompilerManager.getInstance(project).make(scope, new MyCompileStatusNotification(notificationCollector));
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyNotificationCollector implements AutoCloseable {
|
||||
@NotNull private final ProjectTaskContext myContext;
|
||||
@Nullable private final ProjectTaskNotification myTaskNotification;
|
||||
@NotNull private final Runnable myOnFinished;
|
||||
private boolean myCollectingStopped;
|
||||
|
||||
private final Set<MyCompileStatusNotification> myNotifications = ContainerUtil.newIdentityTroveSet();
|
||||
private int myErrors;
|
||||
private int myWarnings;
|
||||
private boolean myAborted;
|
||||
|
||||
|
||||
private MyNotificationCollector(@NotNull ProjectTaskContext context,
|
||||
@Nullable ProjectTaskNotification taskNotification,
|
||||
@NotNull Runnable onFinished) {
|
||||
myContext = context;
|
||||
myTaskNotification = taskNotification;
|
||||
myOnFinished = onFinished;
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
myCollectingStopped = true;
|
||||
}
|
||||
|
||||
synchronized private void notifyFinished() {
|
||||
if (myTaskNotification != null) {
|
||||
myTaskNotification.finished(myContext, new ProjectTaskResult(myAborted, myErrors, myWarnings));
|
||||
}
|
||||
myOnFinished.run();
|
||||
}
|
||||
|
||||
synchronized private void appendJpsBuildResult(boolean aborted, int errors, int warnings,
|
||||
@NotNull CompileContext compileContext,
|
||||
@NotNull MyCompileStatusNotification notification) {
|
||||
if (!myNotifications.remove(notification)) {
|
||||
LOG.error("Multiple invocation of the same callback");
|
||||
}
|
||||
myErrors += errors;
|
||||
myWarnings += warnings;
|
||||
if (aborted) myAborted = true;
|
||||
MyJpsBuildData jpsBuildData = (MyJpsBuildData)JPS_BUILD_DATA_KEY.get(myContext);
|
||||
jpsBuildData.add(compileContext);
|
||||
|
||||
if (myCollectingStopped && myNotifications.isEmpty()) {
|
||||
notifyFinished();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized private void add(@NotNull MyCompileStatusNotification notification) {
|
||||
assert !myCollectingStopped;
|
||||
if (!myNotifications.add(notification)) {
|
||||
LOG.error("Do not use the same callback for different JPS invocations");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyCompileStatusNotification implements CompileStatusNotification {
|
||||
|
||||
private final MyNotificationCollector myCollector;
|
||||
|
||||
private MyCompileStatusNotification(@NotNull MyNotificationCollector collector) {
|
||||
myCollector = collector;
|
||||
myCollector.add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finished(boolean aborted, int errors, int warnings, @NotNull CompileContext compileContext) {
|
||||
myCollector.appendJpsBuildResult(aborted, errors, warnings, compileContext, this);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyJpsBuildData implements JpsBuildData {
|
||||
private final List<CompileContext> myContexts = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public Set<String> getArtifactsWrittenPaths() {
|
||||
return myContexts.stream()
|
||||
.map(ctx -> ArtifactsCompiler.getWrittenPaths(ctx))
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(set -> set.stream())
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompileContext> getFinishedBuildsContexts() {
|
||||
return Collections.unmodifiableList(myContexts);
|
||||
}
|
||||
|
||||
private void add(@NotNull CompileContext context) {
|
||||
myContexts.add(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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-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.debugger.ui;
|
||||
|
||||
@@ -34,8 +20,6 @@ public abstract class HotSwapUI {
|
||||
public abstract void reloadChangedClasses(@NotNull DebuggerSession session, boolean compileBeforeHotswap,
|
||||
@Nullable HotSwapStatusListener callback);
|
||||
|
||||
public abstract void dontPerformHotswapAfterThisCompilation();
|
||||
|
||||
public abstract void addListener(HotSwapVetoableListener listener);
|
||||
|
||||
public abstract void removeListener(HotSwapVetoableListener listener);
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.KeyWithDefaultValue;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.task.*;
|
||||
@@ -38,12 +39,12 @@ import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HotSwapUIImpl extends HotSwapUI {
|
||||
public static final Key<Boolean> SKIP_HOT_SWAP_KEY = KeyWithDefaultValue.create("skip_hotswap_after_this_compilation", false);
|
||||
private static final Key<HotSwapStatusListener> HOT_SWAP_CALLBACK_KEY = Key.create("hot_swap_callback");
|
||||
|
||||
private final List<HotSwapVetoableListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
private boolean myAskBeforeHotswap = true;
|
||||
private final Project myProject;
|
||||
private boolean myPerformHotswapAfterThisCompilation = true;
|
||||
|
||||
public HotSwapUIImpl(@NotNull Project project) {
|
||||
myProject = project;
|
||||
@@ -294,11 +295,6 @@ public class HotSwapUIImpl extends HotSwapUI {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dontPerformHotswapAfterThisCompilation() {
|
||||
myPerformHotswapAfterThisCompilation = false;
|
||||
}
|
||||
|
||||
public void dontAskHotswapAfterThisCompilation() {
|
||||
myAskBeforeHotswap = false;
|
||||
}
|
||||
@@ -324,49 +320,45 @@ public class HotSwapUIImpl extends HotSwapUI {
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (!hasCompilationResults(executionResult)) return;
|
||||
|
||||
int errors = executionResult.getErrors();
|
||||
boolean aborted = executionResult.isAborted();
|
||||
if (errors == 0 && !aborted && myPerformHotswapAfterThisCompilation) {
|
||||
for (HotSwapVetoableListener listener : myListeners) {
|
||||
if (!listener.shouldHotSwap(context, executionResult)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!hasCompilationResults(executionResult)) return;
|
||||
|
||||
List<DebuggerSession> sessions = getHotSwappableDebugSessions();
|
||||
if (!sessions.isEmpty()) {
|
||||
Map<String, Collection<String>> generatedPaths;
|
||||
Collection<String> generatedFilesRoots = context.getGeneratedFilesRoots();
|
||||
if (!generatedFilesRoots.isEmpty()) {
|
||||
generatedPaths = new HashMap<>();
|
||||
for (String outputRoot : generatedFilesRoots) {
|
||||
// collect only classes under IDE output roots
|
||||
if (!JpsPathUtil.isUnder(myOutputRoots, new File(outputRoot))) continue;
|
||||
Collection<String> relativePaths = context.getGeneratedFilesRelativePaths(outputRoot).stream()
|
||||
.filter(relativePath -> StringUtil.endsWith(relativePath, ".class"))
|
||||
.collect(Collectors.toCollection(SmartList::new));
|
||||
if (!relativePaths.isEmpty()) {
|
||||
generatedPaths.put(outputRoot, relativePaths);
|
||||
}
|
||||
}
|
||||
if (generatedPaths.isEmpty()) {
|
||||
generatedPaths = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
generatedPaths = null;
|
||||
}
|
||||
|
||||
HotSwapStatusListener callback = context.getUserData(HOT_SWAP_CALLBACK_KEY);
|
||||
hotSwapSessions(sessions, generatedPaths, callback);
|
||||
int errors = executionResult.getErrors();
|
||||
boolean aborted = executionResult.isAborted();
|
||||
if (errors == 0 && !aborted && !SKIP_HOT_SWAP_KEY.getRequired(context)) {
|
||||
for (HotSwapVetoableListener listener : myListeners) {
|
||||
if (!listener.shouldHotSwap(context, executionResult)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myPerformHotswapAfterThisCompilation = true;
|
||||
|
||||
List<DebuggerSession> sessions = getHotSwappableDebugSessions();
|
||||
if (!sessions.isEmpty()) {
|
||||
Map<String, Collection<String>> generatedPaths;
|
||||
Collection<String> generatedFilesRoots = context.getGeneratedFilesRoots();
|
||||
if (!generatedFilesRoots.isEmpty()) {
|
||||
generatedPaths = new HashMap<>();
|
||||
for (String outputRoot : generatedFilesRoots) {
|
||||
// collect only classes under IDE output roots
|
||||
if (!JpsPathUtil.isUnder(myOutputRoots, new File(outputRoot))) continue;
|
||||
Collection<String> relativePaths = context.getGeneratedFilesRelativePaths(outputRoot).stream()
|
||||
.filter(relativePath -> StringUtil.endsWith(relativePath, ".class"))
|
||||
.collect(Collectors.toCollection(SmartList::new));
|
||||
if (!relativePaths.isEmpty()) {
|
||||
generatedPaths.put(outputRoot, relativePaths);
|
||||
}
|
||||
}
|
||||
if (generatedPaths.isEmpty()) {
|
||||
generatedPaths = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
generatedPaths = null;
|
||||
}
|
||||
|
||||
HotSwapStatusListener callback = context.getUserData(HOT_SWAP_CALLBACK_KEY);
|
||||
hotSwapSessions(sessions, generatedPaths, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,13 @@
|
||||
/*
|
||||
* Copyright 2000-2009 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-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.debugger.ui;
|
||||
|
||||
import com.intellij.compiler.impl.CompileContextImpl;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.DummyCompileContext;
|
||||
import com.intellij.task.ProjectTaskContext;
|
||||
import com.intellij.task.ProjectTaskResult;
|
||||
import com.intellij.task.impl.JpsBuildData;
|
||||
import com.intellij.task.impl.JpsProjectTaskRunner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -40,7 +27,11 @@ public interface HotSwapVetoableListener {
|
||||
* Returns {@code false} if Hot Swap shouldn't be invoked after the given compilation session.
|
||||
*/
|
||||
default boolean shouldHotSwap(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult finishedTasksResult) {
|
||||
CompileContext compileContext = context.getUserData(CompileContextImpl.CONTEXT_KEY);
|
||||
return shouldHotSwap(compileContext != null ? compileContext : DummyCompileContext.getInstance());
|
||||
CompileContext compileContext = DummyCompileContext.getInstance();
|
||||
JpsBuildData jpsBuildData = context.getUserData(JpsProjectTaskRunner.JPS_BUILD_DATA_KEY);
|
||||
if(jpsBuildData != null && jpsBuildData.getFinishedBuildsContexts().size() == 1) {
|
||||
compileContext = jpsBuildData.getFinishedBuildsContexts().get(0);
|
||||
}
|
||||
return shouldHotSwap(compileContext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 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-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.compiler.options;
|
||||
|
||||
import com.intellij.execution.BeforeRunTask;
|
||||
@@ -21,9 +21,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.task.ProjectTask;
|
||||
import com.intellij.task.ProjectTaskContext;
|
||||
import com.intellij.task.ProjectTaskManager;
|
||||
import com.intellij.task.*;
|
||||
import com.intellij.task.impl.EmptyCompileScopeBuildTaskImpl;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -160,12 +158,19 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider<CompileStepBefor
|
||||
}
|
||||
|
||||
if (!myProject.isDisposed()) {
|
||||
projectTaskManager.run(new ProjectTaskContext(sessionId, configuration), projectTask, executionResult -> {
|
||||
if ((executionResult.getErrors() == 0 || ignoreErrors) && !executionResult.isAborted()) {
|
||||
result.set(Boolean.TRUE);
|
||||
}
|
||||
done.up();
|
||||
});
|
||||
ProjectTaskContext context = new ProjectTaskContext(sessionId, configuration);
|
||||
env.copyUserDataTo(context);
|
||||
projectTaskManager.run(context, projectTask,
|
||||
new ProjectTaskNotification() {
|
||||
@Override
|
||||
public void finished(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult executionResult) {
|
||||
if ((executionResult.getErrors() == 0 || ignoreErrors) && !executionResult.isAborted()) {
|
||||
result.set(Boolean.TRUE);
|
||||
}
|
||||
done.up();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
done.up();
|
||||
|
||||
+11
-2
@@ -30,7 +30,10 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.packaging.artifacts.Artifact;
|
||||
import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
|
||||
import com.intellij.task.ProjectTaskContext;
|
||||
import com.intellij.task.ProjectTaskManager;
|
||||
import com.intellij.task.ProjectTaskNotification;
|
||||
import com.intellij.task.ProjectTaskResult;
|
||||
import com.intellij.testFramework.*;
|
||||
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
|
||||
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
|
||||
@@ -412,11 +415,17 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
|
||||
private void build(@NotNull Object[] buildableElements) {
|
||||
final Semaphore semaphore = new Semaphore();
|
||||
semaphore.down();
|
||||
ProjectTaskNotification callback = new ProjectTaskNotification() {
|
||||
@Override
|
||||
public void finished(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult executionResult) {
|
||||
semaphore.up();
|
||||
}
|
||||
};
|
||||
if (buildableElements instanceof Module[]) {
|
||||
ProjectTaskManager.getInstance(myProject).build((Module[])buildableElements, executionResult -> semaphore.up());
|
||||
ProjectTaskManager.getInstance(myProject).build((Module[])buildableElements, callback);
|
||||
}
|
||||
else if (buildableElements instanceof Artifact[]) {
|
||||
ProjectTaskManager.getInstance(myProject).build((Artifact[])buildableElements, executionResult -> semaphore.up());
|
||||
ProjectTaskManager.getInstance(myProject).build((Artifact[])buildableElements, callback);
|
||||
}
|
||||
else {
|
||||
assert false : "Unsupported buildableElements: " + Arrays.toString(buildableElements);
|
||||
|
||||
@@ -1,20 +1,7 @@
|
||||
/*
|
||||
* 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-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;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -23,6 +10,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
public interface ProjectTaskNotification {
|
||||
/**
|
||||
* @param executionResult provides aggregated information about the {@link ProjectTask} execution
|
||||
* @deprecated use {@link #finished(ProjectTaskContext, ProjectTaskResult)} instead
|
||||
*/
|
||||
void finished(@NotNull ProjectTaskResult executionResult);
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2020.1")
|
||||
default void finished(@NotNull ProjectTaskResult executionResult) {}
|
||||
|
||||
/**
|
||||
* @param context tasks execution context
|
||||
* @param executionResult provides aggregated information about the {@link ProjectTask} execution
|
||||
*/
|
||||
default void finished(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult executionResult) { finished(executionResult); }
|
||||
}
|
||||
|
||||
@@ -1,30 +1,20 @@
|
||||
/*
|
||||
* 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-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.task.ProjectTask;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
*/
|
||||
public class ProjectTaskList extends ArrayList<ProjectTask> implements ProjectTask {
|
||||
public class ProjectTaskList extends SmartList<ProjectTask> implements ProjectTask {
|
||||
public ProjectTaskList() {
|
||||
}
|
||||
|
||||
public ProjectTaskList(@NotNull Collection<? extends ProjectTask> c) {
|
||||
super(c);
|
||||
}
|
||||
@@ -34,4 +24,9 @@ public class ProjectTaskList extends ArrayList<ProjectTask> implements ProjectTa
|
||||
public String getPresentableName() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ProjectTaskList asList(ProjectTask... tasks) {
|
||||
return new ProjectTaskList(Arrays.asList(tasks));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,22 +168,22 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
listener.beforeRun(context);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
sendAbortedNotify(new ListenerNotificator(context, callback));
|
||||
sendAbortedNotify(context, new ListenerNotificator(callback));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (toRun.isEmpty()) {
|
||||
sendSuccessNotify(new ListenerNotificator(context, callback));
|
||||
sendSuccessNotify(context, new ListenerNotificator(callback));
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectTaskResultsAggregator callbacksCollector =
|
||||
new ProjectTaskResultsAggregator(new ListenerNotificator(context, callback), toRun.size());
|
||||
new ProjectTaskResultsAggregator(context, new ListenerNotificator(callback), toRun.size());
|
||||
for (Pair<ProjectTaskRunner, Collection<? extends ProjectTask>> pair : toRun) {
|
||||
ProjectTaskRunnerNotification notification = new ProjectTaskRunnerNotification(pair.second, callbacksCollector);
|
||||
if (pair.second.isEmpty()) {
|
||||
sendSuccessNotify(notification);
|
||||
sendSuccessNotify(context, notification);
|
||||
}
|
||||
else {
|
||||
pair.first.run(myProject, context, notification, pair.second);
|
||||
@@ -203,15 +203,15 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
private static void sendSuccessNotify(@Nullable ProjectTaskNotification notification) {
|
||||
private static void sendSuccessNotify(@NotNull ProjectTaskContext context, @Nullable ProjectTaskNotification notification) {
|
||||
if (notification != null) {
|
||||
notification.finished(new ProjectTaskResult(false, 0, 0));
|
||||
notification.finished(context, new ProjectTaskResult(false, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendAbortedNotify(@Nullable ProjectTaskNotification notification) {
|
||||
private static void sendAbortedNotify(@NotNull ProjectTaskContext context, @Nullable ProjectTaskNotification notification) {
|
||||
if (notification != null) {
|
||||
notification.finished(new ProjectTaskResult(true, 0, 0));
|
||||
notification.finished(context, new ProjectTaskResult(true, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
@NotNull ProjectTaskContext context,
|
||||
@Nullable ProjectTaskNotification callback,
|
||||
@NotNull Collection<? extends ProjectTask> tasks) {
|
||||
sendSuccessNotify(callback);
|
||||
sendSuccessNotify(context, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -262,34 +262,31 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
|
||||
private class ListenerNotificator implements ProjectTaskNotification {
|
||||
@Nullable private final ProjectTaskNotification myDelegate;
|
||||
@NotNull private final ProjectTaskContext myContext;
|
||||
|
||||
private ListenerNotificator(@NotNull ProjectTaskContext context,
|
||||
@Nullable ProjectTaskNotification delegate) {
|
||||
myContext = context;
|
||||
private ListenerNotificator(@Nullable ProjectTaskNotification delegate) {
|
||||
myDelegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finished(@NotNull ProjectTaskResult executionResult) {
|
||||
public void finished(@NotNull ProjectTaskContext context, @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);
|
||||
listener.afterRun(context, executionResult);
|
||||
}
|
||||
notify(myContext, executionResult);
|
||||
notify(context, executionResult);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
LOG.debug(e);
|
||||
notify(myContext, new ProjectTaskResult(
|
||||
notify(context, new ProjectTaskResult(
|
||||
false, executionResult.getErrors() + 1, executionResult.getWarnings(), executionResult.getTasksState()));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
notify(myContext, executionResult);
|
||||
notify(context, executionResult);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +296,7 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
myEventPublisher.finished(context, executionResult);
|
||||
}
|
||||
if (myDelegate != null) {
|
||||
myDelegate.finished(executionResult);
|
||||
myDelegate.finished(context, executionResult);
|
||||
}
|
||||
}, ModalityState.defaultModalityState());
|
||||
}
|
||||
@@ -316,7 +313,7 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finished(@NotNull ProjectTaskResult result) {
|
||||
public void finished(@NotNull ProjectTaskContext context, @NotNull ProjectTaskResult result) {
|
||||
if (result.getTasksState().isEmpty()) {
|
||||
final boolean aborted = result.isAborted();
|
||||
final int errors = result.getErrors();
|
||||
@@ -339,6 +336,7 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
}
|
||||
|
||||
private static class ProjectTaskResultsAggregator {
|
||||
private final ProjectTaskContext myContext;
|
||||
private final ProjectTaskNotification myDelegate;
|
||||
private final AtomicInteger myProgressCounter;
|
||||
private final AtomicInteger myErrorsCounter;
|
||||
@@ -346,7 +344,10 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
private final AtomicBoolean myAbortedFlag;
|
||||
private final Map<ProjectTask, ProjectTaskState> myTasksState = ContainerUtil.newConcurrentMap();
|
||||
|
||||
private ProjectTaskResultsAggregator(@NotNull ProjectTaskNotification delegate, int expectedResults) {
|
||||
private ProjectTaskResultsAggregator(@NotNull ProjectTaskContext context,
|
||||
@NotNull ProjectTaskNotification delegate,
|
||||
int expectedResults) {
|
||||
myContext = context;
|
||||
myDelegate = delegate;
|
||||
myProgressCounter = new AtomicInteger(expectedResults);
|
||||
myErrorsCounter = new AtomicInteger();
|
||||
@@ -364,7 +365,7 @@ public class ProjectTaskManagerImpl extends ProjectTaskManager {
|
||||
}
|
||||
if (inProgress <= 0) {
|
||||
ProjectTaskResult result = new ProjectTaskResult(myAbortedFlag.get(), allErrors, allWarnings, myTasksState);
|
||||
myDelegate.finished(result);
|
||||
myDelegate.finished(myContext, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user