diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactAction.java index 6f660d1706a3..e823e88e77d4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactAction.java +++ b/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactAction.java @@ -15,6 +15,7 @@ */ package com.intellij.compiler.actions; +import com.intellij.compiler.CompilerWorkspaceConfiguration; import com.intellij.notification.NotificationGroup; import com.intellij.notification.NotificationType; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -120,12 +121,13 @@ public class BuildArtifactAction extends DumbAwareAction { popup.showCenteredInCurrentWindow(project); } - protected static void doBuild(@NotNull Project project, final @NotNull List items, boolean rebuild) { + private static void doBuild(@NotNull Project project, final @NotNull List items, boolean rebuild) { final Set artifacts = getArtifacts(items, project); - final CompileScope scope = ArtifactCompileScope.createArtifactsScope(project, artifacts); + final CompileScope scope = ArtifactCompileScope.createArtifactsScope(project, artifacts, rebuild); ArtifactsWorkspaceSettings.getInstance(project).setArtifactsToBuild(artifacts); - if (!rebuild) { + if (!rebuild || CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) { + //in external build we can set 'rebuild' flag per target type CompilerManager.getInstance(project).make(scope, null); } else { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java b/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java index 2f55990dfc38..304957977b13 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java @@ -21,6 +21,7 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; +import java.util.Collections; import java.util.List; import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope; @@ -31,8 +32,20 @@ import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage public abstract class BuildTargetScopeProvider { public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.compiler.buildTargetScopeProvider"); + /** + * @deprecated override {@link #getBuildTargetScopes(com.intellij.openapi.compiler.CompileScope, com.intellij.openapi.compiler.CompilerFilter, com.intellij.openapi.project.Project, boolean)} instead + */ @NotNull - public abstract List getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, - @NotNull Project project); + public List getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, + @NotNull Project project) { + return Collections.emptyList(); + } + + + @NotNull + public List getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, + @NotNull Project project, boolean forceBuild) { + return getBuildTargetScopes(baseScope, filter, project); + } } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index b7caf23314a2..e5f3f74daa87 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -254,20 +254,7 @@ public class CompileDriver { return; } try { - final Collection paths = CompileScopeUtil.fetchFiles(compileContext); - List scopes = new ArrayList(); - if (paths.isEmpty()) { - if (!compileContext.isRebuild() && !CompileScopeUtil.allProjectModulesAffected(compileContext)) { - CompileScopeUtil.addScopesForModules(Arrays.asList(compileContext.getCompileScope().getAffectedModules()), scopes); - } - else { - scopes.addAll(CmdlineProtoUtil.createAllModulesScopes()); - } - for (BuildTargetScopeProvider provider : BuildTargetScopeProvider.EP_NAME.getExtensions()) { - scopes = CompileScopeUtil.mergeScopes(scopes, provider.getBuildTargetScopes(compileContext.getCompileScope(), myCompilerFilter, myProject)); - } - } - final RequestFuture future = compileInExternalProcess(compileContext, scopes, paths, true); + final RequestFuture future = compileInExternalProcess(compileContext, true); if (future != null) { while (!future.waitFor(200L , TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { @@ -474,12 +461,24 @@ public class CompileDriver { } @Nullable - private RequestFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, - @NotNull List scopes, - final @NotNull Collection paths, - final boolean onlyCheckUpToDate) + private RequestFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, final boolean onlyCheckUpToDate) throws Exception { final CompileScope scope = compileContext.getCompileScope(); + final Collection paths = CompileScopeUtil.fetchFiles(compileContext); + List scopes = new ArrayList(); + if (paths.isEmpty()) { + boolean forceBuild = !compileContext.isMake(); + if (!compileContext.isRebuild() && !CompileScopeUtil.allProjectModulesAffected(compileContext)) { + CompileScopeUtil.addScopesForModules(Arrays.asList(scope.getAffectedModules()), scopes, forceBuild); + } + else { + scopes.addAll(CmdlineProtoUtil.createAllModulesScopes(forceBuild)); + } + for (BuildTargetScopeProvider provider : BuildTargetScopeProvider.EP_NAME.getExtensions()) { + scopes = CompileScopeUtil.mergeScopes(scopes, provider.getBuildTargetScopes(scope, myCompilerFilter, myProject, forceBuild)); + } + } + // need to pass scope's user data to server final Map builderParams; if (onlyCheckUpToDate) { @@ -683,20 +682,7 @@ public class CompileDriver { return; } - final Collection paths = CompileScopeUtil.fetchFiles(compileContext); - List scopes = new ArrayList(); - if (paths.isEmpty()) { - if (!isRebuild && !CompileScopeUtil.allProjectModulesAffected(compileContext)) { - CompileScopeUtil.addScopesForModules(Arrays.asList(compileContext.getCompileScope().getAffectedModules()), scopes); - } - else { - scopes.addAll(CmdlineProtoUtil.createAllModulesScopes()); - } - for (BuildTargetScopeProvider provider : BuildTargetScopeProvider.EP_NAME.getExtensions()) { - scopes = CompileScopeUtil.mergeScopes(scopes, provider.getBuildTargetScopes(scope, myCompilerFilter, myProject)); - } - } - final RequestFuture future = compileInExternalProcess(compileContext, scopes, paths, false); + final RequestFuture future = compileInExternalProcess(compileContext, false); if (future != null) { while (!future.waitFor(200L , TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileScopeUtil.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileScopeUtil.java index 102db7a12ac0..1f5269e60ad8 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileScopeUtil.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileScopeUtil.java @@ -27,10 +27,10 @@ import java.util.*; * @author nik */ public class CompileScopeUtil { - public static void addScopesForModules(Collection modules, List scopes) { + public static void addScopesForModules(Collection modules, List scopes, boolean forceBuild) { if (!modules.isEmpty()) { for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) { - TargetTypeBuildScope.Builder builder = TargetTypeBuildScope.newBuilder().setTypeId(type.getTypeId()); + TargetTypeBuildScope.Builder builder = TargetTypeBuildScope.newBuilder().setTypeId(type.getTypeId()).setForceBuild(forceBuild); for (Module module : modules) { builder.addTargetId(module.getName()); } @@ -63,15 +63,25 @@ public class CompileScopeUtil { } private static TargetTypeBuildScope mergeScope(TargetTypeBuildScope scope1, TargetTypeBuildScope scope2) { - if (scope1.getAllTargets()) return scope1; - if (scope2.getAllTargets()) return scope2; + String typeId = scope1.getTypeId(); + if (scope1.getAllTargets()) { + return !scope1.getForceBuild() && scope2.getForceBuild() ? createAllTargetForcedBuildScope(typeId) : scope1; + } + if (scope2.getAllTargets()) { + return !scope2.getForceBuild() && scope1.getForceBuild() ? createAllTargetForcedBuildScope(typeId) : scope2; + } return TargetTypeBuildScope.newBuilder() - .setTypeId(scope1.getTypeId()) + .setTypeId(typeId) + .setForceBuild(scope1.getForceBuild() || scope2.getForceBuild()) .addAllTargetId(scope1.getTargetIdList()) .addAllTargetId(scope2.getTargetIdList()) .build(); } + private static TargetTypeBuildScope createAllTargetForcedBuildScope(final String typeId) { + return TargetTypeBuildScope.newBuilder().setTypeId(typeId).setForceBuild(true).setAllTargets(true).build(); + } + public static boolean allProjectModulesAffected(CompileContextImpl compileContext) { final Set allModules = new HashSet(Arrays.asList(compileContext.getProjectCompileScope().getAffectedModules())); allModules.removeAll(Arrays.asList(compileContext.getCompileScope().getAffectedModules())); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index d2985b5a1878..d6a7691195a6 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -428,7 +428,7 @@ public class BuildManager implements ApplicationComponent{ } final List emptyList = Collections.emptyList(); final RequestFuture future = scheduleBuild( - project, false, true, false, CmdlineProtoUtil.createAllModulesScopes(), emptyList, Collections.emptyMap(), new AutoMakeMessageHandler(project) + project, false, true, false, CmdlineProtoUtil.createAllModulesScopes(false), emptyList, Collections.emptyMap(), new AutoMakeMessageHandler(project) ); if (future != null) { futures.add(future); @@ -560,15 +560,14 @@ public class BuildManager implements ApplicationComponent{ final CmdlineRemoteProto.Message.ControllerMessage params; if (isRebuild) { - params = CmdlineProtoUtil.createRebuildRequest(projectPath, scopes, userData, globals); + params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, Collections.emptyList(), userData, globals, null); } else if (onlyCheckUpToDate) { params = CmdlineProtoUtil.createUpToDateCheckRequest(projectPath, scopes, paths, userData, globals, currentFSChanges); } else { - params = isMake ? - CmdlineProtoUtil.createMakeRequest(projectPath, scopes, userData, globals, currentFSChanges) : - CmdlineProtoUtil.createForceCompileRequest(projectPath, scopes, paths, userData, globals, currentFSChanges); + params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, isMake ? Collections.emptyList() : paths, + userData, globals, currentFSChanges); } myMessageDispatcher.registerBuildMessageHandler(sessionId, new BuilderMessageHandlerWrapper(handler) { diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java index c6af2593b486..09d6ba2e1be2 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java @@ -41,7 +41,7 @@ public class ArtifactBuildTargetScopeProvider extends BuildTargetScopeProvider { @NotNull @Override public List getBuildTargetScopes(@NotNull final CompileScope baseScope, @NotNull CompilerFilter filter, - @NotNull final Project project) { + @NotNull final Project project, final boolean forceBuild) { final ArtifactsCompiler compiler = ArtifactsCompiler.getInstance(project); if (compiler == null || !filter.acceptCompiler(compiler)) { return Collections.emptyList(); @@ -52,11 +52,12 @@ public class ArtifactBuildTargetScopeProvider extends BuildTargetScopeProvider { final Set artifacts = ArtifactCompileScope.getArtifactsToBuild(project, baseScope, false); if (ArtifactCompileScope.getArtifacts(baseScope) == null) { Set modules = ArtifactUtil.getModulesIncludedInArtifacts(artifacts, project); - CompileScopeUtil.addScopesForModules(modules, scopes); + CompileScopeUtil.addScopesForModules(modules, scopes, forceBuild); } if (!artifacts.isEmpty()) { - TargetTypeBuildScope.Builder builder = - TargetTypeBuildScope.newBuilder().setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId()); + TargetTypeBuildScope.Builder builder = TargetTypeBuildScope.newBuilder() + .setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId()) + .setForceBuild(ArtifactCompileScope.isArtifactRebuildForced(baseScope)); for (Artifact artifact : artifacts) { builder.addTargetId(artifact.getName()); } diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java index b434eac4328b..abf048489885 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java @@ -41,6 +41,7 @@ import java.util.*; * @author nik */ public class ArtifactCompileScope { + private static final Key FORCE_ARTIFACT_BUILD = Key.create("force_artifact_build"); private static final Key ARTIFACTS_KEY = Key.create("artifacts"); private static final Key> CACHED_ARTIFACTS_KEY = Key.create("cached_artifacts"); private static final Key> ARTIFACTS_CONTENT_ID_KEY = Key.create("build_artifacts_task"); @@ -53,15 +54,34 @@ public class ArtifactCompileScope { return new ModuleCompileScope(project, modules.toArray(new Module[modules.size()]), true); } - public static CompileScope createArtifactsScope(@NotNull Project project, @NotNull Collection artifacts) { - return createScopeWithArtifacts(createScopeForModulesInArtifacts(project, artifacts), artifacts, true); + public static CompileScope createArtifactsScope(@NotNull Project project, + @NotNull Collection artifacts) { + return createArtifactsScope(project, artifacts, false); } - public static CompileScope createScopeWithArtifacts(final CompileScope baseScope, @NotNull Collection artifacts, boolean useCustomContentId) { + public static CompileScope createArtifactsScope(@NotNull Project project, + @NotNull Collection artifacts, + final boolean forceArtifactBuild) { + return createScopeWithArtifacts(createScopeForModulesInArtifacts(project, artifacts), artifacts, true, forceArtifactBuild); + } + + public static CompileScope createScopeWithArtifacts(final CompileScope baseScope, + @NotNull Collection artifacts, + boolean useCustomContentId) { + return createScopeWithArtifacts(baseScope, artifacts, useCustomContentId, false); + } + + public static CompileScope createScopeWithArtifacts(final CompileScope baseScope, + @NotNull Collection artifacts, + boolean useCustomContentId, + final boolean forceArtifactBuild) { baseScope.putUserData(ARTIFACTS_KEY, artifacts.toArray(new Artifact[artifacts.size()])); if (useCustomContentId) { baseScope.putUserData(CompilerManager.CONTENT_ID_KEY, ARTIFACTS_CONTENT_ID_KEY); } + if (forceArtifactBuild) { + baseScope.putUserData(FORCE_ARTIFACT_BUILD, Boolean.TRUE); + } return baseScope; } @@ -101,6 +121,10 @@ public class ArtifactCompileScope { return compileScope.getUserData(ARTIFACTS_KEY); } + public static boolean isArtifactRebuildForced(@NotNull CompileScope scope) { + return Boolean.TRUE.equals(scope.getUserData(FORCE_ARTIFACT_BUILD)); + } + private static boolean containsModuleOutput(Artifact artifact, final Set modules, final PackagingElementResolvingContext context) { return !ArtifactUtil.processPackagingElements(artifact, ProductionModuleOutputElementType.ELEMENT_TYPE, new Processor() { diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java index 8f7528371457..6501f8f77098 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java @@ -161,8 +161,8 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { } protected CompilationLog recompile(final Artifact... artifacts) { - final CompileScope scope = ArtifactCompileScope.createArtifactsScope(myProject, Arrays.asList(artifacts)); - return compile(scope, CompilerFilter.ALL, true); + final CompileScope scope = ArtifactCompileScope.createArtifactsScope(myProject, Arrays.asList(artifacts), true); + return make(scope, CompilerFilter.ALL); } protected CompilationLog make(Module... modules) { @@ -383,6 +383,26 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { return JpsPathUtil.urlToFile(outputUrl); } + protected static void createFileInOutput(Module m, final String fileName) { + try { + boolean created = new File(getOutputDir(m), fileName).createNewFile(); + assertTrue(created); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + protected static void createFileInOutput(Artifact a, final String name) { + try { + boolean created = new File(a.getOutputPath(), name).createNewFile(); + assertTrue(created); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + protected class CompilationLog { private final Set myRecompiledPaths; private final Set myDeletedPaths; diff --git a/jps/jps-builders/proto/cmdline_remote_proto.proto b/jps/jps-builders/proto/cmdline_remote_proto.proto index 3310a3b53b7c..8ccaa5e2e139 100644 --- a/jps/jps-builders/proto/cmdline_remote_proto.proto +++ b/jps/jps-builders/proto/cmdline_remote_proto.proto @@ -50,14 +50,13 @@ message Message { required string type_id = 1; optional bool all_targets = 2; repeated string target_id = 3; + optional bool force_build = 4; } enum Type { - REBUILD = 1; - MAKE = 2; - CLEAN = 3; - FORCED_COMPILATION = 4; - UP_TO_DATE_CHECK = 5; + BUILD = 1; + CLEAN = 2; + UP_TO_DATE_CHECK = 3; } required Type build_type = 1; diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/BuildType.java b/jps/jps-builders/src/org/jetbrains/jps/api/BuildType.java index 5df39130c1b6..7d6c31797072 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/BuildType.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/BuildType.java @@ -20,5 +20,5 @@ package org.jetbrains.jps.api; * Date: 9/10/11 */ public enum BuildType { - PROJECT_REBUILD, FORCED_COMPILATION, MAKE, CLEAN, UP_TO_DATE_CHECK + PROJECT_REBUILD, BUILD, CLEAN, UP_TO_DATE_CHECK } diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineProtoUtil.java b/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineProtoUtil.java index 46397f75509b..28aaeca9d98a 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineProtoUtil.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineProtoUtil.java @@ -34,16 +34,6 @@ import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage */ public class CmdlineProtoUtil { - public static CmdlineRemoteProto.Message.ControllerMessage createMakeRequest(String project, - List scopes, - final Map userData, - final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals, - final @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent event) { - return createBuildParametersMessage( - CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.MAKE, project, scopes, userData, Collections.emptyList(), globals, event - ); - } - public static CmdlineRemoteProto.Message.ControllerMessage createUpToDateCheckRequest(String project, List scopes, Collection paths, @@ -55,39 +45,35 @@ public class CmdlineProtoUtil { ); } - public static CmdlineRemoteProto.Message.ControllerMessage createForceCompileRequest(String project, - List scopes, - Collection paths, - final Map userData, - final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals, - final @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent event) { - return createBuildParametersMessage(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.FORCED_COMPILATION, project, - scopes, userData, paths, globals, event); + public static CmdlineRemoteProto.Message.ControllerMessage createBuildRequest(String project, + List scopes, + Collection paths, + final Map userData, + final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals, + final @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent event) { + return createBuildParametersMessage(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.BUILD, project, scopes, + userData, paths, globals, event); } - public static CmdlineRemoteProto.Message.ControllerMessage createRebuildRequest(String project, - List scopes, - final Map userData, - final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals) { - return createBuildParametersMessage(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.REBUILD, project, - scopes, userData, Collections.emptyList(), - globals, null); - } - - public static List createAllModulesScopes() { + public static List createAllModulesScopes(final boolean forceBuild) { return Arrays.asList( - createAllTargetsScope(JavaModuleBuildTargetType.PRODUCTION), - createAllTargetsScope(JavaModuleBuildTargetType.TEST) + createAllTargetsScope(JavaModuleBuildTargetType.PRODUCTION, forceBuild), + createAllTargetsScope(JavaModuleBuildTargetType.TEST, forceBuild) ); } - public static TargetTypeBuildScope createAllTargetsScope(BuildTargetType type) { + public static TargetTypeBuildScope createAllTargetsScope(BuildTargetType type, boolean forceBuild) { return TargetTypeBuildScope.newBuilder() .setTypeId(type.getTypeId()) .setAllTargets(true) + .setForceBuild(forceBuild) .build(); } + public static TargetTypeBuildScope createTargetsScope(final String targetTypeId, List targetIds, boolean forceBuild) { + return TargetTypeBuildScope.newBuilder().setTypeId(targetTypeId).setForceBuild(forceBuild).addAllTargetId(targetIds).build(); + } + private static CmdlineRemoteProto.Message.ControllerMessage createBuildParametersMessage(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type buildType, String project, List scopes, @@ -120,11 +106,11 @@ public class CmdlineProtoUtil { return controlMessageBuilder.setType(CmdlineRemoteProto.Message.ControllerMessage.Type.BUILD_PARAMETERS).setParamsMessage(builder.build()).build(); } + public static CmdlineRemoteProto.Message.KeyValuePair createPair(String key, String value) { return CmdlineRemoteProto.Message.KeyValuePair.newBuilder().setKey(key).setValue(value).build(); } - public static CmdlineRemoteProto.Message.Failure createFailure(String description, @Nullable Throwable cause) { final CmdlineRemoteProto.Message.Failure.Builder builder = CmdlineRemoteProto.Message.Failure.newBuilder(); if (description != null) { @@ -268,5 +254,4 @@ public class CmdlineProtoUtil { final CmdlineRemoteProto.Message.UUID.Builder uuidBuilder = CmdlineRemoteProto.Message.UUID.newBuilder(); return uuidBuilder.setMostSigBits(sessionId.getMostSignificantBits()).setLeastSigBits(sessionId.getLeastSignificantBits()).build(); } - } diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineRemoteProto.java b/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineRemoteProto.java index 22e8f1658ddd..c14fdfaeaa48 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineRemoteProto.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/CmdlineRemoteProto.java @@ -2327,29 +2327,23 @@ public final class CmdlineRemoteProto { public enum Type implements com.google.protobuf.Internal.EnumLite { - REBUILD(0, 1), - MAKE(1, 2), - CLEAN(2, 3), - FORCED_COMPILATION(3, 4), - UP_TO_DATE_CHECK(4, 5), + BUILD(0, 1), + CLEAN(1, 2), + UP_TO_DATE_CHECK(2, 3), ; - public static final int REBUILD_VALUE = 1; - public static final int MAKE_VALUE = 2; - public static final int CLEAN_VALUE = 3; - public static final int FORCED_COMPILATION_VALUE = 4; - public static final int UP_TO_DATE_CHECK_VALUE = 5; + public static final int BUILD_VALUE = 1; + public static final int CLEAN_VALUE = 2; + public static final int UP_TO_DATE_CHECK_VALUE = 3; public final int getNumber() { return value; } public static Type valueOf(int value) { switch (value) { - case 1: return REBUILD; - case 2: return MAKE; - case 3: return CLEAN; - case 4: return FORCED_COMPILATION; - case 5: return UP_TO_DATE_CHECK; + case 1: return BUILD; + case 2: return CLEAN; + case 3: return UP_TO_DATE_CHECK; default: return null; } } @@ -2390,6 +2384,10 @@ public final class CmdlineRemoteProto { java.util.List getTargetIdList(); int getTargetIdCount(); String getTargetId(int index); + + // optional bool force_build = 4; + boolean hasForceBuild(); + boolean getForceBuild(); } public static final class TargetTypeBuildScope extends com.google.protobuf.GeneratedMessageLite @@ -2466,10 +2464,21 @@ public final class CmdlineRemoteProto { return targetId_.get(index); } + // optional bool force_build = 4; + public static final int FORCE_BUILD_FIELD_NUMBER = 4; + private boolean forceBuild_; + public boolean hasForceBuild() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + public boolean getForceBuild() { + return forceBuild_; + } + private void initFields() { typeId_ = ""; allTargets_ = false; targetId_ = com.google.protobuf.LazyStringArrayList.EMPTY; + forceBuild_ = false; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -2496,6 +2505,9 @@ public final class CmdlineRemoteProto { for (int i = 0; i < targetId_.size(); i++) { output.writeBytes(3, targetId_.getByteString(i)); } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBool(4, forceBuild_); + } } private int memoizedSerializedSize = -1; @@ -2521,6 +2533,10 @@ public final class CmdlineRemoteProto { size += dataSize; size += 1 * getTargetIdList().size(); } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(4, forceBuild_); + } memoizedSerializedSize = size; return size; } @@ -2629,6 +2645,8 @@ public final class CmdlineRemoteProto { bitField0_ = (bitField0_ & ~0x00000002); targetId_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000004); + forceBuild_ = false; + bitField0_ = (bitField0_ & ~0x00000008); return this; } @@ -2676,6 +2694,10 @@ public final class CmdlineRemoteProto { bitField0_ = (bitField0_ & ~0x00000004); } result.targetId_ = targetId_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000004; + } + result.forceBuild_ = forceBuild_; result.bitField0_ = to_bitField0_; return result; } @@ -2698,6 +2720,9 @@ public final class CmdlineRemoteProto { } } + if (other.hasForceBuild()) { + setForceBuild(other.getForceBuild()); + } return this; } @@ -2741,6 +2766,11 @@ public final class CmdlineRemoteProto { targetId_.add(input.readBytes()); break; } + case 32: { + bitField0_ |= 0x00000008; + forceBuild_ = input.readBool(); + break; + } } } } @@ -2860,6 +2890,27 @@ public final class CmdlineRemoteProto { } + // optional bool force_build = 4; + private boolean forceBuild_ ; + public boolean hasForceBuild() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + public boolean getForceBuild() { + return forceBuild_; + } + public Builder setForceBuild(boolean value) { + bitField0_ |= 0x00000008; + forceBuild_ = value; + + return this; + } + public Builder clearForceBuild() { + bitField0_ = (bitField0_ & ~0x00000008); + forceBuild_ = false; + + return this; + } + // @@protoc_insertion_point(builder_scope:org.jetbrains.jpsservice.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope) } @@ -2981,7 +3032,7 @@ public final class CmdlineRemoteProto { } private void initFields() { - buildType_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.REBUILD; + buildType_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.BUILD; globalSettings_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.getDefaultInstance(); projectId_ = ""; scope_ = java.util.Collections.emptyList(); @@ -3179,7 +3230,7 @@ public final class CmdlineRemoteProto { public Builder clear() { super.clear(); - buildType_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.REBUILD; + buildType_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.BUILD; bitField0_ = (bitField0_ & ~0x00000001); globalSettings_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.getDefaultInstance(); bitField0_ = (bitField0_ & ~0x00000002); @@ -3390,7 +3441,7 @@ public final class CmdlineRemoteProto { private int bitField0_; // required .org.jetbrains.jpsservice.Message.ControllerMessage.ParametersMessage.Type build_type = 1; - private org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type buildType_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.REBUILD; + private org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type buildType_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.BUILD; public boolean hasBuildType() { return ((bitField0_ & 0x00000001) == 0x00000001); } @@ -3408,7 +3459,7 @@ public final class CmdlineRemoteProto { } public Builder clearBuildType() { bitField0_ = (bitField0_ & ~0x00000001); - buildType_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.REBUILD; + buildType_ = org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type.BUILD; return this; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java index db367a6d56d5..85746d92ff4f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java @@ -74,7 +74,7 @@ public class JavaBuilderUtil { final Mappings globalMappings = context.getProjectDescriptor().dataManager.getMappings(); - if (!context.isProjectRebuild()) { + if (!isForcedRecompilationAllJavaModules(context)) { if (context.shouldDifferentiate(chunk)) { context.processMessage(new ProgressMessage("Checking dependencies... [" + chunk.getName() + "]")); final Set allCompiledFiles = getAllCompiledFilesContainer(context); @@ -138,7 +138,7 @@ public class JavaBuilderUtil { for (File file : newlyAffectedFiles) { FSOperations.markDirtyIfNotDeleted(context, file); } - additionalPassRequired = context.isMake() && chunkContainsAffectedFiles(context, chunk, newlyAffectedFiles); + additionalPassRequired = !isForcedRecompilationJava(context) && chunkContainsAffectedFiles(context, chunk, newlyAffectedFiles); } } else { @@ -146,7 +146,7 @@ public class JavaBuilderUtil { LOG.info("Non-incremental mode: " + messageText); context.processMessage(new ProgressMessage(messageText)); - additionalPassRequired = context.isMake(); + additionalPassRequired = !isForcedRecompilationJava(context); FSOperations.markDirtyRecursively(context, chunk); } } @@ -184,6 +184,16 @@ public class JavaBuilderUtil { } } + public static boolean isForcedRecompilationAllJavaModules(CompileContext context) { + CompileScope scope = context.getScope(); + return scope.isRecompilationForcedForAllTargets(JavaModuleBuildTargetType.PRODUCTION) && scope.isRecompilationForcedForAllTargets(JavaModuleBuildTargetType.TEST); + } + + public static boolean isForcedRecompilationJava(CompileContext context) { + CompileScope scope = context.getScope(); + return scope.isRecompilationForcedForTargetsOfType(JavaModuleBuildTargetType.PRODUCTION) && scope.isRecompilationForcedForTargetsOfType(JavaModuleBuildTargetType.TEST); + } + private static List> checkAffectedFilesInCorrectModules(CompileContext context, Collection affected, ModulesBasedFileFilter moduleBasedFilter) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java index 14a12542d300..51a43222ae6e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java @@ -112,29 +112,20 @@ public class BuildRunner { targetIndex, buildRootIndex, ignoredFileIndex); } + public void setForceCleanCaches(boolean forceCleanCaches) { + myForceCleanCaches = forceCleanCaches; + } + public void runBuild(ProjectDescriptor pd, CanceledStatus cs, @Nullable Callbacks.ConstantAffectionResolver constantSearch, MessageHandler msgHandler, BuildType buildType) throws Exception { for (int attempt = 0; attempt < 2; attempt++) { - if (myForceCleanCaches && myScopes.isEmpty() && myFilePaths.isEmpty()) { - // if compilation scope is the whole project and cache rebuild is forced, use PROJECT_REBUILD for faster compilation - buildType = BuildType.PROJECT_REBUILD; - } - - final CompileScope compileScope = createCompilationScope(buildType, pd, myScopes, myFilePaths); + final CompileScope compileScope = createCompilationScope(pd, myScopes, myFilePaths); final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), myBuilderParams, cs, constantSearch); builder.addMessageHandler(msgHandler); try { switch (buildType) { - case PROJECT_REBUILD: - builder.build(compileScope, false, true, myForceCleanCaches); - break; - - case FORCED_COMPILATION: - builder.build(compileScope, false, false, myForceCleanCaches); - break; - - case MAKE: - builder.build(compileScope, true, false, myForceCleanCaches); + case BUILD: + builder.build(compileScope, myForceCleanCaches); break; case CLEAN: @@ -159,9 +150,10 @@ public class BuildRunner { } } - private static CompileScope createCompilationScope(BuildType buildType, ProjectDescriptor pd, List scopes, - Collection paths) throws Exception { + private CompileScope createCompilationScope(ProjectDescriptor pd, List scopes, + Collection paths) throws Exception { Set> targetTypes = new HashSet>(); + Set> targetTypesToForceBuild = new HashSet>(); Set> targets = new HashSet>(); Map, Set> files; @@ -172,6 +164,9 @@ public class BuildRunner { LOG.info("Unknown target type: " + scope.getTypeId()); continue; } + if (scope.getForceBuild() || myForceCleanCaches && paths.isEmpty()) { + targetTypesToForceBuild.add(targetType); + } if (scope.getAllTargets()) { targetTypes.add(targetType); } @@ -202,7 +197,7 @@ public class BuildRunner { files.put(descriptor.getTarget(), fileSet); } fileSet.add(file); - if (buildType == BuildType.FORCED_COMPILATION) { + if (targetTypesToForceBuild.contains(descriptor.getTarget().getTargetType())) { pd.fsState.markDirty(null, file, descriptor, timestamps, false); } } @@ -212,7 +207,7 @@ public class BuildRunner { files = Collections.emptyMap(); } - return new CompileScopeImpl(!(buildType == BuildType.MAKE || buildType == BuildType.UP_TO_DATE_CHECK), targetTypes, targets, files); + return new CompileScopeImpl(targetTypes, targetTypesToForceBuild, targets, files); } public List getScopes() { diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index e638739b6cda..e246ad13a5fa 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -171,8 +171,8 @@ final class BuildSession implements Runnable, CanceledStatus { return; } if (!dataStorageRoot.exists()) { - // invoked the very first time for this project. Force full rebuild - myBuildType = BuildType.PROJECT_REBUILD; + // invoked the very first time for this project + myBuildRunner.setForceCleanCaches(true); } final DataInputStream fsStateStream = createFSDataStream(dataStorageRoot); @@ -180,7 +180,8 @@ final class BuildSession implements Runnable, CanceledStatus { if (fsStateStream != null) { // optimization: check whether we can skip the build final boolean hasWorkToDoWithModules = fsStateStream.readBoolean(); - if (!myForceModelLoading && (myBuildType == BuildType.MAKE || myBuildType == BuildType.UP_TO_DATE_CHECK) && !hasWorkToDoWithModules && scopeContainsModulesOnly(myBuildRunner.getScopes()) && !containsChanges(myInitialFSDelta)) { + if (!myForceModelLoading && (myBuildType == BuildType.BUILD || myBuildType == BuildType.UP_TO_DATE_CHECK) && !hasWorkToDoWithModules + && scopeContainsModulesOnlyForIncrementalMake(myBuildRunner.getScopes()) && !containsChanges(myInitialFSDelta)) { updateFsStateOnDisk(dataStorageRoot, fsStateStream, myInitialFSDelta.getOrdinal()); return; } @@ -219,9 +220,10 @@ final class BuildSession implements Runnable, CanceledStatus { } } - private static boolean scopeContainsModulesOnly(List scopes) { + private static boolean scopeContainsModulesOnlyForIncrementalMake(List scopes) { TargetTypeRegistry typeRegistry = null; for (TargetTypeBuildScope scope : scopes) { + if (scope.getForceBuild()) return false; final String typeId = scope.getTypeId(); if (isJavaModuleBuildType(typeId)) { // fast check continue; @@ -551,12 +553,10 @@ final class BuildSession implements Runnable, CanceledStatus { private static BuildType convertCompileType(CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.Type compileType) { switch (compileType) { case CLEAN: return BuildType.CLEAN; - case MAKE: return BuildType.MAKE; - case REBUILD: return BuildType.PROJECT_REBUILD; - case FORCED_COMPILATION: return BuildType.FORCED_COMPILATION; + case BUILD: return BuildType.BUILD; case UP_TO_DATE_CHECK: return BuildType.UP_TO_DATE_CHECK; } - return BuildType.MAKE; // use make by default + return BuildType.BUILD; } private static class EventsProcessor extends SequentialTaskExecutor { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java index 6a95e49e3144..b702b2d01c3e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java @@ -112,8 +112,7 @@ public class BuildOperations { if (!Utils.errorsDetected(context) && !context.getCancelStatus().isCanceled()) { boolean marked = dropRemovedPaths(context, chunk); for (BuildTarget target : chunk.getTargets()) { - if (context.isMake() && target instanceof ModuleBuildTarget) { - // ensure non-incremental flag cleared + if (target instanceof ModuleBuildTarget) { context.clearNonIncrementalMark((ModuleBuildTarget)target); } final Timestamps timestamps = pd.timestamps.getStorage(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index b878c75b3180..8c1fe8b68c6e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -31,8 +31,14 @@ public interface CompileContext extends UserDataHolder, MessageHandler { CompileScope getScope(); + /** + * @deprecated use {@link org.jetbrains.jps.builders.java.JavaBuilderUtil#isForcedRecompilationJava(CompileContext)} for java-related usages + */ boolean isMake(); + /** + * @deprecated use {@link org.jetbrains.jps.builders.java.JavaBuilderUtil#isForcedRecompilationAllJavaModules(CompileContext)} for java-related usages + */ boolean isProjectRebuild(); @Nullable diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContextImpl.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContextImpl.java index 5ccf72e73312..a621595fcc28 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContextImpl.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContextImpl.java @@ -21,6 +21,7 @@ import com.intellij.util.EventDispatcher; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.api.CanceledStatus; +import org.jetbrains.jps.builders.java.JavaBuilderUtil; import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; import org.jetbrains.jps.builders.logging.BuildLoggingManager; import org.jetbrains.jps.cmdline.ProjectDescriptor; @@ -38,8 +39,6 @@ import java.util.*; public class CompileContextImpl extends UserDataHolderBase implements CompileContext { private static final String CANCELED_MESSAGE = "The build has been canceled"; private final CompileScope myScope; - private final boolean myIsMake; - private final boolean myIsProjectRebuild; private final MessageHandler myDelegateMessageHandler; private final Set myNonIncrementalModules = new HashSet(); @@ -51,8 +50,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon private EventDispatcher myListeners = EventDispatcher.create(BuildListener.class); public CompileContextImpl(CompileScope scope, - ProjectDescriptor pd, boolean isMake, - boolean isProjectRebuild, + ProjectDescriptor pd, MessageHandler delegateMessageHandler, Map builderParams, CanceledStatus cancelStatus) throws ProjectBuildException { @@ -61,8 +59,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon myCancelStatus = cancelStatus; myCompilationStartStamp = System.currentTimeMillis(); myScope = scope; - myIsProjectRebuild = isProjectRebuild; - myIsMake = !isProjectRebuild && isMake; myDelegateMessageHandler = delegateMessageHandler; } @@ -78,12 +74,12 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon @Override public boolean isMake() { - return myIsMake; + return !JavaBuilderUtil.isForcedRecompilationJava(this); } @Override public boolean isProjectRebuild() { - return myIsProjectRebuild; + return JavaBuilderUtil.isForcedRecompilationAllJavaModules(this); } @Override @@ -117,8 +113,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon @Override public boolean shouldDifferentiate(ModuleChunk chunk) { - if (!isMake()) { - // the check makes sense only in make mode + if (myNonIncrementalModules.isEmpty()) { return true; } for (ModuleBuildTarget target : chunk.getTargets()) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScope.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScope.java index c88525841237..1f1f5e73a8fc 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScope.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScope.java @@ -17,6 +17,7 @@ package org.jetbrains.jps.incremental; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.builders.BuildTarget; +import org.jetbrains.jps.builders.BuildTargetType; import java.io.File; @@ -30,4 +31,8 @@ public abstract class CompileScope { public abstract boolean isAffected(@NotNull BuildTarget target); public abstract boolean isRecompilationForced(@NotNull BuildTarget target); + + public abstract boolean isRecompilationForcedForAllTargets(@NotNull BuildTargetType targetType); + + public abstract boolean isRecompilationForcedForTargetsOfType(@NotNull BuildTargetType targetType); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScopeImpl.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScopeImpl.java index f3ecd6885712..136363819084 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScopeImpl.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileScopeImpl.java @@ -15,9 +15,11 @@ */ package org.jetbrains.jps.incremental; +import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.builders.BuildTarget; import org.jetbrains.jps.builders.BuildTargetType; +import org.jetbrains.jps.builders.ModuleBasedBuildTargetType; import org.jetbrains.jps.builders.ModuleBasedTarget; import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; import org.jetbrains.jps.model.module.JpsModule; @@ -31,15 +33,29 @@ import java.util.Set; * @author nik */ public class CompileScopeImpl extends CompileScope { - protected final boolean myForcedCompilation; private final Collection> myTypes; + private final Collection> myTypesToForceBuild; private final Collection> myTargets; private final Map, Set> myFiles; - public CompileScopeImpl(boolean forcedCompilation, Collection> types, Collection> targets, + public CompileScopeImpl(Collection> types, + Collection> typesToForceBuild, + Collection> targets, Map, Set> files) { - myForcedCompilation = forcedCompilation; myTypes = types; + myTypesToForceBuild = new HashSet>(); + boolean forceBuildAllModuleBasedTargets = false; + for (BuildTargetType type : typesToForceBuild) { + myTypesToForceBuild.add(type); + forceBuildAllModuleBasedTargets |= type instanceof JavaModuleBuildTargetType; + } + if (forceBuildAllModuleBasedTargets) { + for (BuildTargetType targetType : TargetTypeRegistry.getInstance().getTargetTypes()) { + if (targetType instanceof ModuleBasedBuildTargetType) { + myTypesToForceBuild.add(targetType); + } + } + } myTargets = targets; myFiles = files; } @@ -51,7 +67,18 @@ public class CompileScopeImpl extends CompileScope { @Override public boolean isRecompilationForced(@NotNull BuildTarget target) { - return myForcedCompilation && (myTypes.contains(target.getTargetType()) || myTargets.contains(target) || isAffectedByAssociatedModule(target)); + BuildTargetType type = target.getTargetType(); + return myTypesToForceBuild.contains(type) && (myTypes.contains(type) || myTargets.contains(target) || isAffectedByAssociatedModule(target)); + } + + @Override + public boolean isRecompilationForcedForAllTargets(@NotNull BuildTargetType targetType) { + return myTypesToForceBuild.contains(targetType) && myTypes.contains(targetType); + } + + @Override + public boolean isRecompilationForcedForTargetsOfType(@NotNull BuildTargetType targetType) { + return myTypesToForceBuild.contains(targetType); } @Override diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java index 545cdc762c04..a3fedd494268 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java @@ -26,6 +26,7 @@ import org.jetbrains.jps.builders.BuildRootIndex; import org.jetbrains.jps.builders.BuildTarget; import org.jetbrains.jps.builders.FileProcessor; import org.jetbrains.jps.builders.impl.BuildTargetChunk; +import org.jetbrains.jps.builders.java.JavaBuilderUtil; import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor; import org.jetbrains.jps.cmdline.ProjectDescriptor; import org.jetbrains.jps.incremental.storage.Timestamps; @@ -113,7 +114,7 @@ public class FSOperations { markDirtyFiles(context, target, timestamps, true, null, null); } - if (context.isMake()) { + if (!JavaBuilderUtil.isForcedRecompilationJava(context)) { // mark as non-incremental only the module that triggered non-incremental change for (ModuleBuildTarget target : targets) { context.markNonIncremental(target); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index a326da67dfb4..fdca9022b89b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -130,7 +130,7 @@ public class IncProjectBuilder { public void checkUpToDate(CompileScope scope) { CompileContextImpl context = null; try { - context = createContext(scope, true, false); + context = createContext(scope); final BuildFSState fsState = myProjectDescriptor.fsState; for (BuildTarget target : myProjectDescriptor.getBuildTargetIndex().getAllTargets()) { if (scope.isAffected(target)) { @@ -164,8 +164,7 @@ public class IncProjectBuilder { } - public void build(CompileScope scope, final boolean isMake, final boolean isProjectRebuild, boolean forceCleanCaches) - throws RebuildRequestedException { + public void build(CompileScope scope, boolean forceCleanCaches) throws RebuildRequestedException { final LowMemoryWatcher memWatcher = LowMemoryWatcher.register(new Runnable() { @Override @@ -176,7 +175,7 @@ public class IncProjectBuilder { }); CompileContextImpl context = null; try { - context = createContext(scope, isMake, isProjectRebuild); + context = createContext(scope); runBuild(context, forceCleanCaches); myProjectDescriptor.dataManager.saveVersion(); reportRebuiltModules(context); @@ -326,14 +325,13 @@ public class IncProjectBuilder { } - private CompileContextImpl createContext(CompileScope scope, boolean isMake, final boolean isProjectRebuild) - throws ProjectBuildException { - final CompileContextImpl context = new CompileContextImpl(scope, myProjectDescriptor, isMake, isProjectRebuild, myMessageDispatcher, - myBuilderParams, myCancelStatus - ); + private CompileContextImpl createContext(CompileScope scope) throws ProjectBuildException { + final CompileContextImpl context = new CompileContextImpl(scope, myProjectDescriptor, myMessageDispatcher, + myBuilderParams, myCancelStatus); + // in project rebuild mode performance gain is hard to observe, so it is better to save memory // in make mode it is critical to traverse file system as fast as possible, so we choose speed over memory savings - myProjectDescriptor.setFSCache(isProjectRebuild? FSCache.NO_CACHE : new FSCache()); + myProjectDescriptor.setFSCache(context.isProjectRebuild() ? FSCache.NO_CACHE : new FSCache()); JavaBuilderUtil.CONSTANT_SEARCH_SERVICE.set(context, myConstantSearch); return context; } @@ -964,7 +962,7 @@ public class IncProjectBuilder { FSOperations.processFilesToRecompile(context, chunk, processor); } }; - if (!context.isProjectRebuild()) { + if (!JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)) { final Map> cleanedSources = BuildOperations .cleanOutputsCorrespondingToChangedFiles(context, dirtyFilesHolder); for (Map.Entry> entry : cleanedSources.entrySet()) { @@ -1006,7 +1004,7 @@ public class IncProjectBuilder { nextPassRequired = true; } else if (buildResult == ModuleLevelBuilder.ExitCode.CHUNK_REBUILD_REQUIRED) { - if (!rebuildFromScratchRequested && !context.isProjectRebuild()) { + if (!rebuildFromScratchRequested && !JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)) { LOG.info("Builder " + builder.getPresentableName() + " requested rebuild of module chunk " + chunk.getName()); // allow rebuild from scratch only once per chunk rebuildFromScratchRequested = true; diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 97ea01db976b..411d0b550e6d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -171,7 +171,7 @@ public class JavaBuilder extends ModuleLevelBuilder { } }); - if (context.isMake()) { + if (!JavaBuilderUtil.isForcedRecompilationJava(context)) { final ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger(); if (logger.isEnabled()) { if (filesToCompile.size() > 0) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java index f1886d2d42e9..4b731645877e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java @@ -1,19 +1,3 @@ -/* - * Copyright 2000-2012 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. - */ - // Generated by the protocol buffer compiler. DO NOT EDIT! // source: javac_remote_proto.proto diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java index b8c901470e28..0d1c0afa6d56 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java @@ -15,7 +15,6 @@ */ package org.jetbrains.jps.builders; -import org.jetbrains.jps.api.BuildType; import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; import org.jetbrains.jps.incremental.CompileScope; import org.jetbrains.jps.incremental.CompileScopeImpl; @@ -27,6 +26,7 @@ import org.jetbrains.jps.model.artifact.JpsArtifact; import org.jetbrains.jps.model.module.JpsModule; import java.io.File; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -35,28 +35,24 @@ import java.util.Set; * @author nik */ public class CompileScopeTestBuilder { - private BuildType myBuildType; - private Set> myTargetTypes = new HashSet>(); - private Set> myTargets = new HashSet>(); + private final boolean myForceBuild; + private final Set> myTargetTypes = new HashSet>(); + private final Set> myTargets = new HashSet>(); public static CompileScopeTestBuilder rebuild() { - return new CompileScopeTestBuilder(BuildType.PROJECT_REBUILD); + return new CompileScopeTestBuilder(true); } public static CompileScopeTestBuilder make() { - return new CompileScopeTestBuilder(BuildType.MAKE); + return new CompileScopeTestBuilder(false); } public static CompileScopeTestBuilder recompile() { - return new CompileScopeTestBuilder(BuildType.FORCED_COMPILATION); + return new CompileScopeTestBuilder(true); } - private CompileScopeTestBuilder(BuildType buildType) { - myBuildType = buildType; - } - - public BuildType getBuildType() { - return myBuildType; + private CompileScopeTestBuilder(boolean forceBuild) { + myForceBuild = forceBuild; } public CompileScopeTestBuilder allModules() { @@ -81,7 +77,8 @@ public class CompileScopeTestBuilder { } public CompileScope build() { - return new CompileScopeImpl(myBuildType != BuildType.MAKE, myTargetTypes, myTargets, Collections.,Set>emptyMap()); + Collection> typesToForceBuild = myForceBuild ? myTargetTypes : Collections.>emptyList(); + return new CompileScopeImpl(myTargetTypes, typesToForceBuild, myTargets, Collections.,Set>emptyMap()); } public CompileScopeTestBuilder all() { diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java index 5751878802f8..68b617670adc 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java @@ -25,7 +25,6 @@ import com.intellij.testFramework.UsefulTestCase; import com.intellij.util.containers.hash.HashMap; import com.intellij.util.io.TestFileSystemBuilder; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.api.BuildType; import org.jetbrains.jps.api.CanceledStatus; import org.jetbrains.jps.builders.impl.BuildDataPathsImpl; import org.jetbrains.jps.builders.impl.BuildRootIndexImpl; @@ -288,7 +287,7 @@ public abstract class JpsBuildTestCase extends UsefulTestCase { BuildResult result = new BuildResult(); builder.addMessageHandler(result); try { - builder.build(scopeBuilder.build(), scopeBuilder.getBuildType() == BuildType.MAKE, scopeBuilder.getBuildType() == BuildType.PROJECT_REBUILD, false); + builder.build(scopeBuilder.build(), false); } catch (RebuildRequestedException e) { throw new RuntimeException(e); diff --git a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java index 8c6de9834979..e52c8ac3b087 100644 --- a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java +++ b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java @@ -115,7 +115,6 @@ public class Standalone { } JpsModelLoaderImpl loader = new JpsModelLoaderImpl(projectPath, globalOptionsPath, initializer); - BuildType buildType = incremental ? BuildType.MAKE : BuildType.PROJECT_REBUILD; Set modulesSet = new HashSet(Arrays.asList(modules)); List artifactsList = Arrays.asList(artifacts); File dataStorageRoot; @@ -132,7 +131,7 @@ public class Standalone { long start = System.currentTimeMillis(); try { - runBuild(loader, dataStorageRoot, buildType, modulesSet, artifactsList, true, new ConsoleMessageHandler()); + runBuild(loader, dataStorageRoot, !incremental, modulesSet, artifactsList, true, new ConsoleMessageHandler()); } catch (Throwable t) { System.err.println("Internal error: " + t.getMessage()); @@ -141,12 +140,12 @@ public class Standalone { System.out.println("Build finished in " + Utils.formatDuration(System.currentTimeMillis() - start)); } - public static void runBuild(JpsModelLoader loader, final File dataStorageRoot, BuildType buildType, Set modulesSet, + public static void runBuild(JpsModelLoader loader, final File dataStorageRoot, boolean forceBuild, Set modulesSet, List artifactsList, final boolean includeTests, final MessageHandler messageHandler) throws Exception { List scopes = new ArrayList(); for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) { if (includeTests || !type.isTests()) { - TargetTypeBuildScope.Builder builder = TargetTypeBuildScope.newBuilder().setTypeId(type.getTypeId()); + TargetTypeBuildScope.Builder builder = TargetTypeBuildScope.newBuilder().setTypeId(type.getTypeId()).setForceBuild(forceBuild); if (modulesSet.isEmpty()) { builder.setAllTargets(true); } @@ -157,12 +156,12 @@ public class Standalone { } } if (!artifactsList.isEmpty()) { - scopes.add(TargetTypeBuildScope.newBuilder().setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId()).addAllTargetId(artifactsList).build()); + scopes.add(TargetTypeBuildScope.newBuilder().setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId()).setForceBuild(forceBuild).addAllTargetId(artifactsList).build()); } final BuildRunner buildRunner = new BuildRunner(loader, scopes, Collections.emptyList(), Collections.emptyMap()); ProjectDescriptor descriptor = buildRunner.load(messageHandler, dataStorageRoot, new BuildFSState(true)); try { - buildRunner.runBuild(descriptor, CanceledStatus.NULL, null, messageHandler, buildType); + buildRunner.runBuild(descriptor, CanceledStatus.NULL, null, messageHandler, BuildType.BUILD); } finally { descriptor.release(); diff --git a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java index a5f4f35f6405..3ec94962dd20 100644 --- a/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java +++ b/jps/standalone-builder/src/org/jetbrains/jps/gant/JpsGantProjectBuilder.java @@ -22,7 +22,6 @@ import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.api.BuildType; import org.jetbrains.jps.build.Standalone; import org.jetbrains.jps.cmdline.JpsModelLoader; import org.jetbrains.jps.incremental.MessageHandler; @@ -173,7 +172,7 @@ public class JpsGantProjectBuilder { Logger.setFactory(new AntLoggerFactory(messageHandler)); info("Starting build: modules = " + modulesSet + ", caches are saved to " + myDataStorageRoot.getAbsolutePath()); try { - Standalone.runBuild(myModelLoader, myDataStorageRoot, BuildType.PROJECT_REBUILD, modulesSet, Collections.emptyList(), + Standalone.runBuild(myModelLoader, myDataStorageRoot, true, modulesSet, Collections.emptyList(), includeTests, messageHandler); } catch (Throwable e) { diff --git a/plugins/devkit/src/build/PluginModuleBuildScopeProvider.java b/plugins/devkit/src/build/PluginModuleBuildScopeProvider.java index d4899785a7f7..79bccac2c71e 100644 --- a/plugins/devkit/src/build/PluginModuleBuildScopeProvider.java +++ b/plugins/devkit/src/build/PluginModuleBuildScopeProvider.java @@ -22,6 +22,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.devkit.module.PluginModuleType; +import org.jetbrains.jps.api.CmdlineProtoUtil; import org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope; import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTargetType; @@ -35,7 +36,8 @@ import java.util.List; public class PluginModuleBuildScopeProvider extends BuildTargetScopeProvider { @NotNull @Override - public List getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project) { + public List getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, + @NotNull Project project, boolean forceBuild) { List pluginArtifactTargetIds = new ArrayList(); for (Module module : baseScope.getAffectedModules()) { if (PluginModuleType.isOfType(module)) { @@ -46,6 +48,6 @@ public class PluginModuleBuildScopeProvider extends BuildTargetScopeProvider { if (pluginArtifactTargetIds.isEmpty()) { return Collections.emptyList(); } - return Collections.singletonList(TargetTypeBuildScope.newBuilder().setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId()).addAllTargetId(pluginArtifactTargetIds).build()); + return Collections.singletonList(CmdlineProtoUtil.createTargetsScope(ArtifactBuildTargetType.INSTANCE.getTypeId(), pluginArtifactTargetIds, forceBuild)); } } diff --git a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java index 4e096a64a24d..8d0840af44be 100644 --- a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java +++ b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java @@ -210,7 +210,7 @@ public class GroovyBuilder extends ModuleLevelBuilder { } private static boolean checkChunkRebuildNeeded(CompileContext context, GroovycOSProcessHandler handler) { - if (context.isProjectRebuild() || !handler.shouldRetry()) { + if (JavaBuilderUtil.isForcedRecompilationAllJavaModules(context) || !handler.shouldRetry()) { return false; } diff --git a/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsBindingManager.java b/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsBindingManager.java index 60ce10a7f051..63a1fb4aff85 100644 --- a/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsBindingManager.java +++ b/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsBindingManager.java @@ -25,6 +25,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.builders.DirtyFilesHolder; import org.jetbrains.jps.builders.FileProcessor; +import org.jetbrains.jps.builders.java.JavaBuilderUtil; import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor; import org.jetbrains.jps.incremental.*; import org.jetbrains.jps.incremental.java.CopyResourcesUtil; @@ -103,7 +104,7 @@ public class FormsBindingManager extends FormsBuilder { final Map formsToCompile = new THashMap(FileUtil.FILE_HASHING_STRATEGY); final Map> srcToForms = new THashMap>(FileUtil.FILE_HASHING_STRATEGY); - if (!context.isProjectRebuild() && config.isInstrumentClasses() && FORCE_FORMS_REBUILD_FLAG.get(context, Boolean.FALSE)) { + if (!JavaBuilderUtil.isForcedRecompilationAllJavaModules(context) && config.isInstrumentClasses() && FORCE_FORMS_REBUILD_FLAG.get(context, Boolean.FALSE)) { // force compilation of all forms, but only once per chunk if (!FORMS_REBUILD_FORCED.get(context, Boolean.FALSE)) { FORMS_REBUILD_FORCED.set(context, Boolean.TRUE); diff --git a/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java b/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java index 146354137d0e..f14efe33dc0c 100644 --- a/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java +++ b/plugins/ui-designer/jps-plugin/src/org/jetbrains/jps/uiDesigner/compiler/FormsInstrumenter.java @@ -31,6 +31,7 @@ import org.jetbrains.asm4.ClassReader; import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.ProjectPaths; import org.jetbrains.jps.builders.DirtyFilesHolder; +import org.jetbrains.jps.builders.java.JavaBuilderUtil; import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor; import org.jetbrains.jps.builders.logging.ProjectBuilderLogger; import org.jetbrains.jps.incremental.*; @@ -77,7 +78,7 @@ public class FormsInstrumenter extends FormsBuilder { formsToCompile.addAll(files); } - if (context.isMake()) { + if (!JavaBuilderUtil.isForcedRecompilationJava(context)) { final ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger(); if (logger.isEnabled()) { logger.logCompiledFiles(formsToCompile, getPresentableName(), "Compiling forms:");