summaryrefslogtreecommitdiff
path: root/jps
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2013-07-08 11:26:24 -0700
committerTor Norbye <tnorbye@google.com>2013-07-08 11:26:24 -0700
commitc1ace1f7e1e49c81bb4b75377c99f07be340abfe (patch)
tree9d0db96bd3d86ddfec80e7e3554cad9dcc066553 /jps
parentc6218e46d5d2017e987ecdbd99b318a95c42abc0 (diff)
downloadidea-c1ace1f7e1e49c81bb4b75377c99f07be340abfe.tar.gz
Snapshot aea001abfc1b38fec3a821bcd5174cc77dc75787 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: Icdea2a2bd7ad43b4d05967b1f0479db3bda1c93c
Diffstat (limited to 'jps')
-rw-r--r--jps/jps-builders/proto/javac_remote_proto.proto1
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootDescriptorImpl.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/builders/impl/storage/BuildTargetStorages.java68
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/FSCache.java21
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java33
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java8
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java1
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java63
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildMessage.java4
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java197
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/DiagnosticOutputConsumer.java2
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java8
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java20
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java11
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java9
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java5
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerResponseHandler.java7
-rw-r--r--jps/jps-builders/src/org/jetbrains/jps/javac/TransformableJavaFileObject.java10
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/ether/MarkDirtyTest.java2
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.java14
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java10
-rw-r--r--jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java2
-rw-r--r--jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java7
25 files changed, 344 insertions, 169 deletions
diff --git a/jps/jps-builders/proto/javac_remote_proto.proto b/jps/jps-builders/proto/javac_remote_proto.proto
index c9991c036046..63d4d2ed402e 100644
--- a/jps/jps-builders/proto/javac_remote_proto.proto
+++ b/jps/jps-builders/proto/javac_remote_proto.proto
@@ -50,6 +50,7 @@ message Message {
CLASS_DATA = 3;
BUILD_COMPLETED = 4;
REQUEST_ACK = 5;
+ SRC_FILE_LOADED = 6;
}
message CompileMessage {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java b/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java
index 0569e1917886..17cfe2f33162 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java
@@ -26,7 +26,7 @@ import java.util.List;
*/
public abstract class ArtifactBuildTaskProvider {
public enum ArtifactBuildPhase {
- PRE_PROCESSING, POST_PROCESSING
+ PRE_PROCESSING, FINISHING_BUILD, POST_PROCESSING
}
@NotNull
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootDescriptorImpl.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootDescriptorImpl.java
index 84a12e514248..bb59350983e7 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootDescriptorImpl.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/BuildRootDescriptorImpl.java
@@ -27,9 +27,7 @@ public class BuildRootDescriptorImpl extends BuildRootDescriptor {
private final boolean myCanUseFileCache;
public BuildRootDescriptorImpl(BuildTarget target, File root) {
- myTarget = target;
- myRoot = root;
- myCanUseFileCache = super.canUseFileCache();
+ this(target, root, false);
}
public BuildRootDescriptorImpl(BuildTarget target, File root, boolean canUseFileCache) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/storage/BuildTargetStorages.java b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/storage/BuildTargetStorages.java
index 4e64ce68afa3..e94bee329d3a 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/builders/impl/storage/BuildTargetStorages.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/builders/impl/storage/BuildTargetStorages.java
@@ -15,6 +15,8 @@
*/
package org.jetbrains.jps.builders.impl.storage;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
@@ -23,8 +25,9 @@ import org.jetbrains.jps.incremental.storage.CompositeStorageOwner;
import org.jetbrains.jps.incremental.storage.StorageOwner;
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
/**
* @author nik
@@ -32,7 +35,8 @@ import java.util.Map;
public class BuildTargetStorages extends CompositeStorageOwner {
private final BuildTarget<?> myTarget;
private final BuildDataPaths myPaths;
- private Map<StorageProvider<?>, StorageOwner> myStorages = new HashMap<StorageProvider<?>, StorageOwner>();
+ private final ConcurrentMap<StorageProvider<?>, AtomicNotNullLazyValue<? extends StorageOwner>> myStorages
+ = new ConcurrentHashMap<StorageProvider<?>, AtomicNotNullLazyValue<? extends StorageOwner>>(16, 0.75f, 1);
public BuildTargetStorages(BuildTarget<?> target, BuildDataPaths paths) {
myTarget = target;
@@ -40,18 +44,62 @@ public class BuildTargetStorages extends CompositeStorageOwner {
}
@NotNull
- public <S extends StorageOwner> S getOrCreateStorage(@NotNull StorageProvider<S> provider) throws IOException {
+ public <S extends StorageOwner> S getOrCreateStorage(@NotNull final StorageProvider<S> provider) throws IOException {
+ NotNullLazyValue<? extends StorageOwner> lazyValue = myStorages.get(provider);
+ if (lazyValue == null) {
+ AtomicNotNullLazyValue<S> newValue = new AtomicNotNullLazyValue<S>() {
+ @NotNull
+ @Override
+ protected S compute() {
+ try {
+ return provider.createStorage(myPaths.getTargetDataRoot(myTarget));
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ lazyValue = myStorages.putIfAbsent(provider, newValue);
+ if (lazyValue == null) {
+ lazyValue = newValue; // just initialized
+ }
+ }
//noinspection unchecked
- S storage = (S)myStorages.get(provider);
- if (storage == null) {
- storage = provider.createStorage(myPaths.getTargetDataRoot(myTarget));
- myStorages.put(provider, storage);
+ try {
+ return (S)lazyValue.getValue();
+ }
+ catch (RuntimeException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof IOException) {
+ throw (IOException)cause;
+ }
+ throw e;
}
- return (S)storage;
}
@Override
protected Iterable<? extends StorageOwner> getChildStorages() {
- return myStorages.values();
+ return new Iterable<StorageOwner>() {
+ @Override
+ public Iterator<StorageOwner> iterator() {
+ final Iterator<AtomicNotNullLazyValue<? extends StorageOwner>> iterator = myStorages.values().iterator();
+ return new Iterator<StorageOwner>() {
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public StorageOwner next() {
+ return iterator.next().getValue();
+ }
+
+ @Override
+ public void remove() {
+ iterator.remove();
+ }
+ };
+ }
+ };
}
}
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 7fe98f331a26..7061fc649300 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildRunner.java
@@ -55,7 +55,7 @@ import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage
public class BuildRunner {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildRunner");
public static final boolean PARALLEL_BUILD_ENABLED = Boolean.parseBoolean(System.getProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, "false"));
- private static final boolean STORE_TEMP_CACHES_IN_MEMORY = PARALLEL_BUILD_ENABLED || System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null;
+ private static final boolean STORE_TEMP_CACHES_IN_MEMORY = PARALLEL_BUILD_ENABLED || Boolean.valueOf(System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION, "true"));
private final JpsModelLoader myModelLoader;
private final List<String> myFilePaths;
private final Map<String, String> myBuilderParams;
@@ -121,7 +121,7 @@ public class BuildRunner {
for (int attempt = 0; attempt < 2; attempt++) {
final boolean forceClean = myForceCleanCaches && myFilePaths.isEmpty();
final CompileScope compileScope = createCompilationScope(pd, scopes, myFilePaths, forceClean, includeDependenciesToScope);
- final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), myBuilderParams, cs, constantSearch);
+ final IncProjectBuilder builder = new IncProjectBuilder(pd, BuilderRegistry.getInstance(), myBuilderParams, cs, constantSearch, Utils.IS_TEST_MODE);
builder.addMessageHandler(msgHandler);
try {
switch (buildType) {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSCache.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSCache.java
index 75b5a9910f7a..689d2fea362a 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSCache.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSCache.java
@@ -19,6 +19,7 @@ import gnu.trove.THashMap;
import org.jetbrains.annotations.Nullable;
import java.io.File;
+import java.util.Collections;
import java.util.Map;
/**
@@ -37,24 +38,20 @@ public class FSCache {
private static final File[] NULL_VALUE = new File[0];
private static final File[] EMPTY_FILE_ARRAY = new File[0];
- private final Map<File, File[]> myMap = new THashMap<File, File[]>();
+ private final Map<File, File[]> myMap = Collections.synchronizedMap(new THashMap<File, File[]>());
@Nullable
public File[] getChildren(File file) {
- synchronized (myMap) {
- final File[] children = myMap.get(file);
- if (children != null) {
- return children == NULL_VALUE? null : children;
- }
- final File[] files = file.listFiles();
- myMap.put(file, files == null? NULL_VALUE : (files.length == 0? EMPTY_FILE_ARRAY : files));
- return files;
+ final File[] children = myMap.get(file);
+ if (children != null) {
+ return children == NULL_VALUE? null : children;
}
+ final File[] files = file.listFiles();
+ myMap.put(file, files == null? NULL_VALUE : (files.length == 0? EMPTY_FILE_ARRAY : files));
+ return files;
}
public void clear() {
- synchronized (myMap) {
- myMap.clear();
- }
+ myMap.clear();
}
}
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 b9bf4e5564ec..718dc8c1ca4f 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
@@ -81,7 +81,7 @@ public class IncProjectBuilder {
private static final String CLASSPATH_INDEX_FINE_NAME = "classpath.index";
private static final boolean GENERATE_CLASSPATH_INDEX = Boolean.parseBoolean(System.getProperty(GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION, "false"));
private static final GlobalContextKey<Set<BuildTarget<?>>> TARGET_WITH_CLEARED_OUTPUT = GlobalContextKey.create("_targets_with_cleared_output_");
- private static final int MAX_BUILDER_THREADS;
+ public static final int MAX_BUILDER_THREADS;
static {
int maxThreads = 6;
try {
@@ -105,6 +105,7 @@ public class IncProjectBuilder {
}
}
};
+ private final boolean myIsTestMode;
private volatile float myTargetsProcessed = 0.0f;
private final float myTotalTargetsWork;
@@ -112,7 +113,7 @@ public class IncProjectBuilder {
private final List<Future> myAsyncTasks = Collections.synchronizedList(new ArrayList<Future>());
public IncProjectBuilder(ProjectDescriptor pd, BuilderRegistry builderRegistry, Map<String, String> builderParams, CanceledStatus cs,
- @Nullable Callbacks.ConstantAffectionResolver constantSearch) {
+ @Nullable Callbacks.ConstantAffectionResolver constantSearch, final boolean isTestMode) {
myProjectDescriptor = pd;
myBuilderRegistry = builderRegistry;
myBuilderParams = builderParams;
@@ -120,6 +121,7 @@ public class IncProjectBuilder {
myConstantSearch = constantSearch;
myTotalTargetsWork = pd.getBuildTargetIndex().getAllTargets().size();
myTotalModuleLevelBuilderCount = builderRegistry.getModuleLevelBuilderCount();
+ myIsTestMode = isTestMode;
}
public void addMessageHandler(MessageHandler handler) {
@@ -936,15 +938,10 @@ public class IncProjectBuilder {
final ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger();
// actually delete outputs associated with removed paths
final Collection<String> pathsForIteration;
- if (Utils.IS_TEST_MODE) {
+ if (myIsTestMode) {
// ensure predictable order in test logs
pathsForIteration = new ArrayList<String>(deletedPaths);
- Collections.sort((List<String>)pathsForIteration, new Comparator<String>() {
- @Override
- public int compare(String o1, String o2) {
- return o1.compareTo(o2);
- }
- });
+ Collections.sort((List<String>)pathsForIteration);
}
else {
pathsForIteration = deletedPaths;
@@ -1060,6 +1057,10 @@ public class IncProjectBuilder {
BUILDER_CATEGORY_LOOP:
for (BuilderCategory category : BuilderCategory.values()) {
final List<ModuleLevelBuilder> builders = myBuilderRegistry.getBuilders(category);
+ if (category == BuilderCategory.CLASS_POST_PROCESSOR) {
+ // ensure changes from instrumenters are visible to class post-processors
+ saveInstrumentedClasses(outputConsumer);
+ }
if (builders.isEmpty()) {
continue;
}
@@ -1117,11 +1118,7 @@ public class IncProjectBuilder {
while (nextPassRequired);
}
finally {
- for (CompiledClass compiledClass : outputConsumer.getCompiledClasses().values()) {
- if (compiledClass.isDirty()) {
- compiledClass.save();
- }
- }
+ saveInstrumentedClasses(outputConsumer);
outputConsumer.fireFileGeneratedEvents();
outputConsumer.clear();
for (BuilderCategory category : BuilderCategory.values()) {
@@ -1134,6 +1131,14 @@ public class IncProjectBuilder {
return doneSomething;
}
+ private static void saveInstrumentedClasses(ChunkBuildOutputConsumerImpl outputConsumer) throws IOException {
+ for (CompiledClass compiledClass : outputConsumer.getCompiledClasses().values()) {
+ if (compiledClass.isDirty()) {
+ compiledClass.save();
+ }
+ }
+ }
+
private static void onChunkBuildComplete(CompileContext context, @NotNull BuildTargetChunk chunk) throws IOException {
final ProjectDescriptor pd = context.getProjectDescriptor();
final BuildFSState fsState = pd.fsState;
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 0763f17a3ccb..a16810e15792 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleBuildTarget.java
@@ -139,13 +139,17 @@ public final class ModuleBuildTarget extends JVMModuleBuildTarget<JavaSourceRoot
roots_loop:
for (JpsTypedModuleSourceRoot<JpsSimpleElement<JavaSourceRootProperties>> sourceRoot : myModule.getSourceRoots(type)) {
+ if (JpsPathUtil.isUnder(moduleExcludes, sourceRoot.getFile())) {
+ continue;
+ }
for (ExcludedJavaSourceRootProvider provider : excludedRootProviders) {
- if (provider.isExcludedFromCompilation(myModule, sourceRoot) || JpsPathUtil.isUnder(moduleExcludes, sourceRoot.getFile())) {
+ if (provider.isExcludedFromCompilation(myModule, sourceRoot)) {
continue roots_loop;
}
}
final String packagePrefix = sourceRoot.getProperties().getData().getPackagePrefix();
- roots.add(new JavaSourceRootDescriptor(sourceRoot.getFile(), this, false, false, packagePrefix, computeRootExcludes(sourceRoot.getFile(), index)));
+ roots.add(new JavaSourceRootDescriptor(sourceRoot.getFile(), this, false, false, packagePrefix,
+ computeRootExcludes(sourceRoot.getFile(), index)));
}
return roots;
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java
index e4350bd1d50b..a83164eeba34 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/IncArtifactBuilder.java
@@ -173,6 +173,7 @@ public class IncArtifactBuilder extends TargetBuilder<ArtifactRootDescriptor, Ar
JarsBuilder builder = new JarsBuilder(changedJars, context, outputConsumer, outSrcMapping);
builder.buildJars();
+ runArtifactTasks(context, artifact, ArtifactBuildTaskProvider.ArtifactBuildPhase.FINISHING_BUILD);
runArtifactTasks(context, artifact, ArtifactBuildTaskProvider.ArtifactBuildPhase.POST_PROCESSING);
}
catch (IOException e) {
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 d3a654a47327..776c3a800834 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
@@ -50,15 +50,14 @@ import org.jetbrains.jps.incremental.messages.ProgressMessage;
import org.jetbrains.jps.javac.*;
import org.jetbrains.jps.model.JpsDummyElement;
import org.jetbrains.jps.model.JpsProject;
-import org.jetbrains.jps.model.JpsSimpleElement;
-import org.jetbrains.jps.model.java.*;
+import org.jetbrains.jps.model.java.JpsJavaExtensionService;
+import org.jetbrains.jps.model.java.JpsJavaSdkType;
+import org.jetbrains.jps.model.java.LanguageLevel;
import org.jetbrains.jps.model.java.compiler.*;
import org.jetbrains.jps.model.library.sdk.JpsSdk;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleType;
-import org.jetbrains.jps.model.module.JpsTypedModuleSourceRoot;
import org.jetbrains.jps.service.JpsServiceManager;
-import org.jetbrains.jps.util.JpsPathUtil;
import javax.tools.*;
import java.io.*;
@@ -233,7 +232,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
final Collection<File> platformCp = ProjectPaths.getPlatformCompilationClasspath(chunk, false/*context.isProjectRebuild()*/);
// begin compilation round
- final DiagnosticSink diagnosticSink = new DiagnosticSink(context);
final Mappings delta = pd.dataManager.getMappings().createDelta();
final Callbacks.Backend mappingsCallback = delta.getCallback();
final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, mappingsCallback, chunk.getName());
@@ -248,14 +246,14 @@ public class JavaBuilder extends ModuleLevelBuilder {
exitCode = ExitCode.OK;
final Set<File> srcPath = new HashSet<File>();
- collectSourceRoots(chunk, srcPath, chunk.containsTests()? JavaSourceRootType.TEST_SOURCE : JavaSourceRootType.SOURCE);
final BuildRootIndex index = pd.getBuildRootIndex();
for (ModuleBuildTarget target : chunk.getTargets()) {
for (JavaSourceRootDescriptor rd : index.getTempTargetRoots(target, context)) {
srcPath.add(rd.root);
}
}
-
+ final DiagnosticSink diagnosticSink = new DiagnosticSink(context);
+
final String chunkName = chunk.getName();
context.processMessage(new ProgressMessage("Parsing java... [" + chunkName + "]"));
@@ -276,7 +274,17 @@ public class JavaBuilder extends ModuleLevelBuilder {
LOG.debug(" " + file.getAbsolutePath());
}
}
- compiledOk = compileJava(context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink);
+ try {
+ compiledOk = compileJava(context, chunk, files, classpath, platformCp, srcPath, diagnosticSink, outputSink);
+ }
+ finally {
+ // heuristic: incorrect paths data recovery, so that the next make should not contain non-existing sources in 'recompile' list
+ for (File file : diagnosticSink.getFilesWithErrors()) {
+ if (!file.exists()) {
+ FSOperations.markDeleted(context, file);
+ }
+ }
+ }
}
context.checkCanceled();
@@ -303,14 +311,6 @@ public class JavaBuilder extends ModuleLevelBuilder {
return exitCode;
}
- private static void collectSourceRoots(ModuleChunk chunk, Set<File> srcPath, final JavaSourceRootType rootType) {
- for (JpsModule module : chunk.getModules()) {
- for (JpsTypedModuleSourceRoot<JpsSimpleElement<JavaSourceRootProperties>> root : module.getSourceRoots(rootType)) {
- srcPath.add(JpsPathUtil.urlToFile(root.getUrl()));
- }
- }
- }
-
private boolean compileJava(
final CompileContext context,
ModuleChunk chunk,
@@ -780,15 +780,20 @@ public class JavaBuilder extends ModuleLevelBuilder {
return map;
}
- private class DiagnosticSink implements DiagnosticOutputConsumer {
+ private static class DiagnosticSink implements DiagnosticOutputConsumer {
private final CompileContext myContext;
private volatile int myErrorCount = 0;
private volatile int myWarningCount = 0;
+ private final Set<File> myFilesWithErrors = new HashSet<File>();
public DiagnosticSink(CompileContext context) {
myContext = context;
}
+ @Override
+ public void javaFileLoaded(File file) {
+ }
+
public void registerImports(final String className, final Collection<String> imports, final Collection<String> staticImports) {
//submitAsyncTask(myContext, new Runnable() {
// public void run() {
@@ -819,7 +824,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
- private BuildMessage.Kind getKindByMessageText(String line) {
+ private static BuildMessage.Kind getKindByMessageText(String line) {
final String lowercasedLine = line.toLowerCase(Locale.US);
if (lowercasedLine.contains("error") || lowercasedLine.contains("requires target release")) {
return BuildMessage.Kind.ERROR;
@@ -853,15 +858,23 @@ public class JavaBuilder extends ModuleLevelBuilder {
catch (Exception e) {
LOG.info(e);
}
- final String srcPath = sourceFile != null ? FileUtil.toSystemIndependentName(sourceFile.getPath()) : null;
+ final String srcPath;
+ if (sourceFile != null) {
+ myFilesWithErrors.add(sourceFile);
+ srcPath = FileUtil.toSystemIndependentName(sourceFile.getPath());
+ }
+ else {
+ srcPath = null;
+ }
String message = diagnostic.getMessage(Locale.US);
if (Utils.IS_TEST_MODE) {
LOG.info(message);
}
- myContext.processMessage(
- new CompilerMessage(BUILDER_NAME, kind, message, srcPath, diagnostic.getStartPosition(),
- diagnostic.getEndPosition(), diagnostic.getPosition(), diagnostic.getLineNumber(),
- diagnostic.getColumnNumber()));
+ myContext.processMessage(new CompilerMessage(
+ BUILDER_NAME, kind, message, srcPath, diagnostic.getStartPosition(),
+ diagnostic.getEndPosition(), diagnostic.getPosition(), diagnostic.getLineNumber(),
+ diagnostic.getColumnNumber()
+ ));
}
public int getErrorCount() {
@@ -871,6 +884,10 @@ public class JavaBuilder extends ModuleLevelBuilder {
public int getWarningCount() {
return myWarningCount;
}
+
+ public Collection<File> getFilesWithErrors() {
+ return myFilesWithErrors;
+ }
}
private class ClassProcessingConsumer implements OutputFileConsumer {
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildMessage.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildMessage.java
index 3fad1fbc699d..7e84cc88d808 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildMessage.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/messages/BuildMessage.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -20,7 +20,7 @@ package org.jetbrains.jps.incremental.messages;
* Date: 9/29/11
*/
public abstract class BuildMessage {
- public static enum Kind {
+ public enum Kind {
ERROR, WARNING, INFO, PROGRESS
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
index 522c66ad9360..3c9ac5b4e194 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java
@@ -16,6 +16,7 @@
package org.jetbrains.jps.incremental.storage;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
import com.intellij.openapi.util.io.FileUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -26,11 +27,14 @@ import org.jetbrains.jps.builders.java.dependencyView.Mappings;
import org.jetbrains.jps.builders.storage.BuildDataPaths;
import org.jetbrains.jps.builders.storage.SourceToOutputMapping;
import org.jetbrains.jps.builders.storage.StorageProvider;
+import org.jetbrains.jps.cmdline.BuildRunner;
+import org.jetbrains.jps.incremental.IncProjectBuilder;
import java.io.*;
import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
/**
* @author Eugene Zhuravlev
@@ -41,23 +45,81 @@ public class BuildDataManager implements StorageOwner {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_FORM_STORAGE = "src-form";
private static final String MAPPINGS_STORAGE = "mappings";
+ private static final int CONCURRENCY_LEVEL = BuildRunner.PARALLEL_BUILD_ENABLED? IncProjectBuilder.MAX_BUILDER_THREADS : 1;
- private final Object mySourceToOutputLock = new Object();
- private final Map<BuildTarget<?>, SourceToOutputMappingImpl> mySourceToOutputs = new HashMap<BuildTarget<?>, SourceToOutputMappingImpl>();
- private final Object myTargetStoragesLock = new Object();
- private final Map<BuildTarget<?>, BuildTargetStorages> myTargetStorages = new HashMap<BuildTarget<?>, BuildTargetStorages>();
- private StorageOwner myTargetStoragesOwner = new CompositeStorageOwner() {
- @Override
- protected Iterable<? extends StorageOwner> getChildStorages() {
- return myTargetStorages.values();
- }
- };
+ private final ConcurrentMap<BuildTarget<?>, AtomicNotNullLazyValue<SourceToOutputMappingImpl>> mySourceToOutputs =
+ new ConcurrentHashMap<BuildTarget<?>, AtomicNotNullLazyValue<SourceToOutputMappingImpl>>(16, 0.75f, CONCURRENCY_LEVEL);
+ private final ConcurrentMap<BuildTarget<?>, AtomicNotNullLazyValue<BuildTargetStorages>> myTargetStorages =
+ new ConcurrentHashMap<BuildTarget<?>, AtomicNotNullLazyValue<BuildTargetStorages>>(16, 0.75f, CONCURRENCY_LEVEL);
private final OneToManyPathsMapping mySrcToFormMap;
private final Mappings myMappings;
private final BuildDataPaths myDataPaths;
private final BuildTargetsState myTargetsState;
private final File myVersionFile;
+ private StorageOwner myTargetStoragesOwner = new CompositeStorageOwner() {
+ @Override
+ protected Iterable<? extends StorageOwner> getChildStorages() {
+ return new Iterable<StorageOwner>() {
+ @Override
+ public Iterator<StorageOwner> iterator() {
+ final Iterator<AtomicNotNullLazyValue<BuildTargetStorages>> iterator = myTargetStorages.values().iterator();
+ return new Iterator<StorageOwner>() {
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public StorageOwner next() {
+ return iterator.next().getValue();
+ }
+
+ @Override
+ public void remove() {
+ iterator.remove();
+ }
+ };
+ }
+ };
+ }
+ };
+
+
+ private interface LazyValueFactory<K, V> {
+ AtomicNotNullLazyValue<V> create(K key);
+ }
+
+ private LazyValueFactory<BuildTarget<?>,SourceToOutputMappingImpl> SOURCE_OUTPUT_MAPPING_VALUE_FACTORY = new LazyValueFactory<BuildTarget<?>, SourceToOutputMappingImpl>() {
+ @Override
+ public AtomicNotNullLazyValue<SourceToOutputMappingImpl> create(final BuildTarget<?> key) {
+ return new AtomicNotNullLazyValue<SourceToOutputMappingImpl>() {
+ @NotNull
+ @Override
+ protected SourceToOutputMappingImpl compute() {
+ try {
+ return new SourceToOutputMappingImpl(new File(getSourceToOutputMapRoot(key), "data"));
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+ };
+
+ private LazyValueFactory<BuildTarget<?>,BuildTargetStorages> TARGET_STORAGES_VALUE_FACTORY = new LazyValueFactory<BuildTarget<?>, BuildTargetStorages>() {
+ @Override
+ public AtomicNotNullLazyValue<BuildTargetStorages> create(final BuildTarget<?> target) {
+ return new AtomicNotNullLazyValue<BuildTargetStorages>() {
+ @NotNull
+ @Override
+ protected BuildTargetStorages compute() {
+ return new BuildTargetStorages(target, myDataPaths);
+ }
+ };
+ }
+ };
public BuildDataManager(final BuildDataPaths dataPaths, BuildTargetsState targetsState, final boolean useMemoryTempCaches) throws IOException {
myDataPaths = dataPaths;
@@ -68,31 +130,13 @@ public class BuildDataManager implements StorageOwner {
}
public SourceToOutputMapping getSourceToOutputMap(final BuildTarget<?> target) throws IOException {
- SourceToOutputMappingImpl mapping;
- synchronized (mySourceToOutputLock) {
- mapping = mySourceToOutputs.get(target);
- if (mapping == null) {
- mapping = new SourceToOutputMappingImpl(new File(getSourceToOutputMapRoot(target), "data"));
- mySourceToOutputs.put(target, mapping);
- }
- }
- return mapping;
- }
-
- private File getSourceToOutputMapRoot(BuildTarget<?> target) {
- return new File(myDataPaths.getTargetDataRoot(target), "src-out");
+ return fetchValue(mySourceToOutputs, target, SOURCE_OUTPUT_MAPPING_VALUE_FACTORY);
}
@NotNull
public <S extends StorageOwner> S getStorage(@NotNull BuildTarget<?> target, @NotNull StorageProvider<S> provider) throws IOException {
- synchronized (myTargetStoragesLock) {
- BuildTargetStorages storages = myTargetStorages.get(target);
- if (storages == null) {
- storages = new BuildTargetStorages(target, myDataPaths);
- myTargetStorages.put(target, storages);
- }
- return storages.getOrCreateStorage(provider);
- }
+ final BuildTargetStorages storages = fetchValue(myTargetStorages, target, TARGET_STORAGES_VALUE_FACTORY);
+ return storages.getOrCreateStorage(provider);
}
public OneToManyPathsMapping getSourceToFormMap() {
@@ -105,11 +149,9 @@ public class BuildDataManager implements StorageOwner {
public void cleanTargetStorages(BuildTarget<?> target) throws IOException {
try {
- synchronized (myTargetStoragesLock) {
- BuildTargetStorages storages = myTargetStorages.remove(target);
- if (storages != null) {
- storages.close();
- }
+ AtomicNotNullLazyValue<BuildTargetStorages> storages = myTargetStorages.remove(target);
+ if (storages != null) {
+ storages.getValue().close();
}
}
finally {
@@ -128,16 +170,12 @@ public class BuildDataManager implements StorageOwner {
public void clean() throws IOException {
try {
- synchronized (myTargetStoragesLock) {
- myTargetStoragesOwner.close();
- myTargetStorages.clear();
- }
+ myTargetStoragesOwner.close();
+ myTargetStorages.clear();
}
finally {
try {
- synchronized (mySourceToOutputLock) {
- closeSourceToOutputStorages();
- }
+ closeSourceToOutputStorages();
}
finally {
try {
@@ -161,13 +199,9 @@ public class BuildDataManager implements StorageOwner {
}
public void flush(boolean memoryCachesOnly) {
- synchronized (myTargetStoragesLock) {
- myTargetStoragesOwner.flush(memoryCachesOnly);
- }
- synchronized (mySourceToOutputLock) {
- for (SourceToOutputMappingImpl mapping : mySourceToOutputs.values()) {
- mapping.flush(memoryCachesOnly);
- }
+ myTargetStoragesOwner.flush(memoryCachesOnly);
+ for (AtomicNotNullLazyValue<SourceToOutputMappingImpl> mapping : mySourceToOutputs.values()) {
+ mapping.getValue().flush(memoryCachesOnly);
}
mySrcToFormMap.flush(memoryCachesOnly);
final Mappings mappings = myMappings;
@@ -181,20 +215,16 @@ public class BuildDataManager implements StorageOwner {
public void close() throws IOException {
try {
myTargetsState.save();
- synchronized (myTargetStoragesLock) {
- try {
- myTargetStoragesOwner.close();
- }
- finally {
- myTargetStorages.clear();
- }
+ try {
+ myTargetStoragesOwner.close();
+ }
+ finally {
+ myTargetStorages.clear();
}
}
finally {
try {
- synchronized (mySourceToOutputLock) {
- closeSourceToOutputStorages();
- }
+ closeSourceToOutputStorages();
}
finally {
try {
@@ -220,13 +250,11 @@ public class BuildDataManager implements StorageOwner {
}
public void closeSourceToOutputStorages(Collection<BuildTargetChunk> chunks) throws IOException {
- synchronized (mySourceToOutputLock) {
- for (BuildTargetChunk chunk : chunks) {
- for (BuildTarget<?> target : chunk.getTargets()) {
- final SourceToOutputMappingImpl mapping = mySourceToOutputs.remove(target);
- if (mapping != null) {
- mapping.close();
- }
+ for (BuildTargetChunk chunk : chunks) {
+ for (BuildTarget<?> target : chunk.getTargets()) {
+ final AtomicNotNullLazyValue<SourceToOutputMappingImpl> mapping = mySourceToOutputs.remove(target);
+ if (mapping != null) {
+ mapping.getValue().close();
}
}
}
@@ -235,12 +263,12 @@ public class BuildDataManager implements StorageOwner {
private void closeSourceToOutputStorages() throws IOException {
IOException ex = null;
try {
- for (SourceToOutputMappingImpl mapping : mySourceToOutputs.values()) {
+ for (AtomicNotNullLazyValue<SourceToOutputMappingImpl> mapping : mySourceToOutputs.values()) {
try {
- mapping.close();
+ mapping.getValue().close();
}
catch (IOException e) {
- if (e != null) {
+ if (ex == null) {
ex = e;
}
}
@@ -254,6 +282,31 @@ public class BuildDataManager implements StorageOwner {
}
}
+ private static <K, V> V fetchValue(ConcurrentMap<K, AtomicNotNullLazyValue<V>> container, K key, final LazyValueFactory<K, V> valueFactory) throws IOException {
+ AtomicNotNullLazyValue<V> lazy = container.get(key);
+ if (lazy == null) {
+ final AtomicNotNullLazyValue<V> newValue = valueFactory.create(key);
+ lazy = container.putIfAbsent(key, newValue);
+ if (lazy == null) {
+ lazy = newValue; // just initialized
+ }
+ }
+ try {
+ return lazy.getValue();
+ }
+ catch (RuntimeException e) {
+ final Throwable cause = e.getCause();
+ if (cause instanceof IOException) {
+ throw (IOException)cause;
+ }
+ throw e;
+ }
+ }
+
+ private File getSourceToOutputMapRoot(BuildTarget<?> target) {
+ return new File(myDataPaths.getTargetDataRoot(target), "src-out");
+ }
+
private File getSourceToFormsRoot() {
return new File(myDataPaths.getDataStorageRoot(), SRC_TO_FORM_STORAGE);
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/DiagnosticOutputConsumer.java b/jps/jps-builders/src/org/jetbrains/jps/javac/DiagnosticOutputConsumer.java
index ee4269248c14..b24a8325bb65 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/DiagnosticOutputConsumer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/DiagnosticOutputConsumer.java
@@ -16,6 +16,7 @@
package org.jetbrains.jps.javac;
import javax.tools.*;
+import java.io.File;
import java.util.Collection;
/**
@@ -25,4 +26,5 @@ import java.util.Collection;
public interface DiagnosticOutputConsumer extends DiagnosticListener<JavaFileObject> {
void outputLineAvailable(String line);
void registerImports(String className, Collection<String> imports, Collection<String> staticImports);
+ void javaFileLoaded(File file);
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java
index 03b9d4170aa8..ede1a7746cbd 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacFileManager.java
@@ -61,6 +61,14 @@ class JavacFileManager extends ForwardingJavaFileManager<StandardJavaFileManager
myOutputsMap = outputDirToSrcRoots;
}
+ @Override
+ public String inferBinaryName(Location location, JavaFileObject file) {
+ return super.inferBinaryName(
+ location,
+ file instanceof TransformableJavaFileObject? ((TransformableJavaFileObject)file).getOriginal() : file
+ );
+ }
+
public void setLocation(Location location, Iterable<? extends File> path) throws IOException{
getStdManager().setLocation(location, path);
}
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 33e04756db22..fdf99efcd70f 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java
@@ -16,6 +16,7 @@
package org.jetbrains.jps.javac;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.api.CanceledStatus;
import org.jetbrains.jps.builders.java.JavaSourceTransformer;
@@ -50,7 +51,7 @@ public class JavacMain {
Collection<File> platformClasspath,
Collection<File> sourcePath,
Map<File, Set<File>> outputDirToRoots,
- final DiagnosticOutputConsumer outConsumer,
+ final DiagnosticOutputConsumer diagnosticConsumer,
final OutputFileConsumer outputSink,
CanceledStatus canceledStatus, boolean useEclipseCompiler) {
JavaCompiler compiler = null;
@@ -60,7 +61,7 @@ public class JavacMain {
break;
}
if (compiler == null) {
- outConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, "Eclipse Batch Compiler was not found in classpath"));
+ diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, "Eclipse Batch Compiler was not found in classpath"));
return false;
}
}
@@ -69,7 +70,7 @@ public class JavacMain {
if (compiler == null) {
compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
- outConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, "System Java Compiler was not found in classpath"));
+ diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, "System Java Compiler was not found in classpath"));
return false;
}
nowUsingJavac = true;
@@ -84,7 +85,7 @@ public class JavacMain {
final List<JavaSourceTransformer> transformers = getSourceTransformers();
- final JavacFileManager fileManager = new JavacFileManager(new ContextImpl(compiler, outConsumer, outputSink, canceledStatus, nowUsingJavac), transformers);
+ final JavacFileManager fileManager = new JavacFileManager(new ContextImpl(compiler, diagnosticConsumer, outputSink, canceledStatus, nowUsingJavac), transformers);
fileManager.handleOption("-bootclasspath", Collections.singleton("").iterator()); // this will clear cached stuff
fileManager.handleOption("-extdirs", Collections.singleton("").iterator()); // this will clear cached stuff
@@ -136,7 +137,7 @@ public class JavacMain {
final LineOutputWriter out = new LineOutputWriter() {
protected void lineAvailable(String line) {
if (nowUsingJavac) {
- outConsumer.outputLineAvailable(line);
+ diagnosticConsumer.outputLineAvailable(line);
}
else {
// todo: filter too verbose eclipse output?
@@ -154,7 +155,7 @@ public class JavacMain {
}
final JavaCompiler.CompilationTask task = compiler.getTask(
- out, fileManager, outConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources)
+ out, fileManager, diagnosticConsumer, _options, null, fileManager.getJavaFileObjectsFromFiles(sources)
);
//if (!IS_VM_6_VERSION) { //todo!
@@ -166,10 +167,10 @@ public class JavacMain {
return task.call();
}
catch(IllegalArgumentException e) {
- outConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, e.getMessage()));
+ diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, e.getMessage()));
}
catch (CompilationCanceledException ignored) {
- outConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.OTHER, "Compilation was canceled"));
+ diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.OTHER, "Compilation was canceled"));
}
finally {
fileManager.close();
@@ -183,7 +184,7 @@ public class JavacMain {
private static List<JavaSourceTransformer> getSourceTransformers() {
final Class<JavaSourceTransformer> transformerClass = JavaSourceTransformer.class;
final ServiceLoader<JavaSourceTransformer> loader = ServiceLoader.load(transformerClass, transformerClass.getClassLoader());
- final List<JavaSourceTransformer> transformers = new ArrayList<JavaSourceTransformer>();
+ final List<JavaSourceTransformer> transformers = new SmartList<JavaSourceTransformer>();
for (JavaSourceTransformer t : loader) {
transformers.add(t);
}
@@ -211,7 +212,6 @@ public class JavacMain {
private static Collection<String> prepareOptions(final Collection<String> options, boolean usingJavac) {
final List<String> result = new ArrayList<String>();
if (usingJavac) {
- result.add("-Xprefer:source");
result.add("-implicit:class"); // the option supported by javac only
}
else { // is Eclipse
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java
index 23d0756b8274..7feb5b896401 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacProtoUtil.java
@@ -101,6 +101,17 @@ public class JavacProtoUtil {
return builder.build();
}
+ public static JavacRemoteProto.Message.Response createSourceFileLoadedResponse(File srcFile) {
+
+ final JavacRemoteProto.Message.Response.OutputObject outObjMsg = JavacRemoteProto.Message.Response.OutputObject.newBuilder()
+ .setKind(convertKind(JavaFileObject.Kind.SOURCE)).setFilePath(FileUtil.toSystemIndependentName(srcFile.getPath())).build();
+
+ final JavacRemoteProto.Message.Response.Builder builder = JavacRemoteProto.Message.Response.newBuilder();
+ builder.setResponseType(JavacRemoteProto.Message.Response.Type.SRC_FILE_LOADED).setOutputObject(outObjMsg);
+
+ return builder.build();
+ }
+
public static JavacRemoteProto.Message.Response createClassDataResponse(String className, Collection<String> imports, Collection<String> staticImports) {
final JavacRemoteProto.Message.Response.ClassData.Builder msgBuilder = JavacRemoteProto.Message.Response.ClassData.newBuilder();
msgBuilder.setClassName(className);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java
index 87317f2758a6..e16704d6a629 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacRemoteProto.java
@@ -3694,6 +3694,10 @@ public final class JavacRemoteProto {
* <code>REQUEST_ACK = 5;</code>
*/
REQUEST_ACK(4, 5),
+ /**
+ * <code>SRC_FILE_LOADED = 6;</code>
+ */
+ SRC_FILE_LOADED(5, 6),
;
/**
@@ -3716,6 +3720,10 @@ public final class JavacRemoteProto {
* <code>REQUEST_ACK = 5;</code>
*/
public static final int REQUEST_ACK_VALUE = 5;
+ /**
+ * <code>SRC_FILE_LOADED = 6;</code>
+ */
+ public static final int SRC_FILE_LOADED_VALUE = 6;
public final int getNumber() { return value; }
@@ -3727,6 +3735,7 @@ public final class JavacRemoteProto {
case 3: return CLASS_DATA;
case 4: return BUILD_COMPLETED;
case 5: return REQUEST_ACK;
+ case 6: return SRC_FILE_LOADED;
default: return null;
}
}
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 359e151fd333..76a6fe9b46d5 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServer.java
@@ -127,6 +127,11 @@ public class JavacServer {
Map<File, Set<File>> outs,
final CanceledStatus canceledStatus) {
final DiagnosticOutputConsumer diagnostic = new DiagnosticOutputConsumer() {
+ @Override
+ public void javaFileLoaded(File file) {
+ Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createSourceFileLoadedResponse(file)));
+ }
+
public void outputLineAvailable(String line) {
Channels.write(ctx.getChannel(), JavacProtoUtil.toMessage(sessionId, JavacProtoUtil.createStdOutputResponse(line)));
}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerResponseHandler.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerResponseHandler.java
index a9d2173f29f1..6f06bcae29b6 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerResponseHandler.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacServerResponseHandler.java
@@ -99,6 +99,13 @@ public class JavacServerResponseHandler implements ProtobufResponseHandler{
myOutputSink.save(fileObject);
return false;
}
+
+ if (responseType == JavacRemoteProto.Message.Response.Type.SRC_FILE_LOADED) {
+ final JavacRemoteProto.Message.Response.OutputObject outputObject = response.getOutputObject();
+ final File file = new File(outputObject.getFilePath());
+ myDiagnosticSink.javaFileLoaded(file);
+ return false;
+ }
if (responseType == JavacRemoteProto.Message.Response.Type.CLASS_DATA) {
final JavacRemoteProto.Message.Response.ClassData data = response.getClassData();
diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/TransformableJavaFileObject.java b/jps/jps-builders/src/org/jetbrains/jps/javac/TransformableJavaFileObject.java
index 673b6e376e45..e44aa5ff5edc 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/javac/TransformableJavaFileObject.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/javac/TransformableJavaFileObject.java
@@ -38,6 +38,10 @@ public class TransformableJavaFileObject implements JavaFileObject {
myTransformers = transformers;
}
+ public JavaFileObject getOriginal() {
+ return myOriginal;
+ }
+
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
// todo: cache transformed content?
@@ -108,4 +112,10 @@ public class TransformableJavaFileObject implements JavaFileObject {
public boolean delete() {
return myOriginal.delete();
}
+
+ @Override
+ public final String toString() {
+ // must implement like this because toString() is called inside com.sun.tools.javac.jvm.ClassWriter instead of getName()
+ return getName();
+ }
}
diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/MarkDirtyTest.java b/jps/jps-builders/testSrc/org/jetbrains/ether/MarkDirtyTest.java
index 6e605db97203..4fe9694cf447 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/ether/MarkDirtyTest.java
+++ b/jps/jps-builders/testSrc/org/jetbrains/ether/MarkDirtyTest.java
@@ -54,6 +54,6 @@ public class MarkDirtyTest extends IncrementalTestCase {
}
public void testRecompileTwinDependencies() {
- doTest().assertSuccessful();
+ doTest().assertFailed();
}
}
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.java b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.java
index 0df6ded1041b..1dc08ba8d8ce 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.java
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/BuildResult.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -24,7 +24,6 @@ import org.jetbrains.jps.incremental.messages.BuildMessage;
import org.jetbrains.jps.incremental.messages.DoneSomethingNotification;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
/**
@@ -78,12 +77,9 @@ public class BuildResult implements MessageHandler {
}
@NotNull
- public List<BuildMessage> getErrorMessages() {
- return Collections.unmodifiableList(myErrorMessages);
- }
-
- @NotNull
- public List<BuildMessage> getWarnMessages() {
- return myWarnMessages;
+ public List<BuildMessage> getMessages(@NotNull BuildMessage.Kind kind) {
+ if (kind == BuildMessage.Kind.ERROR) return myErrorMessages;
+ else if (kind == BuildMessage.Kind.WARNING) return myWarnMessages;
+ else return myInfoMessages;
}
}
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 0d1c0afa6d56..73f1e3ebe1e0 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/CompileScopeTestBuilder.java
@@ -26,10 +26,7 @@ import org.jetbrains.jps.model.artifact.JpsArtifact;
import org.jetbrains.jps.model.module.JpsModule;
import java.io.File;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.*;
/**
* @author nik
@@ -76,6 +73,11 @@ public class CompileScopeTestBuilder {
return this;
}
+ public CompileScopeTestBuilder targetTypes(BuildTargetType<?>... targets) {
+ myTargetTypes.addAll(Arrays.asList(targets));
+ return this;
+ }
+
public CompileScope build() {
Collection<BuildTargetType<?>> typesToForceBuild = myForceBuild ? myTargetTypes : Collections.<BuildTargetType<?>>emptyList();
return new CompileScopeImpl(myTargetTypes, typesToForceBuild, myTargets, Collections.<BuildTarget<?>,Set<File>>emptyMap());
diff --git a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
index 5e353c9315c8..6241b04e84d2 100644
--- a/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
+++ b/jps/jps-builders/testSrc/org/jetbrains/jps/builders/JpsBuildTestCase.java
@@ -290,7 +290,7 @@ public abstract class JpsBuildTestCase extends UsefulTestCase {
}
protected BuildResult doBuild(final ProjectDescriptor descriptor, CompileScopeTestBuilder scopeBuilder) {
- IncProjectBuilder builder = new IncProjectBuilder(descriptor, BuilderRegistry.getInstance(), myBuildParams, CanceledStatus.NULL, null);
+ IncProjectBuilder builder = new IncProjectBuilder(descriptor, BuilderRegistry.getInstance(), myBuildParams, CanceledStatus.NULL, null, true);
BuildResult result = new BuildResult();
builder.addMessageHandler(result);
try {
diff --git a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
index c0484d6299fa..05dc780d2e07 100644
--- a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
+++ b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
@@ -22,6 +22,7 @@ import org.jdom.Attribute;
import org.jdom.Comment;
import org.jdom.Element;
import org.jdom.Text;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -36,11 +37,11 @@ public abstract class PathMacroMap {
public abstract String substitute(String text, boolean caseSensitive);
- public final void substitute(Element e, boolean caseSensitive) {
+ public final void substitute(@NotNull Element e, boolean caseSensitive) {
substitute(e, caseSensitive, false);
}
- public final void substitute(Element e, boolean caseSensitive, final boolean recursively,
+ public final void substitute(@NotNull Element e, boolean caseSensitive, final boolean recursively,
@Nullable PathMacroFilter filter) {
List content = e.getContent();
//noinspection ForLoopReplaceableByForEach
@@ -77,7 +78,7 @@ public abstract class PathMacroMap {
}
}
- public final void substitute(Element e, boolean caseSensitive, final boolean recursively) {
+ public final void substitute(@NotNull Element e, boolean caseSensitive, final boolean recursively) {
substitute(e, caseSensitive, recursively, null);
}