mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
external compiler: building process ruled by BuildTargets instead of modules
This commit is contained in:
@@ -170,7 +170,7 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider<CompileStepBefor
|
||||
|
||||
@Nullable
|
||||
public static RunConfiguration getRunConfiguration(final CompileContext context) {
|
||||
return context.getCompileScope().getUserData(RUN_CONFIGURATION);
|
||||
return getRunConfiguration(context.getCompileScope());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -21,16 +21,18 @@ public class ModuleChunk {
|
||||
}
|
||||
};
|
||||
private Set<JpsModule> myModules;
|
||||
private final boolean myTests;
|
||||
private final boolean myContainsTests;
|
||||
private Set<ModuleBuildTarget> myTargets;
|
||||
|
||||
public ModuleChunk(Set<ModuleBuildTarget> targets, boolean tests) {
|
||||
myTests = tests;
|
||||
public ModuleChunk(Set<ModuleBuildTarget> targets) {
|
||||
boolean containsTests = false;
|
||||
myTargets = targets;
|
||||
myModules = new LinkedHashSet<JpsModule>();
|
||||
for (ModuleBuildTarget target : targets) {
|
||||
myModules.add(target.getModule());
|
||||
containsTests |= target.isTests();
|
||||
}
|
||||
myContainsTests = containsTests;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -42,8 +44,8 @@ public class ModuleChunk {
|
||||
return myModules;
|
||||
}
|
||||
|
||||
public boolean isTests() {
|
||||
return myTests;
|
||||
public boolean containsTests() {
|
||||
return myContainsTests;
|
||||
}
|
||||
|
||||
public Set<ModuleBuildTarget> getTargets() {
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
package org.jetbrains.jps;
|
||||
|
||||
import com.intellij.util.graph.CachingSemiGraph;
|
||||
import com.intellij.util.graph.DFSTBuilder;
|
||||
import com.intellij.util.graph.GraphGenerator;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget;
|
||||
import org.jetbrains.jps.model.JpsProject;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class ProjectChunks {
|
||||
private List<ModuleChunk> chunks;
|
||||
private List<ModuleBuildTarget> myAllTargets;
|
||||
private Map<ModuleBuildTarget, Collection<ModuleBuildTarget>> myTargetDependencies;
|
||||
private final JpsProject myProject;
|
||||
|
||||
public ProjectChunks(JpsProject project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public List<ModuleChunk> getChunkList() {
|
||||
initializeChunks();
|
||||
return chunks;
|
||||
}
|
||||
|
||||
private void initializeChunks() {
|
||||
if (chunks != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
myAllTargets = new ArrayList<ModuleBuildTarget>(myProject.getModules().size()*2);
|
||||
for (JpsModule module : myProject.getModules()) {
|
||||
myAllTargets.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
|
||||
myAllTargets.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.TEST));
|
||||
}
|
||||
myTargetDependencies = new HashMap<ModuleBuildTarget, Collection<ModuleBuildTarget>>();
|
||||
for (ModuleBuildTarget target : myAllTargets) {
|
||||
myTargetDependencies.put(target, target.computeDependencies());
|
||||
}
|
||||
|
||||
GraphGenerator<ModuleBuildTarget> graph = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<ModuleBuildTarget>() {
|
||||
@Override
|
||||
public Collection<ModuleBuildTarget> getNodes() {
|
||||
return myAllTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ModuleBuildTarget> getIn(ModuleBuildTarget n) {
|
||||
return myTargetDependencies.get(n).iterator();
|
||||
}
|
||||
}));
|
||||
|
||||
final DFSTBuilder<ModuleBuildTarget> builder = new DFSTBuilder<ModuleBuildTarget>(graph);
|
||||
final TIntArrayList sccs = builder.getSCCs();
|
||||
|
||||
chunks = new ArrayList<ModuleChunk>(sccs.size());
|
||||
sccs.forEach(new TIntProcedure() {
|
||||
int myTNumber = 0;
|
||||
public boolean execute(int size) {
|
||||
final Set<ModuleBuildTarget> chunkNodes = new LinkedHashSet<ModuleBuildTarget>();
|
||||
boolean test = false;
|
||||
for (int j = 0; j < size; j++) {
|
||||
final ModuleBuildTarget node = builder.getNodeByTNumber(myTNumber + j);
|
||||
test = node.isTests();//production target cannot depend on test so this flag is the same for all nodes in the cycle
|
||||
chunkNodes.add(node);
|
||||
}
|
||||
chunks.add(new ModuleChunk(chunkNodes, test));
|
||||
|
||||
myTNumber += size;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Collection<ModuleBuildTarget> getAllTargets() {
|
||||
initializeChunks();
|
||||
return myAllTargets;
|
||||
}
|
||||
|
||||
public Set<ModuleBuildTarget> getDependenciesRecursively(ModuleBuildTarget target) {
|
||||
initializeChunks();
|
||||
LinkedHashSet<ModuleBuildTarget> result = new LinkedHashSet<ModuleBuildTarget>();
|
||||
for (ModuleBuildTarget dep : myTargetDependencies.get(target)) {
|
||||
collectDependenciesRecursively(dep, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void collectDependenciesRecursively(ModuleBuildTarget target, LinkedHashSet<ModuleBuildTarget> result) {
|
||||
if (result.add(target)) {
|
||||
for (ModuleBuildTarget dep : myTargetDependencies.get(target)) {
|
||||
collectDependenciesRecursively(dep, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,11 +41,11 @@ public class ProjectPaths {
|
||||
}
|
||||
|
||||
public Collection<File> getPlatformCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
|
||||
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.isTests()), excludeMainModuleOutput, ClasspathPart.BEFORE_JDK, true);
|
||||
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.BEFORE_JDK, true);
|
||||
}
|
||||
|
||||
public Collection<File> getCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
|
||||
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.isTests()), excludeMainModuleOutput, ClasspathPart.AFTER_JDK, true);
|
||||
return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.AFTER_JDK, true);
|
||||
}
|
||||
|
||||
private Collection<File> getClasspathFiles(ModuleChunk chunk,
|
||||
@@ -94,7 +94,7 @@ public class ProjectPaths {
|
||||
* @return mapping "sourceRoot" -> "package prefix" Package prefix uses slashes instead of dots and ends with trailing slash
|
||||
*/
|
||||
public static Map<File, String> getSourceRootsWithDependents(ModuleChunk chunk) {
|
||||
final boolean includeTests = chunk.isTests();
|
||||
final boolean includeTests = chunk.containsTests();
|
||||
final Map<File, String> result = new LinkedHashMap<File, String>();
|
||||
processModulesRecursively(chunk, JpsJavaClasspathKind.compile(includeTests), new Consumer<JpsModule>() {
|
||||
@Override
|
||||
@@ -122,7 +122,7 @@ public class ProjectPaths {
|
||||
}
|
||||
|
||||
public static Collection<File> getOutputPathsWithDependents(final ModuleChunk chunk) {
|
||||
final boolean forTests = chunk.isTests();
|
||||
final boolean forTests = chunk.containsTests();
|
||||
final Set<File> sourcePaths = new LinkedHashSet<File>();
|
||||
processModulesRecursively(chunk, JpsJavaClasspathKind.compile(forTests), new Consumer<JpsModule>() {
|
||||
@Override
|
||||
|
||||
@@ -25,7 +25,7 @@ public abstract class BuildTarget<R extends BuildRootDescriptor> {
|
||||
return myTargetType;
|
||||
}
|
||||
|
||||
public abstract Collection<? extends BuildTarget<?>> computeDependencies();
|
||||
public abstract Collection<BuildTarget<?>> computeDependencies();
|
||||
|
||||
public void writeConfiguration(PrintWriter out, BuildRootIndex buildRootIndex) {
|
||||
}
|
||||
@@ -36,8 +36,11 @@ public abstract class BuildTarget<R extends BuildRootDescriptor> {
|
||||
@Nullable
|
||||
public abstract BuildRootDescriptor findRootDescriptor(String rootId, BuildRootIndex rootIndex);
|
||||
|
||||
@NotNull
|
||||
public abstract String getPresentableName();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myTargetType.getTypeId() + " '" + getId() + "'";
|
||||
return getPresentableName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package org.jetbrains.jps.builders;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -10,5 +13,14 @@ import java.util.Collection;
|
||||
public interface BuildTargetIndex {
|
||||
@NotNull
|
||||
<T extends BuildTarget<?>>
|
||||
Collection<T> getAllTargets(@NotNull BuildTargetType<T> type);
|
||||
List<T> getAllTargets(@NotNull BuildTargetType<T> type);
|
||||
|
||||
@NotNull
|
||||
Collection<BuildTarget<?>> getDependencies(@NotNull BuildTarget<?> target);
|
||||
|
||||
List<BuildTargetChunk> getSortedTargetChunks();
|
||||
|
||||
List<? extends BuildTarget<?>> getAllTargets();
|
||||
|
||||
Set<BuildTarget<?>> getDependenciesRecursively(BuildTarget<?> target);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.jetbrains.jps.builders;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -20,7 +20,7 @@ public abstract class BuildTargetType<T extends BuildTarget<?>> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract Collection<T> computeAllTargets(@NotNull JpsModel model);
|
||||
public abstract List<T> computeAllTargets(@NotNull JpsModel model);
|
||||
|
||||
@NotNull
|
||||
public abstract BuildTargetLoader<T> createLoader(@NotNull JpsModel model);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.jetbrains.jps.builders.impl;
|
||||
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class BuildTargetChunk {
|
||||
private Set<BuildTarget<?>> myTargets;
|
||||
|
||||
public BuildTargetChunk(Set<BuildTarget<?>> targets) {
|
||||
myTargets = targets;
|
||||
}
|
||||
|
||||
public Set<BuildTarget<?>> getTargets() {
|
||||
return myTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myTargets.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
package org.jetbrains.jps.builders.impl;
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.graph.CachingSemiGraph;
|
||||
import com.intellij.util.graph.DFSTBuilder;
|
||||
import com.intellij.util.graph.GraphGenerator;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.BuildTargetIndex;
|
||||
@@ -7,27 +13,112 @@ import org.jetbrains.jps.builders.BuildTargetType;
|
||||
import org.jetbrains.jps.incremental.BuilderRegistry;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class BuildTargetIndexImpl implements BuildTargetIndex {
|
||||
private Map<BuildTargetType<?>, Collection<? extends BuildTarget<?>>> myTargets;
|
||||
private Map<BuildTargetType<?>, List<? extends BuildTarget<?>>> myTargets;
|
||||
private Map<BuildTarget<?>, Collection<BuildTarget<?>>> myDependencies;
|
||||
private List<BuildTargetChunk> myTargetChunks;
|
||||
private final List<BuildTarget<?>> myAllTargets;
|
||||
|
||||
public BuildTargetIndexImpl(@NotNull JpsModel model) {
|
||||
myTargets = new HashMap<BuildTargetType<?>, Collection<? extends BuildTarget<?>>>();
|
||||
myTargets = new HashMap<BuildTargetType<?>, List<? extends BuildTarget<?>>>();
|
||||
List<List<? extends BuildTarget<?>>> targetsByType = new ArrayList<List<? extends BuildTarget<?>>>();
|
||||
for (BuildTargetType<?> type : BuilderRegistry.getInstance().getTargetTypes()) {
|
||||
myTargets.put(type, type.computeAllTargets(model));
|
||||
List<? extends BuildTarget<?>> targets = type.computeAllTargets(model);
|
||||
myTargets.put(type, targets);
|
||||
targetsByType.add(targets);
|
||||
}
|
||||
myDependencies = new HashMap<BuildTarget<?>, Collection<BuildTarget<?>>>();
|
||||
myAllTargets = ContainerUtil.concat(targetsByType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T extends BuildTarget<?>> List<T> getAllTargets(@NotNull BuildTargetType<T> type) {
|
||||
//noinspection unchecked
|
||||
return (List<T>)myTargets.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BuildTargetChunk> getSortedTargetChunks() {
|
||||
initializeChunks();
|
||||
return myTargetChunks;
|
||||
}
|
||||
|
||||
|
||||
private synchronized void initializeChunks() {
|
||||
if (myTargetChunks != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (BuildTarget<?> target : getAllTargets()) {
|
||||
myDependencies.put(target, target.computeDependencies());
|
||||
}
|
||||
|
||||
GraphGenerator<BuildTarget<?>>
|
||||
graph = GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<BuildTarget<?>>() {
|
||||
@Override
|
||||
public Collection<BuildTarget<?>> getNodes() {
|
||||
return myAllTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<BuildTarget<?>> getIn(BuildTarget<?> n) {
|
||||
return myDependencies.get(n).iterator();
|
||||
}
|
||||
}));
|
||||
|
||||
final DFSTBuilder<BuildTarget<?>> builder = new DFSTBuilder<BuildTarget<?>>(graph);
|
||||
final TIntArrayList sccs = builder.getSCCs();
|
||||
|
||||
myTargetChunks = new ArrayList<BuildTargetChunk>(sccs.size());
|
||||
sccs.forEach(new TIntProcedure() {
|
||||
int myTNumber = 0;
|
||||
public boolean execute(int size) {
|
||||
final Set<BuildTarget<?>> chunkNodes = new LinkedHashSet<BuildTarget<?>>();
|
||||
for (int j = 0; j < size; j++) {
|
||||
final BuildTarget<?> node = builder.getNodeByTNumber(myTNumber + j);
|
||||
chunkNodes.add(node);
|
||||
}
|
||||
myTargetChunks.add(new BuildTargetChunk(chunkNodes));
|
||||
|
||||
myTNumber += size;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends BuildTarget<?>> getAllTargets() {
|
||||
return myAllTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<BuildTarget<?>> getDependenciesRecursively(BuildTarget<?> target) {
|
||||
initializeChunks();
|
||||
LinkedHashSet<BuildTarget<?>> result = new LinkedHashSet<BuildTarget<?>>();
|
||||
for (BuildTarget<?> dep : myDependencies.get(target)) {
|
||||
collectDependenciesRecursively(dep, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void collectDependenciesRecursively(BuildTarget<?> target, LinkedHashSet<BuildTarget<?>> result) {
|
||||
if (result.add(target)) {
|
||||
for (BuildTarget<?> dep : myDependencies.get(target)) {
|
||||
collectDependenciesRecursively(dep, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T extends BuildTarget<?>> Collection<T> getAllTargets(@NotNull BuildTargetType<T> type) {
|
||||
//noinspection unchecked
|
||||
return (Collection<T>)myTargets.get(type);
|
||||
public Collection<BuildTarget<?>> getDependencies(@NotNull BuildTarget<?> target) {
|
||||
initializeChunks();
|
||||
return myDependencies.get(target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public class JavaModuleBuildTargetType extends BuildTargetType<ModuleBuildTarget
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<ModuleBuildTarget> computeAllTargets(@NotNull JpsModel model) {
|
||||
public List<ModuleBuildTarget> computeAllTargets(@NotNull JpsModel model) {
|
||||
List<JpsModule> modules = model.getProject().getModules();
|
||||
List<ModuleBuildTarget> targets = new ArrayList<ModuleBuildTarget>(modules.size());
|
||||
for (JpsModule module : modules) {
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.jetbrains.jps.incremental;
|
||||
|
||||
/**
|
||||
* @see ModuleLevelBuilder
|
||||
* @see ProjectLevelBuilder
|
||||
* @see TargetBuilder
|
||||
*
|
||||
* @author nik
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ public class BuilderRegistry {
|
||||
static final BuilderRegistry ourInstance = new BuilderRegistry();
|
||||
}
|
||||
private final Map<BuilderCategory, List<ModuleLevelBuilder>> myModuleLevelBuilders = new HashMap<BuilderCategory, List<ModuleLevelBuilder>>();
|
||||
private final List<ProjectLevelBuilder> myProjectLevelBuilders = new ArrayList<ProjectLevelBuilder>();
|
||||
private final List<TargetBuilder<?>> myTargetBuilders = new ArrayList<TargetBuilder<?>>();
|
||||
private final Map<String, BuildTargetType<?>> myTargetTypes = new LinkedHashMap<String, BuildTargetType<?>>();
|
||||
|
||||
public static BuilderRegistry getInstance() {
|
||||
@@ -31,7 +31,7 @@ public class BuilderRegistry {
|
||||
}
|
||||
|
||||
for (BuilderService service : JpsServiceManager.getInstance().getExtensions(BuilderService.class)) {
|
||||
myProjectLevelBuilders.addAll(service.createProjectLevelBuilders());
|
||||
myTargetBuilders.addAll(service.createBuilders());
|
||||
final List<? extends ModuleLevelBuilder> moduleLevelBuilders = service.createModuleLevelBuilders();
|
||||
for (ModuleLevelBuilder builder : moduleLevelBuilders) {
|
||||
myModuleLevelBuilders.get(builder.getCategory()).add(builder);
|
||||
@@ -79,7 +79,7 @@ public class BuilderRegistry {
|
||||
return ContainerUtil.concat(myModuleLevelBuilders.values());
|
||||
}
|
||||
|
||||
public List<ProjectLevelBuilder> getProjectLevelBuilders() {
|
||||
return myProjectLevelBuilders;
|
||||
public List<TargetBuilder<?>> getTargetBuilders() {
|
||||
return myTargetBuilders;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public abstract class BuilderService {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<? extends ProjectLevelBuilder> createProjectLevelBuilders() {
|
||||
public List<? extends TargetBuilder<?>> createBuilders() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.intellij.openapi.util.UserDataHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.ModuleChunk;
|
||||
import org.jetbrains.jps.ProjectChunks;
|
||||
import org.jetbrains.jps.ProjectPaths;
|
||||
import org.jetbrains.jps.api.CanceledStatus;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
@@ -47,8 +46,6 @@ public interface CompileContext extends UserDataHolder, MessageHandler {
|
||||
|
||||
void setDone(float done);
|
||||
|
||||
ProjectChunks getChunks();
|
||||
|
||||
long getCompilationStartStamp();
|
||||
|
||||
void markNonIncremental(ModuleBuildTarget target);
|
||||
|
||||
@@ -29,7 +29,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
private final CompileScope myScope;
|
||||
private final boolean myIsMake;
|
||||
private final boolean myIsProjectRebuild;
|
||||
private final ProjectChunks myChunks;
|
||||
private final MessageHandler myDelegateMessageHandler;
|
||||
private final Set<ModuleBuildTarget> myNonIncrementalModules = new HashSet<ModuleBuildTarget>();
|
||||
|
||||
@@ -55,7 +54,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
myScope = scope;
|
||||
myIsProjectRebuild = isProjectRebuild;
|
||||
myIsMake = !isProjectRebuild && isMake;
|
||||
myChunks = new ProjectChunks(pd.jpsProject);
|
||||
myDelegateMessageHandler = delegateMessageHandler;
|
||||
myProjectPaths = new ProjectPaths(pd.jpsProject);
|
||||
}
|
||||
@@ -65,11 +63,6 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon
|
||||
return myCompilationStartStamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectChunks getChunks() {
|
||||
return myChunks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectPaths getProjectPaths() {
|
||||
return myProjectPaths;
|
||||
|
||||
@@ -7,7 +7,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.JpsPathUtil;
|
||||
import org.jetbrains.jps.ModuleChunk;
|
||||
import org.jetbrains.jps.ProjectChunks;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
import org.jetbrains.jps.incremental.fs.RootDescriptor;
|
||||
@@ -65,21 +66,26 @@ public class FSOperations {
|
||||
final Set<ModuleBuildTarget> dirtyTargets = new HashSet<ModuleBuildTarget>(targets);
|
||||
|
||||
// now mark all modules that depend on dirty modules
|
||||
final JpsJavaClasspathKind classpathKind = JpsJavaClasspathKind.compile(chunk.isTests());
|
||||
final ProjectChunks chunks = context.getChunks();
|
||||
final JpsJavaClasspathKind classpathKind = JpsJavaClasspathKind.compile(chunk.containsTests());
|
||||
boolean found = false;
|
||||
for (ModuleChunk moduleChunk : chunks.getChunkList()) {
|
||||
for (BuildTargetChunk targetChunk : context.getProjectDescriptor().getBuildTargetIndex().getSortedTargetChunks()) {
|
||||
if (!found) {
|
||||
if (moduleChunk.equals(chunk)) {
|
||||
if (targetChunk.getTargets().equals(chunk.getTargets())) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (final JpsModule module : moduleChunk.getModules()) {
|
||||
final Set<JpsModule> deps = getDependentModulesRecursively(module, classpathKind);
|
||||
if (Utils.intersects(deps, modules)) {
|
||||
dirtyTargets.addAll(moduleChunk.getTargets());
|
||||
break;
|
||||
for (final BuildTarget<?> target : targetChunk.getTargets()) {
|
||||
if (target instanceof ModuleBuildTarget) {
|
||||
final Set<JpsModule> deps = getDependentModulesRecursively(((ModuleBuildTarget)target).getModule(), classpathKind);
|
||||
if (Utils.intersects(deps, modules)) {
|
||||
for (BuildTarget<?> buildTarget : targetChunk.getTargets()) {
|
||||
if (buildTarget instanceof ModuleBuildTarget) {
|
||||
dirtyTargets.add((ModuleBuildTarget)buildTarget);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.JpsPathUtil;
|
||||
import org.jetbrains.jps.ModuleChunk;
|
||||
import org.jetbrains.jps.ProjectChunks;
|
||||
import org.jetbrains.jps.ProjectPaths;
|
||||
import org.jetbrains.jps.api.CanceledStatus;
|
||||
import org.jetbrains.jps.api.GlobalOptions;
|
||||
import org.jetbrains.jps.api.RequestFuture;
|
||||
import org.jetbrains.jps.builders.BuildRootDescriptor;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.BuildTargetIndex;
|
||||
import org.jetbrains.jps.builders.BuildTargetType;
|
||||
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
|
||||
import org.jetbrains.jps.builders.java.JavaBuilderUtil;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
|
||||
@@ -89,8 +90,8 @@ public class IncProjectBuilder {
|
||||
}
|
||||
};
|
||||
|
||||
private volatile float myModulesProcessed = 0.0f;
|
||||
private final float myTotalModulesWork;
|
||||
private volatile float myTargetsProcessed = 0.0f;
|
||||
private final float myTotalTargetsWork;
|
||||
private final int myTotalModuleLevelBuilderCount;
|
||||
private final List<Future> myAsyncTasks = new ArrayList<Future>();
|
||||
|
||||
@@ -101,7 +102,7 @@ public class IncProjectBuilder {
|
||||
myBuilderParams = builderParams;
|
||||
myCancelStatus = cs;
|
||||
myConstantSearch = constantSearch;
|
||||
myTotalModulesWork = pd.jpsProject.getModules().size() * 2; /* multiply by 2 to reflect production and test sources */
|
||||
myTotalTargetsWork = pd.getBuildTargetIndex().getAllTargets().size();
|
||||
myTotalModuleLevelBuilderCount = builderRegistry.getModuleLevelBuilderCount();
|
||||
}
|
||||
|
||||
@@ -202,9 +203,9 @@ public class IncProjectBuilder {
|
||||
}
|
||||
|
||||
private float updateFractionBuilderFinished(final float delta) {
|
||||
myModulesProcessed += delta;
|
||||
float processed = myModulesProcessed;
|
||||
return processed / myTotalModulesWork;
|
||||
myTargetsProcessed += delta;
|
||||
float processed = myTargetsProcessed;
|
||||
return processed / myTotalTargetsWork;
|
||||
}
|
||||
|
||||
private void runBuild(CompileContextImpl context, boolean forceCleanCaches) throws ProjectBuildException {
|
||||
@@ -212,7 +213,7 @@ public class IncProjectBuilder {
|
||||
|
||||
LOG.info("Building project; isRebuild:" + context.isProjectRebuild() + "; isMake:" + context.isMake() + " parallel compilation:" + BuildRunner.PARALLEL_BUILD_ENABLED);
|
||||
|
||||
for (ProjectLevelBuilder builder : myBuilderRegistry.getProjectLevelBuilders()) {
|
||||
for (TargetBuilder builder : myBuilderRegistry.getTargetBuilders()) {
|
||||
builder.buildStarted(context);
|
||||
}
|
||||
for (ModuleLevelBuilder builder : myBuilderRegistry.getModuleLevelBuilders()) {
|
||||
@@ -228,10 +229,7 @@ public class IncProjectBuilder {
|
||||
runTasks(context, myBuilderRegistry.getBeforeTasks());
|
||||
|
||||
context.processMessage(new ProgressMessage("Checking sources"));
|
||||
buildChunks(context, context.getChunks());
|
||||
|
||||
context.processMessage(new ProgressMessage("Building project"));
|
||||
runProjectLevelBuilders(context);
|
||||
buildChunks(context);
|
||||
|
||||
context.processMessage(new ProgressMessage("Running 'after' tasks"));
|
||||
runTasks(context, myBuilderRegistry.getAfterTasks());
|
||||
@@ -253,7 +251,7 @@ public class IncProjectBuilder {
|
||||
//}
|
||||
}
|
||||
finally {
|
||||
for (ProjectLevelBuilder builder : myBuilderRegistry.getProjectLevelBuilders()) {
|
||||
for (TargetBuilder builder : myBuilderRegistry.getTargetBuilders()) {
|
||||
builder.buildFinished(context);
|
||||
}
|
||||
for (ModuleLevelBuilder builder : myBuilderRegistry.getModuleLevelBuilders()) {
|
||||
@@ -281,7 +279,7 @@ public class IncProjectBuilder {
|
||||
clearOutputs(context);
|
||||
}
|
||||
else {
|
||||
for (ModuleBuildTarget target : context.getChunks().getAllTargets()) {
|
||||
for (BuildTarget<?> target : context.getProjectDescriptor().getBuildTargetIndex().getAllTargets()) {
|
||||
clearOutputFiles(context, target);
|
||||
}
|
||||
}
|
||||
@@ -325,18 +323,20 @@ public class IncProjectBuilder {
|
||||
|
||||
final ProjectPaths paths = context.getProjectPaths();
|
||||
|
||||
for (ModuleBuildTarget target : context.getChunks().getAllTargets()) {
|
||||
final File out = paths.getModuleOutputDir(target.getModule(), target.isTests());
|
||||
if (out != null) {
|
||||
rootsToDelete.putValue(out, target);
|
||||
}
|
||||
for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) {
|
||||
for (ModuleBuildTarget target : context.getProjectDescriptor().getBuildTargetIndex().getAllTargets(type)) {
|
||||
final File out = paths.getModuleOutputDir(target.getModule(), target.isTests());
|
||||
if (out != null) {
|
||||
rootsToDelete.putValue(out, target);
|
||||
}
|
||||
|
||||
final ProcessorConfigProfile profile = context.getAnnotationProcessingProfile(target.getModule());
|
||||
if (profile.isEnabled()) {
|
||||
File annotationOut =
|
||||
paths.getAnnotationProcessorGeneratedSourcesOutputDir(target.getModule(), target.isTests(), profile.getGeneratedSourcesDirectoryName());
|
||||
if (annotationOut != null) {
|
||||
annotationOutputs.add(annotationOut);
|
||||
final ProcessorConfigProfile profile = context.getAnnotationProcessingProfile(target.getModule());
|
||||
if (profile.isEnabled()) {
|
||||
File annotationOut =
|
||||
paths.getAnnotationProcessorGeneratedSourcesOutputDir(target.getModule(), target.isTests(), profile.getGeneratedSourcesDirectoryName());
|
||||
if (annotationOut != null) {
|
||||
annotationOutputs.add(annotationOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,36 +390,28 @@ public class IncProjectBuilder {
|
||||
);
|
||||
}
|
||||
|
||||
private static void appendRootInfo(Map<File, Set<ModuleBuildTarget>> rootsToDelete, File out, ModuleBuildTarget target) {
|
||||
Set<ModuleBuildTarget> infos = rootsToDelete.get(out);
|
||||
if (infos == null) {
|
||||
infos = new HashSet<ModuleBuildTarget>();
|
||||
rootsToDelete.put(out, infos);
|
||||
}
|
||||
infos.add(target);
|
||||
}
|
||||
|
||||
private static void runTasks(CompileContext context, final List<BuildTask> tasks) throws ProjectBuildException {
|
||||
for (BuildTask task : tasks) {
|
||||
task.build(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildChunks(final CompileContextImpl context, ProjectChunks chunks) throws ProjectBuildException {
|
||||
private void buildChunks(final CompileContextImpl context) throws ProjectBuildException {
|
||||
final CompileScope scope = context.getScope();
|
||||
final ProjectDescriptor pd = context.getProjectDescriptor();
|
||||
BuildTargetIndex targetIndex = pd.getBuildTargetIndex();
|
||||
try {
|
||||
if (BuildRunner.PARALLEL_BUILD_ENABLED) {
|
||||
final List<ChunkGroup> chunkGroups = buildChunkGroups(chunks);
|
||||
final List<ChunkGroup> chunkGroups = buildChunkGroups(targetIndex);
|
||||
for (ChunkGroup group : chunkGroups) {
|
||||
final List<ModuleChunk> groupChunks = group.getChunks();
|
||||
final List<BuildTargetChunk> groupChunks = group.getChunks();
|
||||
final int chunkCount = groupChunks.size();
|
||||
if (chunkCount == 0) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
if (chunkCount == 1) {
|
||||
_buildChunk(createContextWrapper(context), scope, groupChunks.iterator().next());
|
||||
buildChunkIfAffected(createContextWrapper(context), scope, groupChunks.iterator().next());
|
||||
}
|
||||
else {
|
||||
final CountDownLatch latch = new CountDownLatch(chunkCount);
|
||||
@@ -427,19 +419,19 @@ public class IncProjectBuilder {
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
final StringBuilder logBuilder = new StringBuilder("Building chunks in parallel: ");
|
||||
for (ModuleChunk chunk : groupChunks) {
|
||||
logBuilder.append(chunk.getName()).append("; ");
|
||||
for (BuildTargetChunk chunk : groupChunks) {
|
||||
logBuilder.append(chunk.toString()).append("; ");
|
||||
}
|
||||
LOG.debug(logBuilder.toString());
|
||||
}
|
||||
|
||||
for (final ModuleChunk chunk : groupChunks) {
|
||||
for (final BuildTargetChunk chunk : groupChunks) {
|
||||
final CompileContext chunkLocalContext = createContextWrapper(context);
|
||||
myParallelBuildExecutor.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
_buildChunk(chunkLocalContext, scope, chunk);
|
||||
buildChunkIfAffected(chunkLocalContext, scope, chunk);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
synchronized (exRef) {
|
||||
@@ -482,9 +474,9 @@ public class IncProjectBuilder {
|
||||
}
|
||||
else {
|
||||
// non-parallel build
|
||||
for (ModuleChunk chunk : chunks.getChunkList()) {
|
||||
for (BuildTargetChunk chunk : targetIndex.getSortedTargetChunks()) {
|
||||
try {
|
||||
_buildChunk(context, scope, chunk);
|
||||
buildChunkIfAffected(context, scope, chunk);
|
||||
}
|
||||
finally {
|
||||
pd.dataManager.closeSourceToOutputStorages(Collections.singleton(chunk));
|
||||
@@ -498,18 +490,18 @@ public class IncProjectBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void _buildChunk(CompileContext context, CompileScope scope, ModuleChunk chunk) throws ProjectBuildException {
|
||||
private void buildChunkIfAffected(CompileContext context, CompileScope scope, BuildTargetChunk chunk) throws ProjectBuildException {
|
||||
if (isAffected(scope, chunk)) {
|
||||
buildChunk(context, chunk);
|
||||
buildTargetsChunk(context, chunk);
|
||||
}
|
||||
else {
|
||||
final float fraction = updateFractionBuilderFinished(chunk.getModules().size());
|
||||
final float fraction = updateFractionBuilderFinished(chunk.getTargets().size());
|
||||
context.setDone(fraction);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAffected(CompileScope scope, ModuleChunk chunk) {
|
||||
for (ModuleBuildTarget target : chunk.getTargets()) {
|
||||
private static boolean isAffected(CompileScope scope, BuildTargetChunk chunk) {
|
||||
for (BuildTarget<?> target : chunk.getTargets()) {
|
||||
if (scope.isAffected(target)) {
|
||||
return true;
|
||||
}
|
||||
@@ -517,7 +509,47 @@ public class IncProjectBuilder {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void buildChunk(CompileContext context, final ModuleChunk chunk) throws ProjectBuildException {
|
||||
private void buildTargetsChunk(CompileContext context, final BuildTargetChunk chunk) throws ProjectBuildException {
|
||||
Set<BuildTarget<?>> targets = chunk.getTargets();
|
||||
if (targets.size() > 1) {
|
||||
Set<ModuleBuildTarget> moduleTargets = new HashSet<ModuleBuildTarget>();
|
||||
for (BuildTarget<?> target : targets) {
|
||||
if (target instanceof ModuleBuildTarget) {
|
||||
moduleTargets.add((ModuleBuildTarget)target);
|
||||
}
|
||||
else {
|
||||
context.processMessage(new CompilerMessage(BUILD_NAME, BuildMessage.Kind.ERROR, "Cannot build " + target.getPresentableName() + " because it is included into a circular dependency"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
buildModuleChunk(context, new ModuleChunk(moduleTargets));
|
||||
}
|
||||
BuildTarget<?> target = targets.iterator().next();
|
||||
if (target instanceof ModuleBuildTarget) {
|
||||
ModuleBuildTarget moduleBuildTarget = (ModuleBuildTarget)target;
|
||||
buildModuleChunk(context, new ModuleChunk(Collections.singleton(moduleBuildTarget)));
|
||||
}
|
||||
else {
|
||||
buildTarget(target, context);
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildTarget(BuildTarget<?> target, CompileContext context) throws ProjectBuildException {
|
||||
for (TargetBuilder<?> builder : BuilderRegistry.getInstance().getTargetBuilders()) {
|
||||
buildTarget(target, context, builder);
|
||||
}
|
||||
}
|
||||
|
||||
private static <B extends BuildTarget<?>> void buildTarget(B target, CompileContext context, TargetBuilder<?> builder) throws ProjectBuildException {
|
||||
if (builder.getTargetTypes().contains(target.getTargetType())) {
|
||||
//noinspection unchecked
|
||||
((TargetBuilder<B>)builder).build(target, context);
|
||||
context.checkCanceled();
|
||||
}
|
||||
}
|
||||
|
||||
private void buildModuleChunk(CompileContext context, final ModuleChunk chunk) throws ProjectBuildException {
|
||||
|
||||
boolean doneSomething = false;
|
||||
try {
|
||||
Utils.ERRORS_DETECTED_KEY.set(context, Boolean.FALSE);
|
||||
@@ -541,7 +573,7 @@ public class IncProjectBuilder {
|
||||
try {
|
||||
for (BuilderCategory category : BuilderCategory.values()) {
|
||||
for (ModuleLevelBuilder builder : myBuilderRegistry.getBuilders(category)) {
|
||||
builder.cleanupResources(context, chunk);
|
||||
builder.cleanupChunkResources(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -748,9 +780,9 @@ public class IncProjectBuilder {
|
||||
if (buildResult == ModuleLevelBuilder.ExitCode.ADDITIONAL_PASS_REQUIRED) {
|
||||
if (!nextPassRequired) {
|
||||
// recalculate basis
|
||||
myModulesProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
myTargetsProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
stageCount += myTotalModuleLevelBuilderCount;
|
||||
myModulesProcessed += (buildersPassed * modulesInChunk) / stageCount;
|
||||
myTargetsProcessed += (buildersPassed * modulesInChunk) / stageCount;
|
||||
}
|
||||
nextPassRequired = true;
|
||||
}
|
||||
@@ -763,7 +795,7 @@ public class IncProjectBuilder {
|
||||
// forcibly mark all files in the chunk dirty
|
||||
FSOperations.markDirty(context, chunk);
|
||||
// reverting to the beginning
|
||||
myModulesProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
myTargetsProcessed -= (buildersPassed * modulesInChunk) / stageCount;
|
||||
stageCount = myTotalModuleLevelBuilderCount;
|
||||
buildersPassed = 0;
|
||||
nextPassRequired = true;
|
||||
@@ -790,13 +822,6 @@ public class IncProjectBuilder {
|
||||
return doneSomething;
|
||||
}
|
||||
|
||||
private void runProjectLevelBuilders(CompileContext context) throws ProjectBuildException {
|
||||
for (ProjectLevelBuilder builder : myBuilderRegistry.getProjectLevelBuilders()) {
|
||||
builder.build(context);
|
||||
context.checkCanceled();
|
||||
}
|
||||
}
|
||||
|
||||
private static void syncOutputFiles(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
final BuildDataManager dataManager = context.getProjectDescriptor().dataManager;
|
||||
try {
|
||||
@@ -854,19 +879,19 @@ public class IncProjectBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ChunkGroup> buildChunkGroups(ProjectChunks chunks) {
|
||||
final List<ModuleChunk> allChunks = chunks.getChunkList();
|
||||
private static List<ChunkGroup> buildChunkGroups(BuildTargetIndex index) {
|
||||
final List<BuildTargetChunk> allChunks = index.getSortedTargetChunks();
|
||||
|
||||
// building aux dependencies map
|
||||
final Map<ModuleBuildTarget, Set<ModuleBuildTarget>> depsMap = new HashMap<ModuleBuildTarget, Set<ModuleBuildTarget>>();
|
||||
for (ModuleBuildTarget target : chunks.getAllTargets()) {
|
||||
depsMap.put(target, chunks.getDependenciesRecursively(target));
|
||||
final Map<BuildTarget<?>, Set<BuildTarget<?>>> depsMap = new HashMap<BuildTarget<?>, Set<BuildTarget<?>>>();
|
||||
for (BuildTarget target : index.getAllTargets()) {
|
||||
depsMap.put(target, index.getDependenciesRecursively(target));
|
||||
}
|
||||
|
||||
final List<ChunkGroup> groups = new ArrayList<ChunkGroup>();
|
||||
ChunkGroup currentGroup = new ChunkGroup();
|
||||
groups.add(currentGroup);
|
||||
for (ModuleChunk chunk : allChunks) {
|
||||
for (BuildTargetChunk chunk : allChunks) {
|
||||
if (dependsOnGroup(chunk, currentGroup, depsMap)) {
|
||||
currentGroup = new ChunkGroup();
|
||||
groups.add(currentGroup);
|
||||
@@ -877,10 +902,10 @@ public class IncProjectBuilder {
|
||||
}
|
||||
|
||||
|
||||
public static boolean dependsOnGroup(ModuleChunk chunk, ChunkGroup group, Map<ModuleBuildTarget, Set<ModuleBuildTarget>> depsMap) {
|
||||
for (ModuleChunk groupChunk : group.getChunks()) {
|
||||
final Set<ModuleBuildTarget> groupChunkTargets = groupChunk.getTargets();
|
||||
for (ModuleBuildTarget target : chunk.getTargets()) {
|
||||
private static boolean dependsOnGroup(BuildTargetChunk chunk, ChunkGroup group, Map<BuildTarget<?>, Set<BuildTarget<?>>> depsMap) {
|
||||
for (BuildTargetChunk groupChunk : group.getChunks()) {
|
||||
final Set<BuildTarget<?>> groupChunkTargets = groupChunk.getTargets();
|
||||
for (BuildTarget<?> target : chunk.getTargets()) {
|
||||
if (ContainerUtil.intersects(depsMap.get(target), groupChunkTargets)) {
|
||||
return true;
|
||||
}
|
||||
@@ -999,13 +1024,13 @@ public class IncProjectBuilder {
|
||||
}
|
||||
|
||||
private static class ChunkGroup {
|
||||
private final List<ModuleChunk> myChunks = new ArrayList<ModuleChunk>();
|
||||
private final List<BuildTargetChunk> myChunks = new ArrayList<BuildTargetChunk>();
|
||||
|
||||
public void addChunk(ModuleChunk chunk) {
|
||||
public void addChunk(BuildTargetChunk chunk) {
|
||||
myChunks.add(chunk);
|
||||
}
|
||||
|
||||
public List<ModuleChunk> getChunks() {
|
||||
public List<BuildTargetChunk> getChunks() {
|
||||
return myChunks;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,12 +55,12 @@ public class ModuleBuildTarget extends BuildTarget<RootDescriptor> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ModuleBuildTarget> computeDependencies() {
|
||||
public Collection<BuildTarget<?>> computeDependencies() {
|
||||
JpsJavaDependenciesEnumerator enumerator = JpsJavaExtensionService.dependencies(myModule).compileOnly();
|
||||
if (!isTests()) {
|
||||
enumerator.productionOnly();
|
||||
}
|
||||
final List<ModuleBuildTarget> dependencies = new ArrayList<ModuleBuildTarget>();
|
||||
final List<BuildTarget<?>> dependencies = new ArrayList<BuildTarget<?>>();
|
||||
enumerator.processModules(new Consumer<JpsModule>() {
|
||||
@Override
|
||||
public void consume(JpsModule module) {
|
||||
@@ -93,6 +93,12 @@ public class ModuleBuildTarget extends BuildTarget<RootDescriptor> {
|
||||
return ContainerUtil.getFirstItem(descriptors);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Module '" + myModuleName + "' " + (myTargetType.isTests() ? "production" : "tests");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
||||
@@ -31,6 +31,6 @@ public abstract class ModuleLevelBuilder extends Builder {
|
||||
return myCategory;
|
||||
}
|
||||
|
||||
public void cleanupResources(CompileContext context, ModuleChunk chunk) {
|
||||
public void cleanupChunkResources(CompileContext context) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.jetbrains.jps.incremental;
|
||||
|
||||
/**
|
||||
* Use {@link BuilderService} to register implementations of this class
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class ProjectLevelBuilder extends Builder {
|
||||
protected ProjectLevelBuilder() {
|
||||
}
|
||||
|
||||
public abstract void build(CompileContext context) throws ProjectBuildException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.jetbrains.jps.incremental;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.BuildTargetType;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Use {@link BuilderService} to register implementations of this class
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class TargetBuilder<B extends BuildTarget<?>> extends Builder {
|
||||
private final Collection<? extends BuildTargetType<? extends B>> myTargetTypes;
|
||||
|
||||
protected TargetBuilder(Collection<? extends BuildTargetType<? extends B>> targetTypes) {
|
||||
myTargetTypes = targetTypes;
|
||||
}
|
||||
|
||||
public Collection<? extends BuildTargetType<? extends B>> getTargetTypes() {
|
||||
return myTargetTypes;
|
||||
}
|
||||
|
||||
public abstract void build(@NotNull B target, @NotNull CompileContext context) throws ProjectBuildException;
|
||||
|
||||
}
|
||||
+48
-7
@@ -1,21 +1,29 @@
|
||||
package org.jetbrains.jps.incremental.artifacts;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.ProjectPaths;
|
||||
import org.jetbrains.jps.builders.BuildRootDescriptor;
|
||||
import org.jetbrains.jps.builders.BuildRootIndex;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget;
|
||||
import org.jetbrains.jps.incremental.ModuleRootsIndex;
|
||||
import org.jetbrains.jps.incremental.artifacts.builders.LayoutElementBuildersRegistry;
|
||||
import org.jetbrains.jps.incremental.artifacts.impl.JpsArtifactUtil;
|
||||
import org.jetbrains.jps.incremental.artifacts.instructions.*;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsArtifactOutputPackagingElement;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
|
||||
import org.jetbrains.jps.model.java.JpsProductionModuleOutputPackagingElement;
|
||||
import org.jetbrains.jps.model.java.JpsTestModuleOutputPackagingElement;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -39,8 +47,36 @@ public class ArtifactBuildTarget extends BuildTarget<ArtifactRootDescriptor> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends BuildTarget<?>> computeDependencies() {
|
||||
return Collections.emptyList();
|
||||
public Collection<BuildTarget<?>> computeDependencies() {
|
||||
final LinkedHashSet<BuildTarget<?>> dependencies = new LinkedHashSet<BuildTarget<?>>();
|
||||
JpsArtifactUtil.processPackagingElements(myArtifact.getRootElement(), new Processor<JpsPackagingElement>() {
|
||||
@Override
|
||||
public boolean process(JpsPackagingElement element) {
|
||||
if (element instanceof JpsArtifactOutputPackagingElement) {
|
||||
JpsArtifact included = ((JpsArtifactOutputPackagingElement)element).getArtifactReference().resolve();
|
||||
if (included != null && !included.equals(myArtifact)) {
|
||||
if (!StringUtil.isEmpty(included.getOutputPath())) {
|
||||
dependencies.add(new ArtifactBuildTarget(included));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (element instanceof JpsProductionModuleOutputPackagingElement) {
|
||||
JpsModule module = ((JpsProductionModuleOutputPackagingElement)element).getModuleReference().resolve();
|
||||
if (module != null) {
|
||||
dependencies.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
|
||||
}
|
||||
}
|
||||
else if (element instanceof JpsTestModuleOutputPackagingElement) {
|
||||
JpsModule module = ((JpsTestModuleOutputPackagingElement)element).getModuleReference().resolve();
|
||||
if (module != null) {
|
||||
dependencies.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.TEST));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,11 +104,10 @@ public class ArtifactBuildTarget extends BuildTarget<ArtifactRootDescriptor> {
|
||||
@Override
|
||||
public List<ArtifactRootDescriptor> computeRootDescriptors(JpsModel model, ModuleRootsIndex index) {
|
||||
ArtifactInstructionsBuilderImpl builder = new ArtifactInstructionsBuilderImpl(index, this);
|
||||
final JpsCompositePackagingElement rootElement = myArtifact.getRootElement();
|
||||
ArtifactInstructionsBuilderContext context = new ArtifactInstructionsBuilderContextImpl(model, new ProjectPaths(model.getProject()));
|
||||
String outputPath = StringUtil.notNullize(myArtifact.getOutputPath());//todo[nik] implement simplified instructions generation which only collect roots
|
||||
String outputPath = StringUtil.notNullize(myArtifact.getOutputPath());
|
||||
final CopyToDirectoryInstructionCreator instructionCreator = new CopyToDirectoryInstructionCreator(builder, outputPath);
|
||||
LayoutElementBuildersRegistry.getInstance().generateInstructions(rootElement, instructionCreator, context);
|
||||
LayoutElementBuildersRegistry.getInstance().generateInstructions(myArtifact, instructionCreator, context);
|
||||
return builder.getDescriptors();
|
||||
}
|
||||
|
||||
@@ -81,4 +116,10 @@ public class ArtifactBuildTarget extends BuildTarget<ArtifactRootDescriptor> {
|
||||
BuildRootIndex rootIndex) {
|
||||
return rootIndex.getTargetRoots(this, null).get(Integer.valueOf(rootId));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Artifact '" + myArtifact.getName() + "'";
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -1,12 +1,12 @@
|
||||
package org.jetbrains.jps.incremental.artifacts;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.builders.BuildTargetLoader;
|
||||
import org.jetbrains.jps.builders.BuildTargetType;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifactService;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -22,11 +22,13 @@ public class ArtifactBuildTargetType extends BuildTargetType<ArtifactBuildTarget
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<ArtifactBuildTarget> computeAllTargets(@NotNull JpsModel model) {
|
||||
public List<ArtifactBuildTarget> computeAllTargets(@NotNull JpsModel model) {
|
||||
Collection<JpsArtifact> artifacts = JpsBuilderArtifactService.getInstance().getArtifacts(model, true);
|
||||
List<ArtifactBuildTarget> targets = new ArrayList<ArtifactBuildTarget>(artifacts.size());
|
||||
for (JpsArtifact artifact : artifacts) {
|
||||
targets.add(new ArtifactBuildTarget(artifact));
|
||||
if (!StringUtil.isEmpty(artifact.getOutputPath())) {
|
||||
targets.add(new ArtifactBuildTarget(artifact));
|
||||
}
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
@@ -42,7 +44,7 @@ public class ArtifactBuildTargetType extends BuildTargetType<ArtifactBuildTarget
|
||||
|
||||
public Loader(JpsModel model) {
|
||||
myArtifacts = new HashMap<String, JpsArtifact>();
|
||||
for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(model.getProject())) {
|
||||
for (JpsArtifact artifact : JpsBuilderArtifactService.getInstance().getArtifacts(model, true)) {
|
||||
myArtifacts.put(artifact.getName(), artifact);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ package org.jetbrains.jps.incremental.artifacts;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.BuildTargetType;
|
||||
import org.jetbrains.jps.incremental.BuilderService;
|
||||
import org.jetbrains.jps.incremental.ProjectLevelBuilder;
|
||||
import org.jetbrains.jps.incremental.TargetBuilder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -19,7 +19,7 @@ public class ArtifactBuilderService extends BuilderService {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends ProjectLevelBuilder> createProjectLevelBuilders() {
|
||||
public List<? extends TargetBuilder<?>> createBuilders() {
|
||||
return Collections.singletonList(new IncArtifactBuilder());
|
||||
}
|
||||
}
|
||||
|
||||
+21
-37
@@ -6,6 +6,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.BuildRootDescriptor;
|
||||
import org.jetbrains.jps.builders.BuildRootIndex;
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor;
|
||||
@@ -18,7 +19,6 @@ import org.jetbrains.jps.incremental.messages.BuildMessage;
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage;
|
||||
import org.jetbrains.jps.incremental.messages.ProgressMessage;
|
||||
import org.jetbrains.jps.incremental.storage.SourceToOutputMapping;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
|
||||
import java.io.File;
|
||||
@@ -28,48 +28,31 @@ import java.util.*;
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class IncArtifactBuilder extends ProjectLevelBuilder {
|
||||
public class IncArtifactBuilder extends TargetBuilder<ArtifactBuildTarget> {
|
||||
public static final String BUILDER_NAME = "artifacts";
|
||||
|
||||
public IncArtifactBuilder() {
|
||||
super();
|
||||
super(Collections.singletonList(ArtifactBuildTargetType.INSTANCE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(CompileContext context) throws ProjectBuildException {
|
||||
Set<JpsArtifact> affected = new HashSet<JpsArtifact>();
|
||||
JpsBuilderArtifactService artifactService = JpsBuilderArtifactService.getInstance();
|
||||
JpsModel model = context.getProjectDescriptor().jpsModel;
|
||||
for (JpsArtifact artifact : artifactService.getArtifacts(model, false)) {
|
||||
if (context.getScope().isAffected(new ArtifactBuildTarget(artifact))) {
|
||||
affected.add(artifact);
|
||||
}
|
||||
public void build(@NotNull ArtifactBuildTarget target, @NotNull CompileContext context) throws ProjectBuildException {
|
||||
JpsArtifact artifact = target.getArtifact();
|
||||
if (StringUtil.isEmpty(artifact.getOutputPath())) {
|
||||
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifact.getName() + "' artifact: output path is not specified"));
|
||||
return;
|
||||
}
|
||||
affected.addAll(artifactService.getSyntheticArtifacts(model));
|
||||
final Set<JpsArtifact> toBuild = ArtifactSorter.addIncludedArtifacts(affected);
|
||||
|
||||
final ArtifactSorter sorter = new ArtifactSorter(model);
|
||||
final Map<JpsArtifact, JpsArtifact> selfIncludingNameMap = sorter.getArtifactToSelfIncludingNameMap();
|
||||
for (JpsArtifact artifact : sorter.getArtifactsSortedByInclusion()) {
|
||||
context.checkCanceled();
|
||||
if (toBuild.contains(artifact)) {
|
||||
final JpsArtifact selfIncluding = selfIncludingNameMap.get(artifact);
|
||||
if (selfIncluding != null) {
|
||||
String name = selfIncluding.equals(artifact) ? "it" : "'" + selfIncluding.getName() + "' artifact";
|
||||
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifact.getName() + "' artifact: " + name + " includes itself in the output layout"));
|
||||
break;
|
||||
}
|
||||
if (StringUtil.isEmpty(artifact.getOutputPath())) {
|
||||
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifact.getName() + "' artifact: output path is not specified"));
|
||||
break;
|
||||
}
|
||||
buildArtifact(new ArtifactBuildTarget(artifact), context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildArtifact(ArtifactBuildTarget target, final CompileContext context) throws ProjectBuildException {
|
||||
final ProjectDescriptor pd = context.getProjectDescriptor();
|
||||
final ArtifactSorter sorter = new ArtifactSorter(pd.jpsModel);
|
||||
final Map<JpsArtifact, JpsArtifact> selfIncludingNameMap = sorter.getArtifactToSelfIncludingNameMap();
|
||||
final JpsArtifact selfIncluding = selfIncludingNameMap.get(artifact);
|
||||
if (selfIncluding != null) {
|
||||
String name = selfIncluding.equals(artifact) ? "it" : "'" + selfIncluding.getName() + "' artifact";
|
||||
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, "Cannot build '" + artifact.getName() + "' artifact: " + name + " includes itself in the output layout"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
final ArtifactSourceFilesState state = pd.dataManager.getArtifactsBuildData().getOrCreateState(target, pd);
|
||||
state.ensureFsStateInitialized(pd.dataManager, context);
|
||||
@@ -80,7 +63,7 @@ public class IncArtifactBuilder extends ProjectLevelBuilder {
|
||||
return;
|
||||
}
|
||||
|
||||
context.processMessage(new ProgressMessage("Building artifact '" + target.getArtifact().getName() + "'..."));
|
||||
context.processMessage(new ProgressMessage("Building artifact '" + artifact.getName() + "'..."));
|
||||
final SourceToOutputMapping srcOutMapping = pd.dataManager.getSourceToOutputMap(target);
|
||||
final ArtifactOutputToSourceMapping outSrcMapping = state.getOrCreateOutSrcMapping();
|
||||
|
||||
@@ -147,7 +130,8 @@ public class IncArtifactBuilder extends ProjectLevelBuilder {
|
||||
srcOutMapping, outSrcMapping);
|
||||
}
|
||||
else if (outSrcMapping.getState(destination.getOutputFilePath()) == null) {
|
||||
outSrcMapping.update(destination.getOutputFilePath(), Collections.<ArtifactOutputToSourceMapping.SourcePathAndRootIndex>emptyList());
|
||||
outSrcMapping
|
||||
.update(destination.getOutputFilePath(), Collections.<ArtifactOutputToSourceMapping.SourcePathAndRootIndex>emptyList());
|
||||
changedJars.add(((JarDestinationInfo)destination).getJarInfo());
|
||||
}
|
||||
}
|
||||
|
||||
+15
-2
@@ -7,6 +7,7 @@ import com.intellij.util.containers.ClassMap;
|
||||
import org.jetbrains.jps.JpsPathUtil;
|
||||
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactCompilerInstructionCreator;
|
||||
import org.jetbrains.jps.incremental.artifacts.instructions.ArtifactInstructionsBuilderContext;
|
||||
import org.jetbrains.jps.incremental.artifacts.instructions.CopyToDirectoryInstructionCreator;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
import org.jetbrains.jps.model.artifact.elements.*;
|
||||
import org.jetbrains.jps.model.java.JpsProductionModuleOutputPackagingElement;
|
||||
@@ -47,7 +48,12 @@ public class LayoutElementBuildersRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
public void generateInstructions(JpsPackagingElement layoutElement, ArtifactCompilerInstructionCreator instructionCreator,
|
||||
public void generateInstructions(JpsArtifact artifact, CopyToDirectoryInstructionCreator creator, ArtifactInstructionsBuilderContext context) {
|
||||
context.enterArtifact(artifact);
|
||||
generateInstructions(artifact.getRootElement(), creator, context);
|
||||
}
|
||||
|
||||
private void generateInstructions(JpsPackagingElement layoutElement, ArtifactCompilerInstructionCreator instructionCreator,
|
||||
ArtifactInstructionsBuilderContext builderContext) {
|
||||
final LayoutElementBuilderService builder = myBuilders.get(layoutElement.getClass());
|
||||
if (builder != null) {
|
||||
@@ -230,7 +236,14 @@ public class LayoutElementBuildersRegistry {
|
||||
|
||||
final String outputPath = artifact.getOutputPath();
|
||||
if (StringUtil.isEmpty(outputPath)) {
|
||||
generateSubstitutionInstructions(element, instructionCreator, builderContext);
|
||||
try {
|
||||
if (builderContext.enterArtifact(artifact)) {
|
||||
generateSubstitutionInstructions(element, instructionCreator, builderContext);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
builderContext.leaveArtifact(artifact);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+16
-3
@@ -1,28 +1,41 @@
|
||||
package org.jetbrains.jps.incremental.artifacts.impl;
|
||||
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsComplexPackagingElement;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsCompositePackagingElement;
|
||||
import org.jetbrains.jps.model.artifact.elements.JpsPackagingElement;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class JpsArtifactUtil {
|
||||
public static boolean processPackagingElements(@NotNull JpsPackagingElement element, @NotNull Processor<JpsPackagingElement> processor) {
|
||||
public static boolean processPackagingElements(@NotNull JpsPackagingElement element,
|
||||
@NotNull Processor<JpsPackagingElement> processor) {
|
||||
return processPackagingElements(element, processor, new HashSet<JpsPackagingElement>());
|
||||
}
|
||||
|
||||
private static boolean processPackagingElements(@NotNull JpsPackagingElement element,
|
||||
@NotNull Processor<JpsPackagingElement> processor,
|
||||
final Set<JpsPackagingElement> processed) {
|
||||
if (!processed.add(element)) {
|
||||
return false;
|
||||
}
|
||||
if (!processor.process(element)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (element instanceof JpsCompositePackagingElement) {
|
||||
for (JpsPackagingElement child : ((JpsCompositePackagingElement)element).getChildren()) {
|
||||
processPackagingElements(child, processor);
|
||||
processPackagingElements(child, processor, processed);
|
||||
}
|
||||
}
|
||||
else if (element instanceof JpsComplexPackagingElement) {
|
||||
for (JpsPackagingElement child : ((JpsComplexPackagingElement)element).getSubstitution()) {
|
||||
processPackagingElements(child, processor);
|
||||
processPackagingElements(child, processor, processed);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
+5
@@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.ProjectPaths;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.JpsProject;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -16,4 +17,8 @@ public interface ArtifactInstructionsBuilderContext {
|
||||
JpsProject getJpsProject();
|
||||
|
||||
JpsModel getJpsModel();
|
||||
|
||||
boolean enterArtifact(JpsArtifact artifact);
|
||||
|
||||
void leaveArtifact(JpsArtifact artifact);
|
||||
}
|
||||
|
||||
+16
@@ -4,6 +4,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.ProjectPaths;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.JpsProject;
|
||||
import org.jetbrains.jps.model.artifact.JpsArtifact;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -11,12 +15,14 @@ import org.jetbrains.jps.model.JpsProject;
|
||||
public class ArtifactInstructionsBuilderContextImpl implements ArtifactInstructionsBuilderContext {
|
||||
private final JpsProject myJpsProject;
|
||||
private final ProjectPaths myProjectPaths;
|
||||
private final Set<JpsArtifact> myParentArtifacts;
|
||||
private JpsModel myModel;
|
||||
|
||||
public ArtifactInstructionsBuilderContextImpl(JpsModel jpsModel, ProjectPaths projectPaths) {
|
||||
myJpsProject = jpsModel.getProject();
|
||||
myModel = jpsModel;
|
||||
myProjectPaths = projectPaths;
|
||||
myParentArtifacts = new HashSet<JpsArtifact>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -29,6 +35,16 @@ public class ArtifactInstructionsBuilderContextImpl implements ArtifactInstructi
|
||||
return myModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enterArtifact(JpsArtifact artifact) {
|
||||
return myParentArtifacts.add(artifact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leaveArtifact(JpsArtifact artifact) {
|
||||
myParentArtifacts.remove(artifact);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ProjectPaths getProjectPaths() {
|
||||
|
||||
@@ -339,7 +339,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
final int filesCount = files.size();
|
||||
boolean compiledOk = true;
|
||||
if (filesCount > 0) {
|
||||
LOG.info("Compiling " + filesCount + " java files; module: " + chunkName + (chunk.isTests() ? " (tests)" : ""));
|
||||
LOG.info("Compiling " + filesCount + " java files; module: " + chunkName + (chunk.containsTests() ? " (tests)" : ""));
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(" classpath for " + chunkName + ":");
|
||||
for (File file : classpath) {
|
||||
@@ -365,7 +365,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
context.processMessage(new ProgressMessage("Instrumenting forms [" + chunkName + "]"));
|
||||
instrumentForms(context, chunk, chunkSourcePath, finder, forms, outputSink);
|
||||
JpsUiDesignerConfiguration configuration = JpsUiDesignerExtensionService.getInstance().getUiDesignerConfiguration(pd.jpsProject);
|
||||
if (configuration != null && configuration.isCopyFormsRuntimeToOutput() && !chunk.isTests()) {
|
||||
if (configuration != null && configuration.isCopyFormsRuntimeToOutput() && !chunk.containsTests()) {
|
||||
for (JpsModule module : chunk.getModules()) {
|
||||
final File outputDir = paths.getModuleOutputDir(module, false);
|
||||
if (outputDir != null) {
|
||||
@@ -760,7 +760,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
|
||||
final File srcOutput = context.getProjectPaths()
|
||||
.getAnnotationProcessorGeneratedSourcesOutputDir(chunk.getModules().iterator().next(), chunk.isTests(),
|
||||
.getAnnotationProcessorGeneratedSourcesOutputDir(chunk.getModules().iterator().next(), chunk.containsTests(),
|
||||
profile.getGeneratedSourcesDirectoryName());
|
||||
if (srcOutput != null) {
|
||||
srcOutput.mkdirs();
|
||||
@@ -874,7 +874,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanupResources(CompileContext context, ModuleChunk chunk) {
|
||||
public void cleanupChunkResources(CompileContext context) {
|
||||
JavaBuilderUtil.cleanupChunkResources(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@ package org.jetbrains.jps.incremental.storage;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.ModuleChunk;
|
||||
import org.jetbrains.jps.builders.BuildTarget;
|
||||
import org.jetbrains.jps.builders.impl.BuildTargetChunk;
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget;
|
||||
import org.jetbrains.jps.incremental.artifacts.ArtifactsBuildData;
|
||||
|
||||
import java.io.*;
|
||||
@@ -170,10 +169,10 @@ public class BuildDataManager implements StorageOwner {
|
||||
}
|
||||
}
|
||||
|
||||
public void closeSourceToOutputStorages(Collection<ModuleChunk> chunks) throws IOException {
|
||||
public void closeSourceToOutputStorages(Collection<BuildTargetChunk> chunks) throws IOException {
|
||||
synchronized (mySourceToOutputLock) {
|
||||
for (ModuleChunk chunk : chunks) {
|
||||
for (ModuleBuildTarget target : chunk.getTargets()) {
|
||||
for (BuildTargetChunk chunk : chunks) {
|
||||
for (BuildTarget<?> target : chunk.getTargets()) {
|
||||
final SourceToOutputMapping mapping = mySourceToOutputs.remove(target);
|
||||
if (mapping != null) {
|
||||
mapping.close();
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ModuleClasspathTest extends JpsRebuildTestCase {
|
||||
|
||||
private ModuleChunk createChunk(String moduleName) {
|
||||
def module = myJpsProject.modules.find {it.name == moduleName}
|
||||
return new ModuleChunk([new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION)] as Set, false)
|
||||
return new ModuleChunk([new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION)] as Set)
|
||||
}
|
||||
|
||||
private def assertClasspath(List<String> expected, List<String> classpath) {
|
||||
|
||||
+9
@@ -238,6 +238,15 @@ public class ArtifactBuilderTest extends ArtifactBuilderTestCase {
|
||||
assertBuildFailed(a);
|
||||
}
|
||||
|
||||
public void testArtifactContainingSelfIncludingArtifactWithoutOutput() {
|
||||
final JpsArtifact a = addArtifact("a", root());
|
||||
LayoutElementTestUtil.addArtifactToLayout(a, a);
|
||||
final JpsArtifact b = addArtifact("b", root().artifact(a));
|
||||
a.setOutputPath(null);
|
||||
|
||||
assertBuildFailed(b);
|
||||
}
|
||||
|
||||
//IDEA-73893
|
||||
public void testManifestFileIsFirstEntry() throws IOException {
|
||||
final String firstFile = createFile("src/A.txt");
|
||||
|
||||
@@ -887,7 +887,7 @@ public class StringUtil extends StringUtilRt {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String notNullize(final String s) {
|
||||
public static String notNullize(final @Nullable String s) {
|
||||
return notNullize(s, "");
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
<orderEntry type="module" module-name="android-common" />
|
||||
<orderEntry type="module" module-name="android-rt" />
|
||||
<orderEntry type="module" module-name="java-indexing-api" />
|
||||
<orderEntry type="module" module-name="jps-builders" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ public class AndroidCommonUtils {
|
||||
@NonNls public static final String ANDROID_MANIFEST_MERGER_PROPERTY = "manifestmerger.enabled";
|
||||
@NonNls public static final String PROGUARD_CFG_OUTPUT_FILE_NAME = "proguard.txt";
|
||||
|
||||
@NonNls public static final String PROJECT_BUILD_TARGET_TYPE_ID = "android-project";
|
||||
|
||||
private AndroidCommonUtils() {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.jetbrains.jps.android;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.android.builder.AndroidProjectBuildTarget;
|
||||
import org.jetbrains.jps.builders.BuildTargetType;
|
||||
import org.jetbrains.jps.incremental.BuilderService;
|
||||
import org.jetbrains.jps.incremental.ModuleLevelBuilder;
|
||||
import org.jetbrains.jps.incremental.ProjectLevelBuilder;
|
||||
import org.jetbrains.jps.incremental.TargetBuilder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -12,6 +14,11 @@ import java.util.List;
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class AndroidBuilderService extends BuilderService {
|
||||
@Override
|
||||
public List<? extends BuildTargetType<?>> getTargetTypes() {
|
||||
return Arrays.asList(AndroidProjectBuildTarget.TargetType.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends ModuleLevelBuilder> createModuleLevelBuilders() {
|
||||
@@ -21,7 +28,7 @@ public class AndroidBuilderService extends BuilderService {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends ProjectLevelBuilder> createProjectLevelBuilders() {
|
||||
public List<? extends TargetBuilder<?>> createBuilders() {
|
||||
return Arrays.asList(new AndroidDexBuilder(),
|
||||
new AndroidPackagingBuilder());
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.android.util.AndroidCompilerMessageKind;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.ProjectPaths;
|
||||
import org.jetbrains.jps.android.builder.AndroidProjectBuildTarget;
|
||||
import org.jetbrains.jps.android.model.JpsAndroidModuleExtension;
|
||||
import org.jetbrains.jps.android.model.JpsAndroidSdkProperties;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
@@ -52,7 +53,7 @@ import java.util.*;
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class AndroidDexBuilder extends ProjectLevelBuilder {
|
||||
public class AndroidDexBuilder extends TargetBuilder<AndroidProjectBuildTarget> {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.android.AndroidDexBuilder");
|
||||
|
||||
@NonNls private static final String BUILDER_NAME = "android-dex";
|
||||
@@ -60,9 +61,13 @@ public class AndroidDexBuilder extends ProjectLevelBuilder {
|
||||
private static final Key<BuildListener> BUILD_LISTENER_KEY = Key.create("BUILD_LISTENER_KEY");
|
||||
public static final Key<Set<String>> DIRTY_OUTPUT_DIRS = Key.create("DIRTY_OUTPUT_DIRS");
|
||||
|
||||
public AndroidDexBuilder() {
|
||||
super(Collections.singletonList(AndroidProjectBuildTarget.TargetType.INSTANCE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(CompileContext context) throws ProjectBuildException {
|
||||
if (!AndroidJpsUtil.containsAndroidFacet(context.getProjectDescriptor().jpsProject) || AndroidJpsUtil.isLightBuild(context)) {
|
||||
public void build(@NotNull AndroidProjectBuildTarget target, @NotNull CompileContext context) throws ProjectBuildException {
|
||||
if (target.getKind() != AndroidProjectBuildTarget.AndroidBuilderKind.DEX && AndroidJpsUtil.isLightBuild(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ import java.util.regex.Matcher;
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
class AndroidJpsUtil {
|
||||
public class AndroidJpsUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.android.AndroidJpsUtil");
|
||||
|
||||
@NonNls public static final String ANDROID_STORAGE_DIR = "android";
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ public class AndroidLibraryPackagingBuilder extends ModuleLevelBuilder {
|
||||
|
||||
@Override
|
||||
public ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
if (chunk.isTests() || !AndroidJpsUtil.containsAndroidFacet(chunk) || AndroidJpsUtil.isLightBuild(context)) {
|
||||
if (chunk.containsTests() || !AndroidJpsUtil.containsAndroidFacet(chunk) || AndroidJpsUtil.isLightBuild(context)) {
|
||||
return ExitCode.NOTHING_DONE;
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -16,6 +16,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.JpsPathUtil;
|
||||
import org.jetbrains.jps.ProjectPaths;
|
||||
import org.jetbrains.jps.android.builder.AndroidProjectBuildTarget;
|
||||
import org.jetbrains.jps.android.model.JpsAndroidModuleExtension;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.jps.incremental.*;
|
||||
@@ -36,11 +37,15 @@ import java.util.*;
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class AndroidPackagingBuilder extends ProjectLevelBuilder {
|
||||
public class AndroidPackagingBuilder extends TargetBuilder<AndroidProjectBuildTarget> {
|
||||
@NonNls private static final String BUILDER_NAME = "android-packager";
|
||||
@NonNls private static final String RELEASE_SUFFIX = ".release";
|
||||
@NonNls private static final String UNSIGNED_SUFFIX = ".unsigned";
|
||||
|
||||
public AndroidPackagingBuilder() {
|
||||
super(Collections.singletonList(AndroidProjectBuildTarget.TargetType.INSTANCE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return BUILDER_NAME;
|
||||
@@ -52,8 +57,8 @@ public class AndroidPackagingBuilder extends ProjectLevelBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(CompileContext context) throws ProjectBuildException {
|
||||
if (!AndroidJpsUtil.containsAndroidFacet(context.getProjectDescriptor().jpsProject) || AndroidJpsUtil.isLightBuild(context)) {
|
||||
public void build(@NotNull AndroidProjectBuildTarget target, @NotNull CompileContext context) throws ProjectBuildException {
|
||||
if (target.getKind() != AndroidProjectBuildTarget.AndroidBuilderKind.PACKAGING || AndroidJpsUtil.isLightBuild(context)) {
|
||||
return;
|
||||
}
|
||||
final Collection<JpsModule> modules = context.getProjectDescriptor().jpsProject.getModules();
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
|
||||
|
||||
@Override
|
||||
public ModuleLevelBuilder.ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
|
||||
if (chunk.isTests() || !AndroidJpsUtil.containsAndroidFacet(chunk)) {
|
||||
if (chunk.containsTests() || !AndroidJpsUtil.containsAndroidFacet(chunk)) {
|
||||
return ExitCode.NOTHING_DONE;
|
||||
}
|
||||
|
||||
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.jetbrains.jps.android.builder;
|
||||
|
||||
import org.jetbrains.android.util.AndroidCommonUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.android.AndroidJpsUtil;
|
||||
import org.jetbrains.jps.builders.*;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget;
|
||||
import org.jetbrains.jps.incremental.ModuleRootsIndex;
|
||||
import org.jetbrains.jps.model.JpsModel;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class AndroidProjectBuildTarget extends BuildTarget<BuildRootDescriptor> {
|
||||
public enum AndroidBuilderKind {DEX, PACKAGING}
|
||||
private final AndroidBuilderKind myKind;
|
||||
private final JpsModel myModel;
|
||||
|
||||
public AndroidProjectBuildTarget(@NotNull AndroidBuilderKind kind, JpsModel model) {
|
||||
super(TargetType.INSTANCE);
|
||||
myKind = kind;
|
||||
myModel = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return myKind.name();
|
||||
}
|
||||
|
||||
public AndroidBuilderKind getKind() {
|
||||
return myKind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<BuildTarget<?>> computeDependencies() {
|
||||
List<BuildTarget<?>> result = new ArrayList<BuildTarget<?>>();
|
||||
for (JpsModule module : myModel.getProject().getModules()) {
|
||||
if (AndroidJpsUtil.getExtension(module) != null) {
|
||||
result.add(new ModuleBuildTarget(module, JavaModuleBuildTargetType.PRODUCTION));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<BuildRootDescriptor> computeRootDescriptors(JpsModel model, ModuleRootsIndex index) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BuildRootDescriptor findRootDescriptor(String rootId, BuildRootIndex rootIndex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Android " + myKind.name();
|
||||
}
|
||||
|
||||
public static class TargetType extends BuildTargetType<AndroidProjectBuildTarget> {
|
||||
public static final TargetType INSTANCE = new TargetType();
|
||||
|
||||
public TargetType() {
|
||||
super(AndroidCommonUtils.PROJECT_BUILD_TARGET_TYPE_ID);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<AndroidProjectBuildTarget> computeAllTargets(@NotNull JpsModel model) {
|
||||
if (!AndroidJpsUtil.containsAndroidFacet(model.getProject())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(new AndroidProjectBuildTarget(AndroidBuilderKind.DEX, model),
|
||||
new AndroidProjectBuildTarget(AndroidBuilderKind.PACKAGING, model));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public BuildTargetLoader<AndroidProjectBuildTarget> createLoader(@NotNull final JpsModel model) {
|
||||
return new BuildTargetLoader<AndroidProjectBuildTarget>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public AndroidProjectBuildTarget createTarget(@NotNull String targetId) {
|
||||
return new AndroidProjectBuildTarget(AndroidBuilderKind.valueOf(targetId), model);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,6 +325,7 @@
|
||||
|
||||
<compileServer.plugin classpath="jps/android-jps-plugin.jar;android-common.jar;android-rt.jar"/>
|
||||
<compileServer.plugin classpath="sdklib.jar;common.jar;jarutils.jar;androidprefs.jar"/>
|
||||
<compiler.buildTargetScopeProvider implementation="org.jetbrains.android.compiler.AndroidTargetBuildScopeProvider"/>
|
||||
|
||||
<inlineActionHandler implementation="org.jetbrains.android.refactoring.AndroidInlineStyleHandler"/>
|
||||
<inlineActionHandler implementation="org.jetbrains.android.refactoring.AndroidInlineLayoutHandler" order="first"/>
|
||||
|
||||
@@ -603,7 +603,11 @@ public class AndroidCompileUtil {
|
||||
}
|
||||
|
||||
public static boolean isFullBuild(@NotNull CompileContext context) {
|
||||
final RunConfiguration c = CompileStepBeforeRun.getRunConfiguration(context);
|
||||
return isFullBuild(context.getCompileScope());
|
||||
}
|
||||
|
||||
public static boolean isFullBuild(@NotNull CompileScope scope) {
|
||||
final RunConfiguration c = CompileStepBeforeRun.getRunConfiguration(scope);
|
||||
return c == null || !AndroidCommonUtils.isTestConfiguration(c.getType().getId());
|
||||
}
|
||||
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.jetbrains.android.compiler;
|
||||
|
||||
import com.intellij.compiler.impl.BuildTargetScopeProvider;
|
||||
import com.intellij.facet.ProjectFacetManager;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerFilter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.util.AndroidCommonUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class AndroidTargetBuildScopeProvider extends BuildTargetScopeProvider {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TargetTypeBuildScope> getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project) {
|
||||
if (AndroidCompileUtil.isFullBuild(baseScope) && ProjectFacetManager.getInstance(project).hasFacets(AndroidFacet.ID)) {
|
||||
return Collections
|
||||
.singletonList(TargetTypeBuildScope.newBuilder().setTypeId(AndroidCommonUtils.PROJECT_BUILD_TARGET_TYPE_ID).setAllTargets(true).build());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@
|
||||
<orderEntry type="module" module-name="idea-ui" scope="TEST" />
|
||||
<orderEntry type="module" module-name="xml" />
|
||||
<orderEntry type="library" scope="TEST" name="Groovy" level="project" />
|
||||
<orderEntry type="module" module-name="jps-builders" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<junitPatcher implementation="org.jetbrains.idea.devkit.run.JUnitDevKitPatcher"/>
|
||||
<antBuildGen implementation="org.jetbrains.idea.devkit.build.ant.ChunkBuildPluginExtension"/>
|
||||
<compiler.buildParticipantProvider implementation="org.jetbrains.idea.devkit.build.PluginBuildParticipantProvider"/>
|
||||
<compiler.buildTargetScopeProvider implementation="org.jetbrains.idea.devkit.build.PluginModuleBuildScopeProvider"/>
|
||||
|
||||
<dom.fileDescription implementation="org.jetbrains.idea.devkit.dom.impl.PluginXmlDomFileDescription"/>
|
||||
<dom.extender domClass="org.jetbrains.idea.devkit.dom.Extensions"
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package org.jetbrains.idea.devkit.build;
|
||||
|
||||
import com.intellij.compiler.impl.BuildTargetScopeProvider;
|
||||
import com.intellij.openapi.compiler.CompileScope;
|
||||
import com.intellij.openapi.compiler.CompilerFilter;
|
||||
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.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
|
||||
import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTargetType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class PluginModuleBuildScopeProvider extends BuildTargetScopeProvider {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TargetTypeBuildScope> getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project) {
|
||||
List<String> pluginArtifactTargetIds = new ArrayList<String>();
|
||||
for (Module module : baseScope.getAffectedModules()) {
|
||||
if (PluginModuleType.isOfType(module)) {
|
||||
pluginArtifactTargetIds.add(module.getName()+":plugin");
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginArtifactTargetIds.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.singletonList(TargetTypeBuildScope.newBuilder().setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId()).addAllTargetId(pluginArtifactTargetIds).build());
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -167,7 +167,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanupResources(CompileContext context, ModuleChunk chunk) {
|
||||
public void cleanupChunkResources(CompileContext context) {
|
||||
JavaBuilderUtil.cleanupChunkResources(context);
|
||||
STUB_TO_SRC.set(context, null);
|
||||
}
|
||||
@@ -288,7 +288,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
|
||||
// IMPORTANT! must be the first in classpath
|
||||
cp.add(getGroovyRtRoot().getPath());
|
||||
|
||||
for (File file : context.getProjectPaths().getCompilationClasspathFiles(chunk, chunk.isTests(), false, false)) {
|
||||
for (File file : context.getProjectPaths().getCompilationClasspathFiles(chunk, chunk.containsTests(), false, false)) {
|
||||
cp.add(FileUtil.toCanonicalPath(file.getPath()));
|
||||
}
|
||||
return new ArrayList<String>(cp);
|
||||
|
||||
Reference in New Issue
Block a user