diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2013-02-27 09:41:48 -0800 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2013-02-27 09:41:48 -0800 |
commit | 1d526b16d476792ca7ce47616d55833115e8d6ab (patch) | |
tree | 650fb03af01ff04097d1d59939518cc71be029cb /jps | |
parent | 9edc8f6b58f71ec510ba36b838f115718d9a174d (diff) | |
download | idea-1d526b16d476792ca7ce47616d55833115e8d6ab.tar.gz |
Snapshot of commit 329607d9ebcedf2bb0ad81265354366db7dc3f9c
from branch master of git://git.jetbrains.org/idea/community.git
Change-Id: I3b27d82897504da1b66169b67c7771e0f551c973
Diffstat (limited to 'jps')
34 files changed, 325 insertions, 145 deletions
diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java b/jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java index d772b3c6c1b4..67073eb67b94 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/GlobalOptions.java @@ -25,4 +25,5 @@ public interface GlobalOptions { String GENERATE_CLASSPATH_INDEX_OPTION = "generate.classpath.index"; String COMPILE_PARALLEL_OPTION = "compile.parallel"; String COMPILE_PARALLEL_MAX_THREADS_OPTION = "compile.parallel.max.threads"; + String REBUILD_ON_DEPENDENCY_CHANGE_OPTION = "rebuild.on.dependency.change"; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/ModuleBasedBuildTargetType.java b/jps/jps-builders/src/org/jetbrains/jps/builders/ModuleBasedBuildTargetType.java new file mode 100644 index 000000000000..c2903e6cab70 --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/ModuleBasedBuildTargetType.java @@ -0,0 +1,7 @@ +package org.jetbrains.jps.builders; + +public abstract class ModuleBasedBuildTargetType<T extends ModuleBasedTarget<?>> extends BuildTargetType<T>{ + protected ModuleBasedBuildTargetType(String typeId) { + super(typeId); + } +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/ModuleBasedTarget.java b/jps/jps-builders/src/org/jetbrains/jps/builders/ModuleBasedTarget.java index a2d070990466..7d4c4b0de1dd 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/ModuleBasedTarget.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/ModuleBasedTarget.java @@ -25,7 +25,7 @@ import org.jetbrains.jps.model.module.JpsModule; public abstract class ModuleBasedTarget<R extends BuildRootDescriptor> extends BuildTarget<R> { protected final JpsModule myModule; - public ModuleBasedTarget(BuildTargetType<?> targetType, @NotNull JpsModule module) { + public ModuleBasedTarget(ModuleBasedBuildTargetType<?> targetType, @NotNull JpsModule module) { super(targetType); myModule = module; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootIndexImpl.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootIndexImpl.java index b40da51805a0..262f0e433def 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootIndexImpl.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootIndexImpl.java @@ -27,8 +27,8 @@ import org.jetbrains.jps.builders.*; import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor; import org.jetbrains.jps.builders.storage.BuildDataPaths; -import org.jetbrains.jps.incremental.BuilderRegistry; import org.jetbrains.jps.incremental.CompileContext; +import org.jetbrains.jps.incremental.TargetTypeRegistry; import org.jetbrains.jps.indices.IgnoredFileIndex; import org.jetbrains.jps.indices.ModuleExcludeIndex; import org.jetbrains.jps.model.JpsModel; @@ -57,7 +57,7 @@ public class BuildRootIndexImpl implements BuildRootIndex { myRootToDescriptors = new THashMap<File, List<BuildRootDescriptor>>(FileUtil.FILE_HASHING_STRATEGY); myFileFilters = new ConcurrentHashMap<BuildRootDescriptor, FileFilter>(); final Iterable<AdditionalRootsProviderService> rootsProviders = JpsServiceManager.getInstance().getExtensions(AdditionalRootsProviderService.class); - for (BuildTargetType<?> targetType : BuilderRegistry.getInstance().getTargetTypes()) { + for (BuildTargetType<?> targetType : TargetTypeRegistry.getInstance().getTargetTypes()) { for (BuildTarget<?> target : targetIndex.getAllTargets(targetType)) { addRoots(dataPaths, rootsProviders, target, model, index, ignoredFileIndex); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildTargetIndexImpl.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildTargetIndexImpl.java index 245e39df571a..fd180142afb0 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildTargetIndexImpl.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildTargetIndexImpl.java @@ -25,8 +25,8 @@ import gnu.trove.TIntArrayList; import gnu.trove.TIntProcedure; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.builders.*; -import org.jetbrains.jps.incremental.BuilderRegistry; import org.jetbrains.jps.incremental.CompileContext; +import org.jetbrains.jps.incremental.TargetTypeRegistry; import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.module.JpsModule; @@ -46,7 +46,7 @@ public class BuildTargetIndexImpl implements BuildTargetIndex { myTargets = new THashMap<BuildTargetType<?>, List<? extends BuildTarget<?>>>(); myModuleBasedTargets = new THashMap<JpsModule, List<ModuleBasedTarget>>(); List<List<? extends BuildTarget<?>>> targetsByType = new ArrayList<List<? extends BuildTarget<?>>>(); - for (BuildTargetType<?> type : BuilderRegistry.getInstance().getTargetTypes()) { + for (BuildTargetType<?> type : TargetTypeRegistry.getInstance().getTargetTypes()) { List<? extends BuildTarget<?>> targets = type.computeAllTargets(model); myTargets.put(type, targets); targetsByType.add(targets); 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 58b6a4ca4aba..db367a6d56d5 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 @@ -67,9 +67,6 @@ public class JavaBuilderUtil { ModuleChunk chunk, Collection<File> filesToCompile, Collection<File> successfullyCompiled) throws IOException { - if (Utils.errorsDetected(context)) { - return false; - } try { boolean additionalPassRequired = false; @@ -161,6 +158,14 @@ public class JavaBuilderUtil { globalMappings.differentiateOnRebuild(delta); } + if (Utils.errorsDetected(context)) { + // important: perform dependency analysis and mark found dependencies even if there were errors during the first phase of make. + // Integration of changes should happen only if the corresponding phase of make succeeds + // In case of errors this wil ensure that all dependencies marked after the first phase + // will be compiled during the first phase of the next make + return false; + } + context.processMessage(new ProgressMessage("Updating dependency information... [" + chunk.getName() + "]")); globalMappings.integrate(delta); diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaModuleBuildTargetType.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaModuleBuildTargetType.java index 3136780252f4..e92414eaf067 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaModuleBuildTargetType.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaModuleBuildTargetType.java @@ -18,7 +18,7 @@ package org.jetbrains.jps.builders.java; 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.builders.ModuleBasedBuildTargetType; import org.jetbrains.jps.incremental.ModuleBuildTarget; import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.module.JpsModule; @@ -28,7 +28,7 @@ import java.util.*; /** * @author nik */ -public class JavaModuleBuildTargetType extends BuildTargetType<ModuleBuildTarget> { +public class JavaModuleBuildTargetType extends ModuleBasedBuildTargetType<ModuleBuildTarget> { public static final JavaModuleBuildTargetType PRODUCTION = new JavaModuleBuildTargetType("java-production", false); public static final JavaModuleBuildTargetType TEST = new JavaModuleBuildTargetType("java-test", true); public static final List<JavaModuleBuildTargetType> ALL_TYPES = Arrays.asList(PRODUCTION, TEST); diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/ResourcesTargetType.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/ResourcesTargetType.java index 0e2219ccf249..abc982105fab 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/ResourcesTargetType.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/ResourcesTargetType.java @@ -18,7 +18,7 @@ package org.jetbrains.jps.builders.java; 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.builders.ModuleBasedBuildTargetType; import org.jetbrains.jps.incremental.ResourcesTarget; import org.jetbrains.jps.model.JpsModel; import org.jetbrains.jps.model.module.JpsModule; @@ -28,7 +28,7 @@ import java.util.*; /** * @author nik */ -public class ResourcesTargetType extends BuildTargetType<ResourcesTarget> { +public class ResourcesTargetType extends ModuleBasedBuildTargetType<ResourcesTarget> { public static final ResourcesTargetType PRODUCTION = new ResourcesTargetType("resources-production", false); public static final ResourcesTargetType TEST = new ResourcesTargetType("resources-test", true); public static final List<ResourcesTargetType> ALL_TYPES = Arrays.asList(PRODUCTION, TEST); diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java index 56985a2f8c11..0ff34899e1ac 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java @@ -45,7 +45,13 @@ import java.util.UUID; public class BuildMain { public static final Key<String> FORCE_MODEL_LOADING_PARAMETER = Key.create("_force_model_loading"); private static final String LOG_FILE_NAME = "log.xml"; - private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildMain"); + + private static final Logger LOG; + static { + initLoggers(); + LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildMain"); + } + private static NioClientSocketChannelFactory ourChannelFactory; public static void main(String[] args){ @@ -56,8 +62,6 @@ public class BuildMain { final File systemDir = new File(FileUtil.toCanonicalPath(args[3])); Utils.setSystemRoot(systemDir); - initLoggers(); - ourChannelFactory = new NioClientSocketChannelFactory(SharedThreadPool.getInstance(), SharedThreadPool.getInstance(), 1); final ClientBootstrap bootstrap = new ClientBootstrap(ourChannelFactory); bootstrap.setPipelineFactory(new ChannelPipelineFactory() { 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 0fd522e6053b..1c6edbf86772 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java @@ -165,8 +165,9 @@ public class BuildRunner { Set<BuildTarget<?>> targets = new HashSet<BuildTarget<?>>(); Map<BuildTarget<?>, Set<File>> files; + final TargetTypeRegistry typeRegistry = TargetTypeRegistry.getInstance(); for (TargetTypeBuildScope scope : scopes) { - BuildTargetType<?> targetType = BuilderRegistry.getInstance().getTargetType(scope.getTypeId()); + final BuildTargetType<?> targetType = typeRegistry.getTargetType(scope.getTypeId()); if (targetType == null) { LOG.info("Unknown target type: " + scope.getTypeId()); continue; 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 e41a788e44e0..e8e20e1b5d61 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -28,11 +28,11 @@ import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channels; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.api.*; -import org.jetbrains.jps.builders.BuildRootDescriptor; +import org.jetbrains.jps.builders.*; import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; import org.jetbrains.jps.builders.java.dependencyView.Callbacks; import org.jetbrains.jps.incremental.MessageHandler; -import org.jetbrains.jps.incremental.ModuleBuildTarget; +import org.jetbrains.jps.incremental.TargetTypeRegistry; import org.jetbrains.jps.incremental.Utils; import org.jetbrains.jps.incremental.fs.BuildFSState; import org.jetbrains.jps.incremental.fs.FSState; @@ -227,15 +227,33 @@ final class BuildSession implements Runnable, CanceledStatus { } private static boolean scopeContainsModulesOnly(List<TargetTypeBuildScope> scopes) { + TargetTypeRegistry typeRegistry = null; for (TargetTypeBuildScope scope : scopes) { - String typeId = scope.getTypeId(); - if (!typeId.equals(JavaModuleBuildTargetType.PRODUCTION.getTypeId()) && !typeId.equals(JavaModuleBuildTargetType.TEST.getTypeId())) { + final String typeId = scope.getTypeId(); + if (isJavaModuleBuildType(typeId)) { // fast check + continue; + } + if (typeRegistry == null) { + // lazy init + typeRegistry = TargetTypeRegistry.getInstance(); + } + final BuildTargetType<?> targetType = typeRegistry.getTargetType(typeId); + if (targetType != null && !(targetType instanceof ModuleBasedBuildTargetType)) { return false; } } return true; } + private static boolean isJavaModuleBuildType(String typeId) { + for (JavaModuleBuildTargetType moduleBuildTargetType : JavaModuleBuildTargetType.ALL_TYPES) { + if (moduleBuildTargetType.getTypeId().equals(typeId)) { + return true; + } + } + return false; + } + private void saveData(final BuildFSState fsState, File dataStorageRoot) { final boolean wasInterrupted = Thread.interrupted(); try { @@ -301,23 +319,25 @@ final class BuildSession implements Runnable, CanceledStatus { pd.getFSCache().clear(); cacheCleared = true; } - if (Utils.IS_TEST_MODE) { - LOG.info("Applying deleted path from fs event: " + file.getPath()); + if (LOG.isDebugEnabled()) { + LOG.debug("Applying deleted path from fs event: " + file.getPath()); } for (BuildRootDescriptor rootDescriptor : descriptor) { pd.fsState.registerDeleted(rootDescriptor.getTarget(), file, timestamps); } } - else if (Utils.IS_TEST_MODE) { - LOG.info("Skipping deleted path: " + file.getPath()); + else { + if (LOG.isDebugEnabled()) { + LOG.debug("Skipping deleted path: " + file.getPath()); + } } } for (String changed : event.getChangedPathsList()) { final File file = new File(changed); Collection<BuildRootDescriptor> descriptors = pd.getBuildRootIndex().findAllParentDescriptors(file, null, null); if (!descriptors.isEmpty()) { - if (Utils.IS_TEST_MODE) { - LOG.info("Applying dirty path from fs event: " + file.getPath()); + if (LOG.isDebugEnabled()) { + LOG.debug("Applying dirty path from fs event: " + changed); } long fileStamp = -1L; for (BuildRootDescriptor descriptor : descriptors) { @@ -325,7 +345,7 @@ final class BuildSession implements Runnable, CanceledStatus { if (fileStamp == -1L) { fileStamp = FileSystemUtil.lastModified(file); // lazy init } - long stamp = timestamps.getStamp(file, descriptor.getTarget()); + final long stamp = timestamps.getStamp(file, descriptor.getTarget()); if (stamp != fileStamp) { if (!cacheCleared) { pd.getFSCache().clear(); @@ -333,11 +353,18 @@ final class BuildSession implements Runnable, CanceledStatus { } pd.fsState.markDirty(null, file, descriptor, timestamps, saveEventStamp); } + else { + if (LOG.isDebugEnabled()) { + LOG.debug(descriptor.getTarget() + ": Path considered up-to-date: " + changed + "; timestamp= " + stamp); + } + } } } } - else if (Utils.IS_TEST_MODE) { - LOG.info("Skipping dirty path: " + file.getPath()); + else { + if (LOG.isDebugEnabled()) { + LOG.debug("Skipping dirty path: " + file.getPath()); + } } } } @@ -380,19 +407,7 @@ final class BuildSession implements Runnable, CanceledStatus { try { out.writeInt(FSState.VERSION); out.writeLong(myLastEventOrdinal); - boolean hasWorkToDoWithModules = false; - for (JpsModule module : pd.getProject().getModules()) { - for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) { - if (state.hasWorkToDo(new ModuleBuildTarget(module, type))) { - hasWorkToDoWithModules = true; - break; - } - } - if (hasWorkToDoWithModules) { - break; - } - } - out.writeBoolean(hasWorkToDoWithModules); + out.writeBoolean(hasWorkToDo(state, pd)); state.save(out); } finally { @@ -407,6 +422,18 @@ final class BuildSession implements Runnable, CanceledStatus { } } + private static boolean hasWorkToDo(BuildFSState state, ProjectDescriptor pd) { + final BuildTargetIndex targetIndex = pd.getBuildTargetIndex(); + for (JpsModule module : pd.getProject().getModules()) { + for (ModuleBasedTarget<?> target : targetIndex.getModuleBasedTargets(module, BuildTargetRegistry.ModuleTargetSelector.ALL)) { + if (state.hasWorkToDo(target)) { + return true; + } + } + } + return false; + } + private static void saveOnDisk(BufferExposingByteArrayOutputStream bytes, final File file) throws IOException { FileOutputStream fos = null; try { diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java index 034e85120859..6b9fef1d9e8f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/ClasspathBootstrap.java @@ -131,7 +131,7 @@ public class ClasspathBootstrap { return ContainerUtil.newArrayList(cp); } - public static List<File> getJavacServerClasspath(String sdkHome) { + public static List<File> getJavacServerClasspath(String sdkHome, boolean useEclipseCompiler) { final Set<File> cp = new LinkedHashSet<File>(); cp.add(getResourceFile(JavacServer.class)); // self // util @@ -190,6 +190,17 @@ public class ClasspathBootstrap { } } + if (useEclipseCompiler) { + // eclipse compiler + for (JavaCompiler javaCompiler : ServiceLoader.load(JavaCompiler.class)) { // Eclipse compiler + final File compilerResource = getResourceFile(javaCompiler.getClass()); + final String name = compilerResource.getName(); + if (name.startsWith("ecj-") && name.endsWith(".jar")) { + cp.add(compilerResource); + } + } + } + final Class<JavaSourceTransformer> transformerClass = JavaSourceTransformer.class; final ServiceLoader<JavaSourceTransformer> loader = ServiceLoader.load(transformerClass, transformerClass.getClassLoader()); for (JavaSourceTransformer t : loader) { 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 c924d6d5e345..6f2015e88bc4 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java @@ -48,13 +48,12 @@ public class BuildOperations { final ProjectDescriptor pd = context.getProjectDescriptor(); final Timestamps timestamps = pd.timestamps.getStorage(); final BuildTargetConfiguration configuration = pd.getTargetsState().getTargetConfiguration(target); - if (context.isProjectRebuild()) { FSOperations.markDirtyFiles(context, target, timestamps, true, null, null); pd.fsState.markInitialScanPerformed(target); configuration.save(); } - else if (context.getScope().isRecompilationForced(target) || configuration.isTargetDirty() || configuration.outputRootWasDeleted(context)) { + else if (context.getScope().isRecompilationForced(target) || configuration.isTargetDirty(context) || configuration.outputRootWasDeleted(context)) { initTargetFSState(context, target, true); IncProjectBuilder.clearOutputFiles(context, target); pd.dataManager.cleanTargetStorages(target); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java index 7b2436ee58ac..fb466079dc38 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java @@ -20,8 +20,6 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jps.builders.BuildTargetType; import org.jetbrains.jps.service.JpsServiceManager; import java.io.File; @@ -39,7 +37,6 @@ public class BuilderRegistry { } private final Map<BuilderCategory, List<ModuleLevelBuilder>> myModuleLevelBuilders = new HashMap<BuilderCategory, List<ModuleLevelBuilder>>(); private final List<TargetBuilder<?,?>> myTargetBuilders = new ArrayList<TargetBuilder<?,?>>(); - private final Map<String, BuildTargetType<?>> myTargetTypes = new LinkedHashMap<String, BuildTargetType<?>>(); private final FileFilter myModuleBuilderFileFilter; public static BuilderRegistry getInstance() { @@ -66,13 +63,6 @@ public class BuilderRegistry { } myModuleLevelBuilders.get(builder.getCategory()).add(builder); } - for (BuildTargetType<?> type : service.getTargetTypes()) { - String id = type.getTypeId(); - BuildTargetType<?> old = myTargetTypes.put(id, type); - if (old != null) { - LOG.error("Two build target types (" + type + ", " + old + ") use same id (" + id + ")"); - } - } } if (compilableFileExtensions == null) { myModuleBuilderFileFilter = FileUtilRt.ALL_FILES; @@ -88,20 +78,11 @@ public class BuilderRegistry { } } - @Nullable - public BuildTargetType<?> getTargetType(String typeId) { - return myTargetTypes.get(typeId); - } - @NotNull public FileFilter getModuleBuilderFileFilter() { return myModuleBuilderFileFilter; } - public Collection<BuildTargetType<?>> getTargetTypes() { - return myTargetTypes.values(); - } - public int getModuleLevelBuilderCount() { int count = 0; for (BuilderCategory category : BuilderCategory.values()) { 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 e16c78813312..d4f828572b68 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -49,10 +49,12 @@ import org.jetbrains.jps.cmdline.ProjectDescriptor; import org.jetbrains.jps.incremental.fs.BuildFSState; import org.jetbrains.jps.incremental.java.ExternalJavacDescriptor; import org.jetbrains.jps.incremental.messages.*; +import org.jetbrains.jps.incremental.storage.BuildTargetConfiguration; import org.jetbrains.jps.incremental.storage.OneToManyPathsMapping; import org.jetbrains.jps.indices.ModuleExcludeIndex; import org.jetbrains.jps.model.java.JpsJavaExtensionService; import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerConfiguration; +import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.service.SharedThreadPool; import org.jetbrains.jps.util.JpsPathUtil; @@ -177,6 +179,7 @@ public class IncProjectBuilder { context = createContext(scope, isMake, isProjectRebuild); runBuild(context, forceCleanCaches); myProjectDescriptor.dataManager.saveVersion(); + reportRebuiltModules(context); } catch (ProjectBuildException e) { final Throwable cause = e.getCause(); @@ -191,8 +194,9 @@ public class IncProjectBuilder { throw new RebuildRequestedException(cause); } else { + reportRebuiltModules(context); if (cause == null) { - // some builder desided to stop the build + // some builder decided to stop the build // report optional progress message if exists final String msg = e.getMessage(); if (!StringUtil.isEmpty(msg)) { @@ -222,6 +226,41 @@ public class IncProjectBuilder { } } + private static void reportRebuiltModules(CompileContextImpl context) { + final Set<JpsModule> modules = BuildTargetConfiguration.MODULES_WITH_TARGET_CONFIG_CHANGED_KEY.get(context); + if (modules == null || modules.isEmpty()) { + return; + } + final StringBuilder message = new StringBuilder(); + if (modules.size() > 1) { + message.append("Modules "); + final int namesLimit = 5; + int idx = 0; + for (Iterator<JpsModule> iterator = modules.iterator(); iterator.hasNext(); ) { + final JpsModule module = iterator.next(); + if (idx == namesLimit && iterator.hasNext()) { + message.append(" and ").append(modules.size() - namesLimit).append(" others"); + break; + } + if (idx > 0) { + message.append(", "); + } + message.append("\"").append(module.getName()).append("\""); + idx += 1; + } + message.append(" were"); + } + else { + message.append("Module \"").append(modules.iterator().next().getName()).append("\" was"); + } + message.append(" fully rebuilt due to project configuration"); + if (ModuleBuildTarget.REBUILD_ON_DEPENDENCY_CHANGE) { + message.append("/dependencies"); + } + message.append(" changes"); + context.processMessage(new CompilerMessage("", BuildMessage.Kind.INFO, message.toString())); + } + private static void flushContext(CompileContext context) { if (context != null) { final ProjectDescriptor pd = context.getProjectDescriptor(); @@ -240,25 +279,8 @@ public class IncProjectBuilder { } ExternalJavacDescriptor.KEY.set(context, null); } - //cleanupJavacNameTable(); } - //private static boolean ourClenupFailed = false; - - //private static void cleanupJavacNameTable() { - // try { - // if (JavaBuilder.USE_EMBEDDED_JAVAC && !ourClenupFailed) { - // final Field freelistField = Class.forName("com.sun.tools.javac.util.Name$Table").getDeclaredField("freelist"); - // freelistField.setAccessible(true); - // freelistField.set(null, com.sun.tools.javac.util.List.nil()); - // } - // } - // catch (Throwable e) { - // ourClenupFailed = true; - // //LOG.info(e); - // } - //} - private void runBuild(CompileContextImpl context, boolean forceCleanCaches) throws ProjectBuildException { context.setDone(0.0f); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/JVMModuleBuildTarget.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/JVMModuleBuildTarget.java index 42afc58fcbc6..12c3c18cc20c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/JVMModuleBuildTarget.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/JVMModuleBuildTarget.java @@ -19,10 +19,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.builders.BuildRootDescriptor; -import org.jetbrains.jps.builders.BuildRootIndex; -import org.jetbrains.jps.builders.BuildTargetType; -import org.jetbrains.jps.builders.ModuleBasedTarget; +import org.jetbrains.jps.builders.*; import org.jetbrains.jps.indices.ModuleExcludeIndex; import org.jetbrains.jps.model.module.JpsModule; @@ -38,7 +35,7 @@ import java.util.Set; */ public abstract class JVMModuleBuildTarget<R extends BuildRootDescriptor> extends ModuleBasedTarget<R> { - public JVMModuleBuildTarget(BuildTargetType<? extends JVMModuleBuildTarget<R>> targetType, JpsModule module) { + public JVMModuleBuildTarget(ModuleBasedBuildTargetType<? extends JVMModuleBuildTarget<R>> targetType, JpsModule module) { super(targetType, module); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java index e27534b98d40..2ae917dcf319 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java @@ -22,6 +22,7 @@ import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.ProjectPaths; +import org.jetbrains.jps.api.GlobalOptions; import org.jetbrains.jps.builders.*; import org.jetbrains.jps.builders.java.ExcludedJavaSourceRootProvider; import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; @@ -50,6 +51,9 @@ import java.util.Set; * @author nik */ public final class ModuleBuildTarget extends JVMModuleBuildTarget<JavaSourceRootDescriptor> { + public static final Boolean REBUILD_ON_DEPENDENCY_CHANGE = Boolean.valueOf( + System.getProperty(GlobalOptions.REBUILD_ON_DEPENDENCY_CHANGE_OPTION, "true") + ); private final JavaModuleBuildTargetType myTargetType; public ModuleBuildTarget(@NotNull JpsModule module, JavaModuleBuildTargetType targetType) { @@ -169,10 +173,13 @@ public final class ModuleBuildTarget extends JVMModuleBuildTarget<JavaSourceRoot } private int getDependenciesFingerprint() { - final JpsModule module = getModule(); - int fingerprint = 0; + if (!REBUILD_ON_DEPENDENCY_CHANGE) { + return fingerprint; + } + + final JpsModule module = getModule(); JpsJavaDependenciesEnumerator enumerator = JpsJavaExtensionService.dependencies(module).compileOnly(); if (!isTests()) { enumerator = enumerator.productionOnly(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/TargetTypeRegistry.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/TargetTypeRegistry.java new file mode 100644 index 000000000000..ab2b35d5bae8 --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/TargetTypeRegistry.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2013 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.incremental; + +import com.intellij.openapi.diagnostic.Logger; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.builders.BuildTargetType; +import org.jetbrains.jps.service.JpsServiceManager; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +public class TargetTypeRegistry { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.TargetTypeRegistry"); + private static class Holder { + static final TargetTypeRegistry ourInstance = new TargetTypeRegistry(); + } + private final Map<String, BuildTargetType<?>> myTargetTypes = new LinkedHashMap<String, BuildTargetType<?>>(); + + public static TargetTypeRegistry getInstance() { + return Holder.ourInstance; + } + + private TargetTypeRegistry() { + for (BuilderService service : JpsServiceManager.getInstance().getExtensions(BuilderService.class)) { + for (BuildTargetType<?> type : service.getTargetTypes()) { + String id = type.getTypeId(); + BuildTargetType<?> old = myTargetTypes.put(id, type); + if (old != null) { + LOG.error("Two build target types (" + type + ", " + old + ") use same id (" + id + ")"); + } + } + } + } + + @Nullable + public BuildTargetType<?> getTargetType(String typeId) { + return myTargetTypes.get(typeId); + } + + + public Collection<BuildTargetType<?>> getTargetTypes() { + return myTargetTypes.values(); + } + +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java index 32bfab619171..a6d23b53aa69 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/Utils.java @@ -92,12 +92,7 @@ public class Utils { return new File(systemRoot, name.toLowerCase(Locale.US) + "_" + Integer.toHexString(locationHash)); } - public static URI toURI(String localPath) { - return toURI(localPath, true); - } - - private static URI toURI(String localPath, boolean convertSpaces) { try { String p = FileUtil.toSystemIndependentName(localPath); if (!p.startsWith("/")) { @@ -106,7 +101,7 @@ public class Utils { if (p.startsWith("//")) { p = "//" + p; } - return new URI("file", null, convertSpaces? p.replaceAll(" ", "%20") : p, null); + return new URI("file", null, p, null); } catch (URISyntaxException e) { throw new Error(e); @@ -122,7 +117,7 @@ public class Utils { if (path == null) { return null; } - return new File(toURI(path, false)); + return new File(toURI(path)); } public static boolean intersects(Set<JpsModule> set1, Set<JpsModule> set2) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactRootDescriptor.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactRootDescriptor.java index 24849efae998..4d4f7492768e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactRootDescriptor.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactRootDescriptor.java @@ -50,10 +50,6 @@ public abstract class ArtifactRootDescriptor extends BuildRootDescriptor { myDestinationInfo = destinationInfo; } - public final String getArtifactName() { - return myTarget.getId(); - } - @Override public String toString() { return getFullPath(); @@ -75,8 +71,8 @@ public abstract class ArtifactRootDescriptor extends BuildRootDescriptor { public FileFilter createFileFilter() { return new FileFilter() { @Override - public boolean accept(File pathname) { - return myFilter.accept(pathname.getAbsolutePath()); + public boolean accept(File file) { + return myFilter.accept(file.getAbsolutePath()); } }; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FSState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FSState.java index 462b8eaf027e..dde4f12065db 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FSState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FSState.java @@ -23,8 +23,8 @@ import gnu.trove.TObjectLongHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.builders.*; -import org.jetbrains.jps.incremental.BuilderRegistry; import org.jetbrains.jps.incremental.CompileContext; +import org.jetbrains.jps.incremental.TargetTypeRegistry; import org.jetbrains.jps.incremental.storage.Timestamps; import org.jetbrains.jps.model.JpsModel; @@ -63,7 +63,7 @@ public class FSState { } public void load(DataInputStream in, JpsModel model, final BuildRootIndex buildRootIndex) throws IOException { - BuilderRegistry registry = BuilderRegistry.getInstance(); + final TargetTypeRegistry registry = TargetTypeRegistry.getInstance(); int typeCount = in.readInt(); while (typeCount-- > 0) { final String typeId = IOUtil.readString(in); @@ -102,6 +102,9 @@ public class FSState { public boolean markDirty(@Nullable CompileContext context, final File file, final BuildRootDescriptor rd, final @Nullable Timestamps tsStorage, boolean saveEventStamp) throws IOException { final boolean marked = getDelta(rd.getTarget()).markRecompile(rd, file); if (marked) { + if (LOG.isDebugEnabled()) { + LOG.debug(rd.getTarget() + ": MARKED DIRTY: " + file.getPath()); + } if (saveEventStamp) { myRegistrationStamps.put(file, System.currentTimeMillis()); } @@ -109,6 +112,11 @@ public class FSState { tsStorage.removeStamp(file, rd.getTarget()); } } + else { + if (LOG.isDebugEnabled()) { + LOG.debug(rd.getTarget() + ": NOT MARKED DIRTY: " + file.getPath()); + } + } return marked; } 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 46921cf25856..97ea01db976b 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 @@ -378,9 +378,6 @@ public class JavaBuilder extends ModuleLevelBuilder { } private static boolean useEclipseCompiler(CompileContext context) { - if (!USE_EMBEDDED_JAVAC) { - return false; - } JpsProject project = context.getProjectDescriptor().getProject(); final JpsJavaCompilerConfiguration configuration = JpsJavaExtensionService.getInstance().getCompilerConfiguration(project); final String compilerId = configuration != null? configuration.getJavaCompilerId() : null; @@ -414,21 +411,11 @@ public class JavaBuilder extends ModuleLevelBuilder { final int port = findFreePort(); final int heapSize = getJavacServerHeapSize(context); - // defaulting to the same jdk that used to run the build process - String javaHome = SystemProperties.getJavaHome(); - int javaVersion = convertToNumber(SystemProperties.getJavaVersion()); - - for (JpsSdk<?> sdk : context.getProjectDescriptor().getProjectJavaSdks()) { - final String version = sdk.getVersionString(); - final int ver = convertToNumber(version); - if (ver > javaVersion) { - javaVersion = ver; - javaHome = sdk.getHomePath(); - } - } + // use the same jdk that used to run the build process + final String javaHome = SystemProperties.getJavaHome(); final BaseOSProcessHandler processHandler = JavacServerBootstrap.launchJavacServer( - javaHome, heapSize, port, Utils.getSystemRoot(), getCompilationVMOptions(context) + javaHome, heapSize, port, Utils.getSystemRoot(), getCompilationVMOptions(context), useEclipseCompiler(context) ); final JavacServerClient client = new JavacServerClient(); try { @@ -657,16 +644,6 @@ public class JavaBuilder extends ModuleLevelBuilder { return cached; } int javaVersion = convertToNumber(SystemProperties.getJavaVersion()); - if (!USE_EMBEDDED_JAVAC) { - // in case of external javac, run compiler from the newest jdk that is used in the project - for (JpsSdk<?> sdk : context.getProjectDescriptor().getProjectJavaSdks()) { - final String version = sdk.getVersionString(); - final int ver = convertToNumber(version); - if (ver > javaVersion) { - javaVersion = ver; - } - } - } JAVA_COMPILER_VERSION_KEY.set(context, javaVersion); return javaVersion; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetConfiguration.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetConfiguration.java index 8067aefacd5c..8d926f89c273 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetConfiguration.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetConfiguration.java @@ -16,6 +16,7 @@ package org.jetbrains.jps.incremental.storage; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.SmartList; @@ -23,6 +24,8 @@ import gnu.trove.THashSet; import org.jetbrains.jps.builders.BuildTarget; import org.jetbrains.jps.incremental.CompileContext; import org.jetbrains.jps.incremental.GlobalContextKey; +import org.jetbrains.jps.incremental.ModuleBuildTarget; +import org.jetbrains.jps.model.module.JpsModule; import java.io.*; import java.util.Collection; @@ -34,6 +37,7 @@ import java.util.Set; * @author nik */ public class BuildTargetConfiguration { + public static final Key<Set<JpsModule>> MODULES_WITH_TARGET_CONFIG_CHANGED_KEY = GlobalContextKey.create("_modules_with_target_config_changed_"); private static final Logger LOG = Logger.getInstance(BuildTargetConfiguration.class); private final BuildTarget<?> myTarget; private final BuildTargetsState myTargetsState; @@ -60,7 +64,7 @@ public class BuildTargetConfiguration { return ""; } - public boolean isTargetDirty() { + public boolean isTargetDirty(CompileContext context) { final String currentState = getCurrentState(); if (!currentState.equals(myConfiguration)) { LOG.debug(myTarget + " configuration was changed:"); @@ -69,6 +73,16 @@ public class BuildTargetConfiguration { LOG.debug("New:"); LOG.debug(currentState); LOG.debug(myTarget + " will be recompiled"); + if (myTarget instanceof ModuleBuildTarget) { + final JpsModule module = ((ModuleBuildTarget)myTarget).getModule(); + synchronized (MODULES_WITH_TARGET_CONFIG_CHANGED_KEY) { + Set<JpsModule> modules = MODULES_WITH_TARGET_CONFIG_CHANGED_KEY.get(context); + if (modules == null) { + MODULES_WITH_TARGET_CONFIG_CHANGED_KEY.set(context, modules = new THashSet<JpsModule>()); + } + modules.add(module); + } + } return true; } return false; diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetsState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetsState.java index 2c95168fc29d..b4294293dc86 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetsState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildTargetsState.java @@ -23,7 +23,7 @@ import org.jetbrains.jps.builders.BuildTarget; import org.jetbrains.jps.builders.BuildTargetType; import org.jetbrains.jps.builders.impl.BuildRootIndexImpl; import org.jetbrains.jps.builders.storage.BuildDataPaths; -import org.jetbrains.jps.incremental.BuilderRegistry; +import org.jetbrains.jps.incremental.TargetTypeRegistry; import org.jetbrains.jps.model.JpsModel; import java.io.*; @@ -58,7 +58,7 @@ public class BuildTargetsState { catch (IOException e) { LOG.debug("Cannot load " + targetTypesFile + ":" + e.getMessage(), e); LOG.debug("Loading all target types to calculate max target id"); - for (BuildTargetType<?> type : BuilderRegistry.getInstance().getTargetTypes()) { + for (BuildTargetType<?> type : TargetTypeRegistry.getInstance().getTargetTypes()) { getTypeState(type); } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java index f298026813a2..0422fc270e8f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java @@ -25,6 +25,7 @@ import org.jetbrains.jps.incremental.LineOutputWriter; import javax.tools.*; import java.io.File; import java.io.IOException; +import java.lang.reflect.Field; import java.util.*; /** @@ -170,6 +171,9 @@ public class JavacMain { } finally { fileManager.close(); + if (nowUsingJavac) { + cleanupJavacNameTable(); + } } return false; } @@ -277,4 +281,40 @@ public class JavacMain { myOutputFileSink.save(cls); } } + + private static boolean ourCleanupFailed = false; + private static final class NameTableCleanupDataHolder { + static final com.sun.tools.javac.util.List emptyList = com.sun.tools.javac.util.List.nil(); + static final Field freelistField; + static { + try { + Field freelistRef; + try { + // trying jdk 6 + freelistRef = Class.forName("com.sun.tools.javac.util.Name$Table").getDeclaredField("freelist"); + } + catch (Exception e) { + // trying jdk 7 + freelistRef = Class.forName("com.sun.tools.javac.util.SharedNameTable").getDeclaredField("freelist"); + } + freelistRef.setAccessible(true); + freelistField = freelistRef; + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + private static void cleanupJavacNameTable() { + try { + if (!ourCleanupFailed) { + NameTableCleanupDataHolder.freelistField.set(null, NameTableCleanupDataHolder.emptyList); + } + } + catch (Throwable e) { + ourCleanupFailed = true; + } + } + } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java index de7d2a4577c0..359e151fd333 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java @@ -42,6 +42,7 @@ public class JavacServer { public static final int DEFAULT_SERVER_PORT = 7878; public static final String SERVER_SUCCESS_START_MESSAGE = "Javac server started successfully. Listening on port: "; public static final String SERVER_ERROR_START_MESSAGE = "Error starting Javac Server: "; + public static final String USE_ECLIPSE_COMPILER_PROPERTY = "use.eclipse.compiler"; private final ChannelGroup myAllOpenChannels = new DefaultChannelGroup("javac-server"); private final ChannelFactory myChannelFactory; @@ -149,7 +150,7 @@ public class JavacServer { }; try { - final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus, false); + final boolean rc = JavacMain.compile(options, files, classpath, platformCp, sourcePath, outs, diagnostic, outputSink, canceledStatus, System.getProperty(USE_ECLIPSE_COMPILER_PROPERTY) != null); return JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createBuildCompletedResponse(rc)); } catch (Throwable e) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java index 05a33b5ae65a..97093800f7bf 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerBootstrap.java @@ -39,7 +39,12 @@ import java.util.concurrent.Future; */ public class JavacServerBootstrap { - public static BaseOSProcessHandler launchJavacServer(String sdkHomePath, int heapSize, int port, File workingDir, List<String> vmOptions) throws Exception { + public static BaseOSProcessHandler launchJavacServer(String sdkHomePath, + int heapSize, + int port, + File workingDir, + List<String> vmOptions, + boolean useEclipseCompiler) throws Exception { final List<String> cmdLine = new ArrayList<String>(); appendParam(cmdLine, getVMExecutablePath(sdkHomePath)); appendParam(cmdLine, "-XX:MaxPermSize=150m"); @@ -77,13 +82,17 @@ public class JavacServerBootstrap { appendParam(cmdLine, "-Duser.region=" + region); } + if (useEclipseCompiler) { + appendParam(cmdLine, "-D" + JavacServer.USE_ECLIPSE_COMPILER_PROPERTY); + } + for (String option : vmOptions) { appendParam(cmdLine, option); } appendParam(cmdLine, "-classpath"); - final List<File> cp = ClasspathBootstrap.getJavacServerClasspath(sdkHomePath); + final List<File> cp = ClasspathBootstrap.getJavacServerClasspath(sdkHomePath, useEclipseCompiler); final StringBuilder classpath = new StringBuilder(); for (File file : cp) { if (classpath.length() > 0) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java index 89c7be1cda83..0004f5736c3a 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.List; +import org.jetbrains.jps.incremental.Utils; import javax.lang.model.SourceVersion; import javax.tools.*; @@ -26,7 +27,6 @@ import java.io.*; import java.lang.ref.SoftReference; import java.lang.reflect.Field; import java.net.URI; -import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.*; @@ -418,10 +418,10 @@ class OptimizedFileManager extends DefaultFileManager { public URI toUri() { try { - return new URI(f.getPath()); + return Utils.toURI(f.getPath()); } - catch (URISyntaxException ex) { - return f.toURI(); + catch (Throwable ex) { + return f.toURI().normalize(); } } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java index 80f06fd182c0..2d96145a20c9 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/OptimizedFileManager17.java @@ -21,6 +21,7 @@ import com.sun.tools.javac.file.RelativePath; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; +import org.jetbrains.jps.incremental.Utils; import javax.lang.model.SourceVersion; import javax.tools.*; @@ -229,7 +230,12 @@ class OptimizedFileManager17 extends com.sun.tools.javac.file.JavacFileManager { @Override public URI toUri() { - return file.toURI().normalize(); + try { + return Utils.toURI(file.getPath()); + } + catch (Throwable e) { + return file.toURI().normalize(); // fallback + } } @Override 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 8e49ab4ef8cf..b8c901470e28 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java +++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java @@ -17,10 +17,10 @@ package org.jetbrains.jps.builders; import org.jetbrains.jps.api.BuildType; import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType; -import org.jetbrains.jps.incremental.BuilderRegistry; import org.jetbrains.jps.incremental.CompileScope; import org.jetbrains.jps.incremental.CompileScopeImpl; import org.jetbrains.jps.incremental.ModuleBuildTarget; +import org.jetbrains.jps.incremental.TargetTypeRegistry; import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget; import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTargetType; import org.jetbrains.jps.model.artifact.JpsArtifact; @@ -85,7 +85,7 @@ public class CompileScopeTestBuilder { } public CompileScopeTestBuilder all() { - myTargetTypes.addAll(BuilderRegistry.getInstance().getTargetTypes()); + myTargetTypes.addAll(TargetTypeRegistry.getInstance().getTargetTypes()); return this; } diff --git a/jps/lib/optimizedFileManager.jar b/jps/lib/optimizedFileManager.jar Binary files differindex d744fd8cff84..cc5355bc32a6 100644 --- a/jps/lib/optimizedFileManager.jar +++ b/jps/lib/optimizedFileManager.jar diff --git a/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java b/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java index 8fd023eba207..cd31b4458246 100644 --- a/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java +++ b/jps/model-impl/src/com/intellij/openapi/fileTypes/impl/IgnoredPatternSet.java @@ -61,7 +61,7 @@ public class IgnoredPatternSet { } //Quite a hack, but still we need to have some name, which - //won't be catched by VFS for sure. + //won't be caught by VFS for sure. return fileName.endsWith(FileUtil.ASYNC_DELETE_EXTENSION); } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsGlobalLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsGlobalLoader.java index ef510e534a1e..aa6950dcf063 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsGlobalLoader.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsGlobalLoader.java @@ -15,6 +15,7 @@ */ package org.jetbrains.jps.model.serialization; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.FileUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -35,6 +36,7 @@ import java.util.Map; * @author nik */ public class JpsGlobalLoader extends JpsLoaderBase { + private static final Logger LOG = Logger.getInstance(JpsGlobalLoader.class); public static final String SDK_TABLE_COMPONENT_NAME = "ProjectJdkTable"; private static final JpsElementChildRole<JpsSimpleElement<Map<String, String>>> PATH_VARIABLES_ROLE = JpsElementChildRoleBase.create("path variables"); private static final JpsGlobalExtensionSerializer[] SERIALIZERS = { @@ -61,6 +63,7 @@ public class JpsGlobalLoader extends JpsLoaderBase { } private void load(File optionsDir) { + LOG.debug("Loading config from " + optionsDir.getAbsolutePath()); for (JpsGlobalExtensionSerializer serializer : SERIALIZERS) { loadGlobalComponents(optionsDir, serializer); } 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 1f6e04089a6d..ed66c43e7409 100644 --- a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java +++ b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java @@ -49,6 +49,9 @@ public class Standalone { @Argument(value = "script", prefix = "--", description = "Path to Groovy script which will be used to initialize global options") public String initializationScriptPath; + @Argument(value = "cache-dir", prefix = "--", description = "Path to directory to store build caches") + public String cacheDirPath; + @Argument(value = "modules", prefix = "--", delimiter = ",", description = "Comma-separated list of modules to compile") public String[] modules = ArrayUtil.EMPTY_STRING_ARRAY; @@ -117,7 +120,13 @@ public class Standalone { BuildType buildType = incremental ? BuildType.MAKE : BuildType.PROJECT_REBUILD; Set<String> modulesSet = new HashSet<String>(Arrays.asList(modules)); List<String> artifactsList = Arrays.asList(artifacts); - File dataStorageRoot = Utils.getDataStorageRoot(projectPath); + File dataStorageRoot; + if (cacheDirPath != null) { + dataStorageRoot = new File(cacheDirPath); + } + else { + dataStorageRoot = Utils.getDataStorageRoot(projectPath); + } if (dataStorageRoot == null) { System.err.println("Error: Cannot determine build data storage root for project " + projectPath); return; |