diff options
author | Tor Norbye <tnorbye@google.com> | 2013-07-08 11:26:24 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2013-07-08 11:26:24 -0700 |
commit | c1ace1f7e1e49c81bb4b75377c99f07be340abfe (patch) | |
tree | 9d0db96bd3d86ddfec80e7e3554cad9dcc066553 /jps | |
parent | c6218e46d5d2017e987ecdbd99b318a95c42abc0 (diff) | |
download | idea-c1ace1f7e1e49c81bb4b75377c99f07be340abfe.tar.gz |
Snapshot aea001abfc1b38fec3a821bcd5174cc77dc75787 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: Icdea2a2bd7ad43b4d05967b1f0479db3bda1c93c
Diffstat (limited to 'jps')
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); } |