diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index af2a19460731..2ea7c9bc8117 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -90,11 +90,6 @@
-
-
-
-
-
@@ -185,6 +180,13 @@
+
+
+
+
+
+
+
diff --git a/.idea/libraries/Netty.xml b/.idea/libraries/Netty.xml
index 9ebc1a1f2323..0d0f840e2724 100644
--- a/.idea/libraries/Netty.xml
+++ b/.idea/libraries/Netty.xml
@@ -1,11 +1,11 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Snappy_Java.xml b/.idea/libraries/Snappy_Java.xml
index 85b426fb3a0c..79efa842173c 100644
--- a/.idea/libraries/Snappy_Java.xml
+++ b/.idea/libraries/Snappy_Java.xml
@@ -1,14 +1,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 8720385396a2..d943f90d0368 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -56,6 +56,7 @@
+
diff --git a/RegExpSupport/test/test/MainParseTest.java b/RegExpSupport/test/test/MainParseTest.java
index 8f46144f6767..0c41b1e37653 100644
--- a/RegExpSupport/test/test/MainParseTest.java
+++ b/RegExpSupport/test/test/MainParseTest.java
@@ -1,220 +1,220 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package test;
-
-import org.intellij.lang.regexp.RegExpFileType;
-import org.jdom.Document;
-import org.jdom.Element;
-import org.jdom.input.SAXBuilder;
-import org.jdom.xpath.XPath;
-
-import java.io.*;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-public class MainParseTest extends BaseParseTestcase {
-
- private ByteArrayOutputStream myOut;
-
- enum Result {
- OK, ERR
- }
-
- static class Test {
- String pattern;
- boolean showWarnings = true;
- boolean showInfo = false;
- Result expectedResult;
-
- Test(String pattern, Result result, boolean warn, boolean info) {
- this.pattern = pattern;
- expectedResult = result;
- showWarnings = warn;
- showInfo = info;
- }
- }
-
- private final Map myMap = new LinkedHashMap();
-
- @Override
- protected void setUp() throws Exception {
- final Document document = new SAXBuilder().build(new File(getTestDataRoot(), "/RETest.xml"));
- final List list = XPath.selectNodes(document.getRootElement(), "//test");
-
- int i = 0;
- for (Element element : list) {
- final String name;
- final Element parent = (Element)element.getParent();
- final String s = parent.getName();
- final String t = parent.getAttribute("id") == null ? "" : parent.getAttribute("id").getValue() + "-";
- if (!"tests".equals(s)) {
- name = s + "/test-" + t + ++i + ".regexp";
- }
- else {
- name = "test-" + t + ++i + ".regexp";
- }
- final Result result = Result.valueOf((String)XPath.selectSingleNode(element, "string(expected)"));
- final boolean warn = !"false".equals(element.getAttributeValue("warning"));
- final boolean info = "true".equals(element.getAttributeValue("info"));
-
- final String pattern = (String)XPath.selectSingleNode(element, "string(pattern)");
- myMap.put(name, new Test(pattern, result, warn, info));
- if (!"false".equals(element.getAttributeValue("verify"))) {
- try {
- Pattern.compile(pattern);
- if (result == Result.ERR) {
- System.out.println("Incorrect FAIL value for " + pattern);
- }
- }
- catch (PatternSyntaxException e) {
- if (result == Result.OK) {
- System.out.println("Incorrect OK value for " + pattern);
- }
- }
- }
- }
-
- super.setUp();
-
- myOut = new ByteArrayOutputStream();
- System.setErr(new PrintStream(myOut));
- }
-
- @Override
- protected String getTestDataPath() {
- return super.getTestDataPath() + "/gen/";
- }
-
- public void testSimple() throws Exception {
- doTest("simple/");
- }
-
- public void testQuantifiers() throws Exception {
- doTest("quantifiers/");
- }
-
- public void testGroups() throws Exception {
- doTest("groups/");
- }
-
- public void testCharclasses() throws Exception {
- doTest("charclasses/");
- }
-
- public void testEscapes() throws Exception {
- doTest("escapes/");
- }
-
- public void testAnchors() throws Exception {
- doTest("anchors/");
- }
-
- public void testNamedchars() throws Exception {
- doTest("namedchars/");
- }
-
- public void testBackrefs() throws Exception {
- doTest("backrefs/");
- }
-
- public void testComplex() throws Exception {
- doTest("complex/");
- }
-
- public void testIncomplete() throws Exception {
- doTest("incomplete/");
- }
-
- public void testRealLife() throws Exception {
- doTest("real-life/");
- }
-
- public void testRegressions() throws Exception {
- doTest("regressions/");
- }
-
- public void testBugs() throws Exception {
- doTest("bug/");
- }
-
- public void testFromXML() throws Exception {
- doTest(null);
- }
-
- private void doTest(String prefix) throws IOException {
- int n = 0;
- int failed = 0;
- for (String name : myMap.keySet()) {
- if (prefix == null && name.contains("/")) {
- continue;
- }
- if (prefix != null && !name.startsWith(prefix)) {
- continue;
- }
- System.out.print("filename = " + name);
- n++;
-
- final MainParseTest.Test test = myMap.get(name);
- try {
- myFixture.configureByText(RegExpFileType.INSTANCE, test.pattern);
- myFixture.testHighlighting(test.showWarnings, true, test.showInfo);
-
- if (test.expectedResult == Result.ERR) {
- System.out.println(" FAILED. Expression incorrectly parsed OK: " + test.pattern);
- failed++;
- }
- else {
- System.out.println(" OK");
- }
- }
- catch (Throwable e) {
- if (test.expectedResult == Result.ERR) {
- System.out.println(" OK");
- }
- else {
- e.printStackTrace();
- System.out.println(" FAILED. Expression = " + test.pattern);
- if (myOut.size() > 0) {
- String line;
- final BufferedReader reader = new BufferedReader(new StringReader(myOut.toString()));
- do {
- line = reader.readLine();
- }
- while (line != null && (line.trim().length() == 0 || line.trim().equals("ERROR:")));
- if (line != null) {
- if (line.matches(".*java.lang.Error: junit.framework.AssertionFailedError:.*")) {
- System.out.println("ERROR: " + line.replace("java.lang.Error: junit.framework.AssertionFailedError:", ""));
- }
- }
- else {
- System.out.println("ERROR: " + myOut.toString());
- }
- }
- failed++;
- }
- }
- myOut.reset();
- }
-
- System.out.println("");
- System.out.println(n + " Tests executed, " + failed + " failed");
-
- assertFalse(failed > 0);
- }
-}
+/*
+ * Copyright 2006 Sascha Weinreuter
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package test;
+
+import org.intellij.lang.regexp.RegExpFileType;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+import org.jdom.xpath.XPath;
+
+import java.io.*;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+public class MainParseTest extends BaseParseTestcase {
+
+ private ByteArrayOutputStream myOut;
+
+ enum Result {
+ OK, ERR
+ }
+
+ static class Test {
+ String pattern;
+ boolean showWarnings = true;
+ boolean showInfo = false;
+ Result expectedResult;
+
+ Test(String pattern, Result result, boolean warn, boolean info) {
+ this.pattern = pattern;
+ expectedResult = result;
+ showWarnings = warn;
+ showInfo = info;
+ }
+ }
+
+ private final Map myMap = new LinkedHashMap();
+
+ @Override
+ protected void setUp() throws Exception {
+ final Document document = new SAXBuilder().build(new File(getTestDataRoot(), "/RETest.xml"));
+ final List list = XPath.selectNodes(document.getRootElement(), "//test");
+
+ int i = 0;
+ for (Element element : list) {
+ final String name;
+ final Element parent = (Element)element.getParent();
+ final String s = parent.getName();
+ final String t = parent.getAttribute("id") == null ? "" : parent.getAttribute("id").getValue() + "-";
+ if (!"tests".equals(s)) {
+ name = s + "/test-" + t + ++i + ".regexp";
+ }
+ else {
+ name = "test-" + t + ++i + ".regexp";
+ }
+ final Result result = Result.valueOf((String)XPath.selectSingleNode(element, "string(expected)"));
+ final boolean warn = !"false".equals(element.getAttributeValue("warning"));
+ final boolean info = "true".equals(element.getAttributeValue("info"));
+
+ final String pattern = (String)XPath.selectSingleNode(element, "string(pattern)");
+ myMap.put(name, new Test(pattern, result, warn, info));
+ if (!"false".equals(element.getAttributeValue("verify"))) {
+ try {
+ Pattern.compile(pattern);
+ if (result == Result.ERR) {
+ System.out.println("Incorrect FAIL value for " + pattern);
+ }
+ }
+ catch (PatternSyntaxException e) {
+ if (result == Result.OK) {
+ System.out.println("Incorrect OK value for " + pattern);
+ }
+ }
+ }
+ }
+
+ super.setUp();
+
+ myOut = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(myOut));
+ }
+
+ @Override
+ protected String getTestDataPath() {
+ return super.getTestDataPath() + "/gen/";
+ }
+
+ public void testSimple() throws Exception {
+ doTest("simple/");
+ }
+
+ public void testQuantifiers() throws Exception {
+ doTest("quantifiers/");
+ }
+
+ public void testGroups() throws Exception {
+ doTest("groups/");
+ }
+
+ public void testCharclasses() throws Exception {
+ doTest("charclasses/");
+ }
+
+ public void testEscapes() throws Exception {
+ doTest("escapes/");
+ }
+
+ public void testAnchors() throws Exception {
+ doTest("anchors/");
+ }
+
+ public void testNamedchars() throws Exception {
+ doTest("namedchars/");
+ }
+
+ public void testBackrefs() throws Exception {
+ doTest("backrefs/");
+ }
+
+ public void testComplex() throws Exception {
+ doTest("complex/");
+ }
+
+ public void testIncomplete() throws Exception {
+ doTest("incomplete/");
+ }
+
+ public void testRealLife() throws Exception {
+ doTest("real-life/");
+ }
+
+ public void testRegressions() throws Exception {
+ doTest("regressions/");
+ }
+
+ public void testBugs() throws Exception {
+ doTest("bug/");
+ }
+
+ public void testFromXML() throws Exception {
+ doTest(null);
+ }
+
+ private void doTest(String prefix) throws IOException {
+ int n = 0;
+ int failed = 0;
+ for (String name : myMap.keySet()) {
+ if (prefix == null && name.contains("/")) {
+ continue;
+ }
+ if (prefix != null && !name.startsWith(prefix)) {
+ continue;
+ }
+ System.out.print("filename = " + name);
+ n++;
+
+ final MainParseTest.Test test = myMap.get(name);
+ try {
+ myFixture.configureByText(RegExpFileType.INSTANCE, test.pattern);
+ myFixture.testHighlighting(test.showWarnings, true, test.showInfo);
+
+ if (test.expectedResult == Result.ERR) {
+ System.out.println(" FAILED. Expression incorrectly parsed OK: " + test.pattern);
+ failed++;
+ }
+ else {
+ System.out.println(" OK");
+ }
+ }
+ catch (Throwable e) {
+ if (test.expectedResult == Result.ERR) {
+ System.out.println(" OK");
+ }
+ else {
+ e.printStackTrace();
+ System.out.println(" FAILED. Expression = " + test.pattern);
+ if (myOut.size() > 0) {
+ String line;
+ final BufferedReader reader = new BufferedReader(new StringReader(myOut.toString()));
+ do {
+ line = reader.readLine();
+ }
+ while (line != null && (line.trim().length() == 0 || line.trim().equals("ERROR:")));
+ if (line != null) {
+ if (line.matches(".*java.lang.Error: junit.framework.AssertionFailedError:.*")) {
+ System.out.println("ERROR: " + line.replace("java.lang.Error: junit.framework.AssertionFailedError:", ""));
+ }
+ }
+ else {
+ System.out.println("ERROR: " + myOut.toString());
+ }
+ }
+ failed++;
+ }
+ }
+ myOut.reset();
+ }
+
+ System.out.println("");
+ System.out.println(n + " Tests executed, " + failed + " failed");
+
+ assertFalse(failed > 0);
+ }
+}
diff --git a/build.txt b/build.txt
index 2b466995ac79..c867e1275895 100644
--- a/build.txt
+++ b/build.txt
@@ -1 +1 @@
-120.SNAPSHOT
+120.SNAPSHOT
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index 1d802d4255f5..11de4164c82b 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -49,7 +49,7 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir
//noinspection GroovyAssignabilityCheck
List openapiModules = [platformApiModules,
- "java-psi-api", "openapi", "testFramework-java", "debugger-openapi", "compiler-openapi", "dom-openapi", "execution-openapi",
+ "java-psi-api", "java-indexing-api", "openapi", "testFramework-java", "debugger-openapi", "compiler-openapi", "dom-openapi", "execution-openapi",
"jsp-openapi", "jsp-base-openapi"].flatten()
//noinspection GroovyAssignabilityCheck
@@ -534,6 +534,7 @@ def layout_core_upsource(String home, String target) {
module("java-psi-impl")
module("projectModel-api")
module("projectModel-impl")
+ module("java-indexing-api")
module("java-indexing-impl")
module("platform-resources")
module("platform-resources-en")
diff --git a/images/src/META-INF/ImagesPlugin.xml b/images/src/META-INF/ImagesPlugin.xml
index 6ebe49b4b110..dab33be1048e 100644
--- a/images/src/META-INF/ImagesPlugin.xml
+++ b/images/src/META-INF/ImagesPlugin.xml
@@ -1,139 +1,139 @@
-
-
- Alexey Efimov
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- org.intellij.images.fileTypes.ImageFileTypeManager
- org.intellij.images.fileTypes.impl.ImageFileTypeManagerImpl
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ Alexey Efimov
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.intellij.images.fileTypes.ImageFileTypeManager
+ org.intellij.images.fileTypes.impl.ImageFileTypeManagerImpl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index 5d13be23f351..54ff62601367 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -1,2868 +1,2868 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author: Eugene Zhuravlev
- * Date: Jan 17, 2003
- * Time: 1:42:26 PM
- */
-package com.intellij.compiler.impl;
-
-import com.intellij.CommonBundle;
-import com.intellij.compiler.*;
-import com.intellij.compiler.make.CacheCorruptedException;
-import com.intellij.compiler.make.CacheUtils;
-import com.intellij.compiler.make.ChangedConstantsDependencyProcessor;
-import com.intellij.compiler.make.DependencyCache;
-import com.intellij.compiler.progress.CompilerTask;
-import com.intellij.compiler.server.BuildManager;
-import com.intellij.compiler.server.DefaultMessageHandler;
-import com.intellij.diagnostic.IdeErrorsDialog;
-import com.intellij.diagnostic.PluginException;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ModalityState;
-import com.intellij.openapi.application.Result;
-import com.intellij.openapi.application.WriteAction;
-import com.intellij.openapi.compiler.*;
-import com.intellij.openapi.compiler.Compiler;
-import com.intellij.openapi.compiler.ex.CompileContextEx;
-import com.intellij.openapi.compiler.ex.CompilerPathsEx;
-import com.intellij.openapi.compiler.generic.GenericCompiler;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.extensions.PluginId;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.module.LanguageLevelUtil;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.progress.ProcessCanceledException;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.project.DumbService;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.project.ProjectBundle;
-import com.intellij.openapi.projectRoots.Sdk;
-import com.intellij.openapi.roots.*;
-import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
-import com.intellij.openapi.roots.ui.configuration.CommonContentEntriesEditor;
-import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
-import com.intellij.openapi.ui.MessageType;
-import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.*;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.registry.Registry;
-import com.intellij.openapi.vfs.*;
-import com.intellij.openapi.vfs.newvfs.ManagingFS;
-import com.intellij.openapi.vfs.newvfs.RefreshQueue;
-import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
-import com.intellij.openapi.wm.StatusBar;
-import com.intellij.openapi.wm.ToolWindowId;
-import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.openapi.wm.WindowManager;
-import com.intellij.packaging.artifacts.Artifact;
-import com.intellij.packaging.artifacts.ArtifactManager;
-import com.intellij.packaging.impl.artifacts.ArtifactImpl;
-import com.intellij.packaging.impl.artifacts.ArtifactUtil;
-import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
-import com.intellij.packaging.impl.compiler.ArtifactCompilerUtil;
-import com.intellij.pom.java.LanguageLevel;
-import com.intellij.psi.PsiDocumentManager;
-import com.intellij.util.Chunk;
-import com.intellij.util.Function;
-import com.intellij.util.StringBuilderSpinAllocator;
-import com.intellij.util.ThrowableRunnable;
-import com.intellij.util.concurrency.Semaphore;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.HashMap;
-import com.intellij.util.containers.MultiMap;
-import com.intellij.util.containers.OrderedSet;
-import com.intellij.util.messages.MessageBus;
-import gnu.trove.TIntHashSet;
-import gnu.trove.TObjectHashingStrategy;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jps.api.CmdlineRemoteProto;
-import org.jetbrains.jps.api.JpsRemoteProto;
-import org.jetbrains.jps.api.JpsServerResponseHandler;
-import org.jetbrains.jps.api.RequestFuture;
-
-import javax.swing.*;
-import java.io.*;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
-public class CompileDriver {
-
- private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileDriver");
- // to be used in tests only for debug output
- public static volatile boolean ourDebugMode = false;
-
- private final Project myProject;
- private final Map, Pair> myGenerationCompilerModuleToOutputDirMap; // [IntermediateOutputCompiler, Module] -> [ProductionSources, TestSources]
- private final String myCachesDirectoryPath;
- private boolean myShouldClearOutputDirectory;
-
- private final Map myModuleOutputPaths = new HashMap();
- private final Map myModuleTestOutputPaths = new HashMap();
-
- @NonNls private static final String VERSION_FILE_NAME = "version.dat";
- @NonNls private static final String LOCK_FILE_NAME = "in_progress.dat";
-
- private static final boolean GENERATE_CLASSPATH_INDEX = "true".equals(System.getProperty("generate.classpath.index"));
- private static final String PROP_PERFORM_INITIAL_REFRESH = "compiler.perform.outputs.refresh.on.start";
- private static final Key REFRESH_DONE_KEY = Key.create("_compiler.initial.refresh.done_");
-
- private static final FileProcessingCompilerAdapterFactory FILE_PROCESSING_COMPILER_ADAPTER_FACTORY = new FileProcessingCompilerAdapterFactory() {
- public FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler) {
- return new FileProcessingCompilerAdapter(context, compiler);
- }
- };
- private static final FileProcessingCompilerAdapterFactory FILE_PACKAGING_COMPILER_ADAPTER_FACTORY = new FileProcessingCompilerAdapterFactory() {
- public FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler) {
- return new PackagingCompilerAdapter(context, (PackagingCompiler)compiler);
- }
- };
- private CompilerFilter myCompilerFilter = CompilerFilter.ALL;
- private static final CompilerFilter SOURCE_PROCESSING_ONLY = new CompilerFilter() {
- public boolean acceptCompiler(Compiler compiler) {
- return compiler instanceof SourceProcessingCompiler;
- }
- };
- private static final CompilerFilter ALL_EXCEPT_SOURCE_PROCESSING = new CompilerFilter() {
- public boolean acceptCompiler(Compiler compiler) {
- return !SOURCE_PROCESSING_ONLY.acceptCompiler(compiler);
- }
- };
-
- private Set myAllOutputDirectories;
- private static final long ONE_MINUTE_MS = 60L /*sec*/ * 1000L /*millisec*/;
-
- public CompileDriver(Project project) {
- myProject = project;
- myCachesDirectoryPath = CompilerPaths.getCacheStoreDirectory(myProject).getPath().replace('/', File.separatorChar);
- myShouldClearOutputDirectory = CompilerWorkspaceConfiguration.getInstance(myProject).CLEAR_OUTPUT_DIRECTORY;
-
- myGenerationCompilerModuleToOutputDirMap = new HashMap, Pair>();
-
- if (!useOutOfProcessBuild()) {
- final LocalFileSystem lfs = LocalFileSystem.getInstance();
- final IntermediateOutputCompiler[] generatingCompilers = CompilerManager.getInstance(myProject).getCompilers(IntermediateOutputCompiler.class, myCompilerFilter);
- final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
- final CompilerConfiguration config = CompilerConfiguration.getInstance(project);
- for (Module module : allModules) {
- for (IntermediateOutputCompiler compiler : generatingCompilers) {
- final VirtualFile productionOutput = lookupVFile(lfs, CompilerPaths.getGenerationOutputPath(compiler, module, false));
- final VirtualFile testOutput = lookupVFile(lfs, CompilerPaths.getGenerationOutputPath(compiler, module, true));
- final Pair pair = new Pair(compiler, module);
- final Pair outputs = new Pair(productionOutput, testOutput);
- myGenerationCompilerModuleToOutputDirMap.put(pair, outputs);
- }
- if (config.getAnnotationProcessingConfiguration(module).isEnabled()) {
- final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
- if (path != null) {
- lookupVFile(lfs, path); // ensure the file is created and added to VFS
- }
- }
- }
- }
- }
-
- public void setCompilerFilter(CompilerFilter compilerFilter) {
- myCompilerFilter = compilerFilter == null? CompilerFilter.ALL : compilerFilter;
- }
-
- public void rebuild(CompileStatusNotification callback) {
- CompileScope projectScope = ArtifactCompileScope.createScopeWithArtifacts(new ProjectCompileScope(myProject),
- ArtifactUtil.getArtifactWithOutputPaths(myProject), false);
- final CompileScope compileScope = useOutOfProcessBuild() ? projectScope : addAdditionalRoots(projectScope, ALL_EXCEPT_SOURCE_PROCESSING);
- doRebuild(callback, null, true, compileScope);
- }
-
- public void make(CompileScope scope, CompileStatusNotification callback) {
- if (!useOutOfProcessBuild()) {
- scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING);
- }
- if (validateCompilerConfiguration(scope, false)) {
- startup(scope, false, false, callback, null, true);
- }
- else {
- callback.finished(true, 0, 0, DummyCompileContext.getInstance());
- }
- }
-
- public boolean isUpToDate(CompileScope scope) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("isUpToDate operation started");
- }
- scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING);
-
- final CompilerTask task = new CompilerTask(myProject, true, "Classes up-to-date check", true);
- final CompileContextImpl compileContext = new CompileContextImpl(myProject, task, scope, createDependencyCache(), true, false);
-
- checkCachesVersion(compileContext, ((PersistentFS)ManagingFS.getInstance()).getCreationTimestamp());
- if (compileContext.isRebuildRequested()) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Rebuild requested, up-to-date=false");
- }
- return false;
- }
-
- for (Map.Entry, Pair> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) {
- final Pair outputs = entry.getValue();
- final Pair key = entry.getKey();
- final Module module = key.getSecond();
- compileContext.assignModule(outputs.getFirst(), module, false, key.getFirst());
- compileContext.assignModule(outputs.getSecond(), module, true, key.getFirst());
- }
-
- final Ref status = new Ref();
-
- task.start(new Runnable() {
- public void run() {
- try {
- myAllOutputDirectories = getAllOutputDirectories(compileContext);
- // need this for updating zip archives experiment, uncomment if the feature is turned on
- //myOutputFinder = new OutputPathFinder(myAllOutputDirectories);
- status.set(doCompile(compileContext, false, false, true));
- }
- finally {
- CompilerCacheManager.getInstance(myProject).flushCaches();
- }
- }
- }, null);
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("isUpToDate operation finished");
- }
-
- return ExitStatus.UP_TO_DATE.equals(status.get());
- }
-
- private DependencyCache createDependencyCache() {
- return new DependencyCache(myCachesDirectoryPath + File.separator + ".dependency-info");
- }
-
- public void compile(CompileScope scope, CompileStatusNotification callback, boolean clearingOutputDirsPossible) {
- myShouldClearOutputDirectory &= clearingOutputDirsPossible;
- if (containsFileIndexScopes(scope)) {
- scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING);
- }
- if (validateCompilerConfiguration(scope, false)) {
- startup(scope, false, true, callback, null, true);
- }
- else {
- callback.finished(true, 0, 0, DummyCompileContext.getInstance());
- }
- }
-
- private static boolean containsFileIndexScopes(CompileScope scope) {
- if (scope instanceof CompositeScope) {
- for (CompileScope childScope : ((CompositeScope)scope).getScopes()) {
- if (containsFileIndexScopes(childScope)) {
- return true;
- }
- }
- }
- return scope instanceof FileIndexCompileScope;
- }
-
- private static class CompileStatus {
- final int CACHE_FORMAT_VERSION;
- final boolean COMPILATION_IN_PROGRESS;
- final long VFS_CREATION_STAMP;
-
- private CompileStatus(int cacheVersion, boolean isCompilationInProgress, long vfsStamp) {
- CACHE_FORMAT_VERSION = cacheVersion;
- COMPILATION_IN_PROGRESS = isCompilationInProgress;
- VFS_CREATION_STAMP = vfsStamp;
- }
- }
-
- private CompileStatus readStatus() {
- final boolean isInProgress = getLockFile().exists();
- int version = -1;
- long vfsStamp = -1L;
- try {
- final File versionFile = new File(myCachesDirectoryPath, VERSION_FILE_NAME);
- DataInputStream in = new DataInputStream(new FileInputStream(versionFile));
- try {
- version = in.readInt();
- try {
- vfsStamp = in.readLong();
- }
- catch (IOException ignored) {
- }
- }
- finally {
- in.close();
- }
- }
- catch (FileNotFoundException e) {
- // ignore
- }
- catch (IOException e) {
- LOG.info(e); // may happen in case of IDEA crashed and the file is not written properly
- return null;
- }
- return new CompileStatus(version, isInProgress, vfsStamp);
- }
-
- private void writeStatus(CompileStatus status, CompileContext context) {
- final File statusFile = new File(myCachesDirectoryPath, VERSION_FILE_NAME);
-
- final File lockFile = getLockFile();
- try {
- FileUtil.createIfDoesntExist(statusFile);
- DataOutputStream out = new DataOutputStream(new FileOutputStream(statusFile));
- try {
- out.writeInt(status.CACHE_FORMAT_VERSION);
- out.writeLong(status.VFS_CREATION_STAMP);
- }
- finally {
- out.close();
- }
- if (status.COMPILATION_IN_PROGRESS) {
- FileUtil.createIfDoesntExist(lockFile);
- }
- else {
- deleteFile(lockFile);
- }
- }
- catch (IOException e) {
- context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.exception", e.getMessage()), null, -1, -1);
- }
- }
-
- private File getLockFile() {
- return new File(CompilerPaths.getCompilerSystemDirectory(myProject), LOCK_FILE_NAME);
- }
-
- private void doRebuild(CompileStatusNotification callback,
- CompilerMessage message,
- final boolean checkCachesVersion,
- final CompileScope compileScope) {
- if (validateCompilerConfiguration(compileScope, true)) {
- startup(compileScope, true, false, callback, message, checkCachesVersion);
- }
- else {
- callback.finished(true, 0, 0, DummyCompileContext.getInstance());
- }
- }
-
- private CompileScope addAdditionalRoots(CompileScope originalScope, final CompilerFilter filter) {
- CompileScope scope = attachIntermediateOutputDirectories(originalScope, filter);
-
- final AdditionalCompileScopeProvider[] scopeProviders = Extensions.getExtensions(AdditionalCompileScopeProvider.EXTENSION_POINT_NAME);
- CompileScope baseScope = scope;
- for (AdditionalCompileScopeProvider scopeProvider : scopeProviders) {
- final CompileScope additionalScope = scopeProvider.getAdditionalScope(baseScope, filter, myProject);
- if (additionalScope != null) {
- scope = new CompositeScope(scope, additionalScope);
- }
- }
- return scope;
- }
-
- private CompileScope attachIntermediateOutputDirectories(CompileScope originalScope, CompilerFilter filter) {
- CompileScope scope = originalScope;
- final Set affected = new HashSet(Arrays.asList(originalScope.getAffectedModules()));
- for (Map.Entry, Pair> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) {
- final Module module = entry.getKey().getSecond();
- if (affected.contains(module) && filter.acceptCompiler(entry.getKey().getFirst())) {
- final Pair outputs = entry.getValue();
- scope = new CompositeScope(scope, new FileSetCompileScope(Arrays.asList(outputs.getFirst(), outputs.getSecond()), new Module[]{module}));
- }
- }
- return scope;
- }
-
- private void attachAnnotationProcessorsOutputDirectories(CompileContextEx context) {
- final LocalFileSystem lfs = LocalFileSystem.getInstance();
- final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject);
- final Set affected = new HashSet(Arrays.asList(context.getCompileScope().getAffectedModules()));
- for (Module module : affected) {
- if (!config.getAnnotationProcessingConfiguration(module).isEnabled()) {
- continue;
- }
- final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
- if (path == null) {
- continue;
- }
- final VirtualFile vFile = lfs.findFileByPath(path);
- if (vFile == null) {
- continue;
- }
- if (ModuleRootManager.getInstance(module).getFileIndex().isInSourceContent(vFile)) {
- // no need to add, is already marked as source
- continue;
- }
- context.addScope(new FileSetCompileScope(Collections.singletonList(vFile), new Module[]{module}));
- context.assignModule(vFile, module, false, null);
- }
- }
-
- @Nullable
- private RequestFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, @NotNull Collection modules, @NotNull Collection artifacts,
- final @NotNull Collection paths, @Nullable final CompileStatusNotification callback)
- throws Exception {
- Collection moduleNames = Collections.emptyList();
- if (modules.size() > 0) {
- moduleNames = new ArrayList(modules.size());
- for (Module module : modules) {
- moduleNames.add(module.getName());
- }
- }
- List artifactNames = new ArrayList();
- for (Artifact artifact : artifacts) {
- artifactNames.add(artifact.getName());
- }
-
- final CompileScope scope = compileContext.getCompileScope();
- // need to pass scope's user data to server
- final Map exported = scope.exportUserData();
- final Map builderParams;
- if (!exported.isEmpty()) {
- builderParams = new HashMap();
- for (Map.Entry entry : exported.entrySet()) {
- final String _key = entry.getKey().toString();
- final String _value = entry.getValue().toString();
- builderParams.put(_key, _value);
- }
- }
- else {
- builderParams = Collections.emptyMap();
- }
-
- final MessageBus messageBus = myProject.getMessageBus();
-
- if (!CompilerWorkspaceConfiguration.useServerlessOutOfProcessBuild()) {
- final CompileServerManager csManager = CompileServerManager.getInstance();
- csManager.cancelAutoMakeTasks(myProject);
- return csManager.submitCompilationTask(myProject, compileContext.isRebuild(), compileContext.isMake(), moduleNames, artifactNames, paths,
- builderParams, new JpsServerResponseHandler() {
-
- @Override
- public void handleCompileMessage(JpsRemoteProto.Message.Response.CompileMessage compilerMessage) {
- final JpsRemoteProto.Message.Response.CompileMessage.Kind kind = compilerMessage.getKind();
- //System.out.println(compilerMessage.getText());
- if (kind == JpsRemoteProto.Message.Response.CompileMessage.Kind.PROGRESS) {
- final ProgressIndicator indicator = compileContext.getProgressIndicator();
- indicator.setText(compilerMessage.getText());
- if (compilerMessage.hasDone()) {
- indicator.setFraction(compilerMessage.getDone());
- }
- }
- else {
- final CompilerMessageCategory category = kind == JpsRemoteProto.Message.Response.CompileMessage.Kind.ERROR ? CompilerMessageCategory.ERROR
- : kind == JpsRemoteProto.Message.Response.CompileMessage.Kind.WARNING ? CompilerMessageCategory.WARNING : CompilerMessageCategory.INFORMATION;
-
- String sourceFilePath = compilerMessage.hasSourceFilePath() ? compilerMessage.getSourceFilePath() : null;
- if (sourceFilePath != null) {
- sourceFilePath = FileUtil.toSystemIndependentName(sourceFilePath);
- }
- final long line = compilerMessage.hasLine() ? compilerMessage.getLine() : -1;
- final long column = compilerMessage.hasColumn() ? compilerMessage.getColumn() : -1;
- final String srcUrl = sourceFilePath != null ? VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, sourceFilePath) : null;
- compileContext.addMessage(
- category, compilerMessage.getText(), srcUrl, (int)line, (int)column
- );
- }
- }
-
- @Override
- public boolean handleBuildEvent(JpsRemoteProto.Message.Response.BuildEvent event) {
- final JpsRemoteProto.Message.Response.BuildEvent.Type eventType = event.getEventType();
- switch (eventType) {
- case BUILD_STARTED:
- //compileContext.getProgressIndicator().setText("Compilation started");
- break;
- case FILES_GENERATED:
- final List generated = event.getGeneratedFilesList();
- final CompilationStatusListener publisher = messageBus.syncPublisher(CompilerTopics.COMPILATION_STATUS);
- for (JpsRemoteProto.Message.Response.BuildEvent.GeneratedFile generatedFile : generated) {
- final String root = FileUtil.toSystemIndependentName(generatedFile.getOutputRoot());
- final String relativePath = FileUtil.toSystemIndependentName(generatedFile.getRelativePath());
- publisher.fileGenerated(root, relativePath);
- }
- break;
- case BUILD_COMPLETED:
- ExitStatus status = ExitStatus.SUCCESS;
- if (event.hasCompletionStatus()) {
- final JpsRemoteProto.Message.Response.BuildEvent.Status completionStatus = event.getCompletionStatus();
- switch(completionStatus) {
- case CANCELED:
- status = ExitStatus.CANCELLED;
- break;
- case ERRORS:
- status = ExitStatus.ERRORS;
- break;
- case SUCCESS:
- status = ExitStatus.SUCCESS;
- break;
- case UP_TO_DATE:
- status = ExitStatus.UP_TO_DATE;
- break;
- }
- }
- compileContext.putUserDataIfAbsent(COMPILE_SERVER_BUILD_STATUS, status);
- break;
- }
- return eventType == JpsRemoteProto.Message.Response.BuildEvent.Type.BUILD_COMPLETED;
- }
-
- @Override
- public void handleFailure(JpsRemoteProto.Message.Failure failure) {
- compileContext.addMessage(CompilerMessageCategory.ERROR, failure.getDescription(), null, -1, -1);
- final String trace = failure.getStacktrace();
- if (trace != null) {
- LOG.info(trace);
- System.out.println(trace);
- }
- compileContext.putUserData(COMPILE_SERVER_BUILD_STATUS, ExitStatus.ERRORS);
- }
-
- @Override
- public void sessionTerminated() {
- notifyCompilationCompleted(compileContext, callback, COMPILE_SERVER_BUILD_STATUS.get(compileContext, ExitStatus.SUCCESS));
- }
- });
- }
- else {
- final BuildManager buildManager = BuildManager.getInstance();
- buildManager.cancelAutoMakeTasks(myProject);
- return buildManager.scheduleBuild(myProject, compileContext.isRebuild(), compileContext.isMake(), moduleNames, artifactNames, paths, builderParams, new DefaultMessageHandler(myProject) {
- @Override
- public void sessionTerminated() {
- notifyCompilationCompleted(compileContext, callback, COMPILE_SERVER_BUILD_STATUS.get(compileContext));
- }
-
- @Override
- public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) {
- compileContext.addMessage(CompilerMessageCategory.ERROR, failure.getDescription(), null, -1, -1);
- final String trace = failure.getStacktrace();
- if (trace != null) {
- LOG.info(trace);
- System.out.println(trace);
- }
- compileContext.putUserData(COMPILE_SERVER_BUILD_STATUS, ExitStatus.ERRORS);
- }
-
- @Override
- protected void handleCompileMessage(CmdlineRemoteProto.Message.BuilderMessage.CompileMessage message) {
- final CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind kind = message.getKind();
- //System.out.println(compilerMessage.getText());
- if (kind == CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind.PROGRESS) {
- final ProgressIndicator indicator = compileContext.getProgressIndicator();
- indicator.setText(message.getText());
- if (message.hasDone()) {
- indicator.setFraction(message.getDone());
- }
- }
- else {
- final CompilerMessageCategory category = kind == CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind.ERROR ? CompilerMessageCategory.ERROR
- : kind == CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind.WARNING ? CompilerMessageCategory.WARNING : CompilerMessageCategory.INFORMATION;
-
- String sourceFilePath = message.hasSourceFilePath() ? message.getSourceFilePath() : null;
- if (sourceFilePath != null) {
- sourceFilePath = FileUtil.toSystemIndependentName(sourceFilePath);
- }
- final long line = message.hasLine() ? message.getLine() : -1;
- final long column = message.hasColumn() ? message.getColumn() : -1;
- final String srcUrl = sourceFilePath != null ? VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, sourceFilePath) : null;
- compileContext.addMessage(
- category, message.getText(), srcUrl, (int)line, (int)column
- );
- }
- }
-
- @Override
- protected void handleBuildEvent(CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event) {
- final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Type eventType = event.getEventType();
- switch (eventType) {
- case FILES_GENERATED:
- final List generated = event.getGeneratedFilesList();
- final CompilationStatusListener publisher = messageBus.syncPublisher(CompilerTopics.COMPILATION_STATUS);
- for (CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.GeneratedFile generatedFile : generated) {
- final String root = FileUtil.toSystemIndependentName(generatedFile.getOutputRoot());
- final String relativePath = FileUtil.toSystemIndependentName(generatedFile.getRelativePath());
- publisher.fileGenerated(root, relativePath);
- }
- break;
- case BUILD_COMPLETED:
- ExitStatus status = ExitStatus.SUCCESS;
- if (event.hasCompletionStatus()) {
- final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Status completionStatus = event.getCompletionStatus();
- switch(completionStatus) {
- case CANCELED:
- status = ExitStatus.CANCELLED;
- break;
- case ERRORS:
- status = ExitStatus.ERRORS;
- break;
- case SUCCESS:
- status = ExitStatus.SUCCESS;
- break;
- case UP_TO_DATE:
- status = ExitStatus.UP_TO_DATE;
- break;
- }
- }
- compileContext.putUserDataIfAbsent(COMPILE_SERVER_BUILD_STATUS, status);
- break;
- }
- }
- });
- }
- }
-
-
- public static final Key COMPILE_SERVER_BUILD_STATUS = Key.create("COMPILE_SERVER_BUILD_STATUS");
-
- private void startup(final CompileScope scope,
- final boolean isRebuild,
- final boolean forceCompile,
- final CompileStatusNotification callback,
- final CompilerMessage message,
- final boolean checkCachesVersion) {
- ApplicationManager.getApplication().assertIsDispatchThread();
-
- final boolean useExtProcessBuild = useOutOfProcessBuild();
-
- final String contentName =
- forceCompile ? CompilerBundle.message("compiler.content.name.compile") : CompilerBundle.message("compiler.content.name.make");
- final boolean compileInBackground = true;
- final CompilerTask compileTask =
- new CompilerTask(myProject, compileInBackground, contentName, ApplicationManager.getApplication().isUnitTestMode());
-
- StatusBar.Info.set("", myProject, "Compiler");
- if (useOutOfProcessBuild() && BuildManager.getInstance().rescanRequired(myProject)) {
- // ensure the project model seen by build process is up-to-date
- myProject.save();
- }
- PsiDocumentManager.getInstance(myProject).commitAllDocuments();
- FileDocumentManager.getInstance().saveAllDocuments();
-
- final DependencyCache dependencyCache = useExtProcessBuild ? null: createDependencyCache();
- final CompileContextImpl compileContext =
- new CompileContextImpl(myProject, compileTask, scope, dependencyCache, !isRebuild && !forceCompile, isRebuild);
-
- if (!useExtProcessBuild) {
- for (Map.Entry, Pair> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) {
- final Pair outputs = entry.getValue();
- final Pair key = entry.getKey();
- final Module module = key.getSecond();
- compileContext.assignModule(outputs.getFirst(), module, false, key.getFirst());
- compileContext.assignModule(outputs.getSecond(), module, true, key.getFirst());
- }
- attachAnnotationProcessorsOutputDirectories(compileContext);
- }
-
- final Runnable compileWork;
- if (useExtProcessBuild) {
- compileWork = new Runnable() {
- public void run() {
- final ProgressIndicator indicator = compileContext.getProgressIndicator();
- if (indicator.isCanceled() || myProject.isDisposed()) {
- if (callback != null) {
- callback.finished(true, 0, 0, compileContext);
- }
- return;
- }
- final long start = System.currentTimeMillis();
- try {
- LOG.info("COMPILATION STARTED " + (CompilerWorkspaceConfiguration.useServerlessOutOfProcessBuild() ? "(BUILD PROCESS)" : "(COMPILE SERVER)"));
- if (message != null) {
- compileContext.addMessage(message);
- }
- final Collection paths = fetchFiles(compileContext);
- final List modules = paths.isEmpty() && !isRebuild && !allProjectModulesAffected(compileContext)? Arrays.asList(compileContext.getCompileScope().getAffectedModules()) : Collections.emptyList();
- final Set artifacts = ArtifactCompileScope.getArtifactsToBuild(myProject, compileContext.getCompileScope(), true);
- final RequestFuture future = compileInExternalProcess(compileContext, modules, artifacts, paths, callback);
- if (future != null) {
- while (!future.waitFor(200L , TimeUnit.MILLISECONDS)) {
- if (indicator.isCanceled()) {
- future.cancel(false);
- }
- }
- }
- else {
- callback.finished(false, compileContext.getMessageCount(CompilerMessageCategory.ERROR), compileContext.getMessageCount(CompilerMessageCategory.WARNING), compileContext);
- }
- }
- catch (Throwable e) {
- LOG.error(e); // todo
- callback.finished(false, compileContext.getMessageCount(CompilerMessageCategory.ERROR), compileContext.getMessageCount(CompilerMessageCategory.WARNING), compileContext);
- }
- finally {
- final long finish = System.currentTimeMillis();
- CompilerUtil.logDuration(
- "\tCOMPILATION FINISHED " + (CompilerWorkspaceConfiguration.useServerlessOutOfProcessBuild() ? "(BUILD PROCESS)" : "(COMPILE SERVER)") + "; Errors: " +
- compileContext.getMessageCount(CompilerMessageCategory.ERROR) +
- "; warnings: " +
- compileContext.getMessageCount(CompilerMessageCategory.WARNING),
- finish - start
- );
-
- CompilerCacheManager.getInstance(myProject).flushCaches();
-
- // todo: need this for tests; should be removed later
- final Set outputs = new HashSet();
- for (final String path : CompilerPathsEx.getOutputPaths(ModuleManager.getInstance(myProject).getModules())) {
- outputs.add(new File(path));
- }
- CompilerUtil.refreshIOFiles(outputs);
- }
- }
- };
- }
- else {
- compileWork = new Runnable() {
- public void run() {
- if (compileContext.getProgressIndicator().isCanceled()) {
- if (callback != null) {
- callback.finished(true, 0, 0, compileContext);
- }
- return;
- }
- long start = System.currentTimeMillis();
- try {
- if (myProject.isDisposed()) {
- return;
- }
- LOG.info("COMPILATION STARTED");
- if (message != null) {
- compileContext.addMessage(message);
- }
- TranslatingCompilerFilesMonitor.getInstance().ensureInitializationCompleted(myProject, compileContext.getProgressIndicator());
- doCompile(compileContext, isRebuild, forceCompile, callback, checkCachesVersion);
- }
- finally {
- final long finish = System.currentTimeMillis();
- CompilerUtil.logDuration(
- "\tCOMPILATION FINISHED; Errors: " +
- compileContext.getMessageCount(CompilerMessageCategory.ERROR) +
- "; warnings: " +
- compileContext.getMessageCount(CompilerMessageCategory.WARNING),
- finish - start
- );
- CompilerCacheManager.getInstance(myProject).flushCaches();
- FileUtil.delete(CompilerPaths.getRebuildMarkerFile(myProject));
- }
- }
- };
- }
-
- compileTask.start(compileWork, new Runnable() {
- public void run() {
- if (isRebuild) {
- final int rv = Messages.showOkCancelDialog(
- myProject, "You are about to rebuild the whole project.\nRun 'Make Project' instead?", "Confirm Project Rebuild",
- "Make", "Rebuild", Messages.getQuestionIcon()
- );
- if (rv == 0 /*yes, please, do run make*/) {
- startup(scope, false, false, callback, null, checkCachesVersion);
- return;
- }
- }
- startup(scope, isRebuild, forceCompile, callback, message, checkCachesVersion);
- }
- });
- }
-
- private static boolean allProjectModulesAffected(CompileContextImpl compileContext) {
- final Set allModules = new HashSet(Arrays.asList(compileContext.getProjectCompileScope().getAffectedModules()));
- allModules.removeAll(Arrays.asList(compileContext.getCompileScope().getAffectedModules()));
- return allModules.isEmpty();
- }
-
- private static List fetchFiles(CompileContextImpl context) {
- if (context.isRebuild()) {
- return Collections.emptyList();
- }
- final CompileScope scope = context.getCompileScope();
- if (shouldFetchFiles(scope)) {
- final List paths = new ArrayList();
- for (VirtualFile file : scope.getFiles(null, true)) {
- paths.add(file.getPath());
- }
- return paths;
- }
- return Collections.emptyList();
- }
-
- private static boolean shouldFetchFiles(CompileScope scope) {
- if (scope instanceof CompositeScope) {
- for (CompileScope compileScope : ((CompositeScope)scope).getScopes()) {
- if (shouldFetchFiles(compileScope)) {
- return true;
- }
- }
- }
- return scope instanceof OneProjectItemCompileScope || scope instanceof FileSetCompileScope;
- }
-
- private void doCompile(final CompileContextImpl compileContext,
- final boolean isRebuild,
- final boolean forceCompile,
- final CompileStatusNotification callback,
- final boolean checkCachesVersion) {
- ExitStatus status = ExitStatus.ERRORS;
- boolean wereExceptions = false;
- final long vfsTimestamp = ((PersistentFS)ManagingFS.getInstance()).getCreationTimestamp();
- try {
- if (checkCachesVersion) {
- checkCachesVersion(compileContext, vfsTimestamp);
- if (compileContext.isRebuildRequested()) {
- return;
- }
- }
- writeStatus(new CompileStatus(CompilerConfigurationImpl.DEPENDENCY_FORMAT_VERSION, true, vfsTimestamp), compileContext);
- if (compileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- return;
- }
-
- myAllOutputDirectories = getAllOutputDirectories(compileContext);
- status = doCompile(compileContext, isRebuild, forceCompile, false);
- }
- catch (Throwable ex) {
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- throw new RuntimeException(ex);
- }
- wereExceptions = true;
- final PluginId pluginId = IdeErrorsDialog.findPluginId(ex);
-
- final StringBuilder message = new StringBuilder();
- message.append("Internal error");
- if (pluginId != null) {
- message.append(" (Plugin: ").append(pluginId).append(")");
- }
- message.append(": ").append(ex.getMessage());
- compileContext.addMessage(CompilerMessageCategory.ERROR, message.toString(), null, -1, -1);
-
- if (pluginId != null) {
- throw new PluginException(ex, pluginId);
- }
- throw new RuntimeException(ex);
- }
- finally {
- dropDependencyCache(compileContext);
- final ExitStatus _status = status;
- if (compileContext.isRebuildRequested()) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- public void run() {
- final CompilerMessageImpl msg = new CompilerMessageImpl(myProject, CompilerMessageCategory.INFORMATION, compileContext.getRebuildReason());
- doRebuild(callback, msg, false, compileContext.getCompileScope());
- }
- }, ModalityState.NON_MODAL);
- }
- else {
- if (!myProject.isDisposed()) {
- writeStatus(new CompileStatus(CompilerConfigurationImpl.DEPENDENCY_FORMAT_VERSION, wereExceptions, vfsTimestamp), compileContext);
- }
- notifyCompilationCompleted(compileContext, callback, _status);
- }
- }
- }
-
- /** @noinspection SSBasedInspection*/
- private void notifyCompilationCompleted(final CompileContextImpl compileContext, final CompileStatusNotification callback, final ExitStatus _status) {
- final long duration = System.currentTimeMillis() - compileContext.getStartCompilationStamp();
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- int errorCount = 0;
- int warningCount = 0;
- try {
- errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR);
- warningCount = compileContext.getMessageCount(CompilerMessageCategory.WARNING);
- if (!myProject.isDisposed()) {
- final String statusMessage = createStatusMessage(_status, warningCount, errorCount, duration);
- final MessageType messageType = errorCount > 0 ? MessageType.ERROR : warningCount > 0 ? MessageType.WARNING : MessageType.INFO;
- if (duration > ONE_MINUTE_MS) {
- ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType, statusMessage);
- }
- CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, messageType).notify(myProject);
- if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) {
- compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1);
- }
- }
- }
- finally {
- if (callback != null) {
- callback.finished(_status == ExitStatus.CANCELLED, errorCount, warningCount, compileContext);
- }
- }
- }
- });
- }
-
- private void checkCachesVersion(final CompileContextImpl compileContext, final long currentVFSTimestamp) {
- if (CompilerPaths.getRebuildMarkerFile(compileContext.getProject()).exists()) {
- compileContext.requestRebuildNextTime("Compiler caches are out of date, project rebuild is required");
- return;
- }
- final CompileStatus compileStatus = readStatus();
- if (compileStatus == null) {
- compileContext.requestRebuildNextTime(CompilerBundle.message("error.compiler.caches.corrupted"));
- }
- else if (compileStatus.CACHE_FORMAT_VERSION != -1 &&
- compileStatus.CACHE_FORMAT_VERSION != CompilerConfigurationImpl.DEPENDENCY_FORMAT_VERSION) {
- compileContext.requestRebuildNextTime(CompilerBundle.message("error.caches.old.format"));
- }
- else if (compileStatus.COMPILATION_IN_PROGRESS) {
- compileContext.requestRebuildNextTime(CompilerBundle.message("error.previous.compilation.failed"));
- }
- else if (compileStatus.VFS_CREATION_STAMP >= 0L){
- if (currentVFSTimestamp != compileStatus.VFS_CREATION_STAMP) {
- compileContext.requestRebuildNextTime(CompilerBundle.message("error.vfs.was.rebuilt"));
- }
- }
- }
-
- private static String createStatusMessage(final ExitStatus status, final int warningCount, final int errorCount, long duration) {
- String message;
- if (status == ExitStatus.CANCELLED) {
- message = CompilerBundle.message("status.compilation.aborted");
- }
- else if (status == ExitStatus.UP_TO_DATE) {
- message = CompilerBundle.message("status.all.up.to.date");
- }
- else {
- if (status == ExitStatus.SUCCESS) {
- message = warningCount > 0
- ? CompilerBundle.message("status.compilation.completed.successfully.with.warnings", warningCount)
- : CompilerBundle.message("status.compilation.completed.successfully");
- }
- else {
- message = CompilerBundle.message("status.compilation.completed.successfully.with.warnings.and.errors", errorCount, warningCount);
- }
- message = message + " in " + formatDuration(duration);
- }
- return message;
- }
-
- public static String formatDuration(long duration) {
- final long minutes = duration / 60000;
- final long seconds = (duration % 60000) / 1000;
- if (minutes > 0L) {
- return minutes + " min " + seconds + " sec";
- }
- return seconds + " sec";
- }
-
- private ExitStatus doCompile(final CompileContextEx context, boolean isRebuild, final boolean forceCompile, final boolean onlyCheckStatus) {
- try {
- if (isRebuild) {
- deleteAll(context);
- }
- else if (forceCompile) {
- if (myShouldClearOutputDirectory) {
- clearAffectedOutputPathsIfPossible(context);
- }
- }
- if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- if (LOG.isDebugEnabled()) {
- logErrorMessages(context);
- }
- return ExitStatus.ERRORS;
- }
-
- if (!onlyCheckStatus) {
- if (!executeCompileTasks(context, true)) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Compilation cancelled");
- }
- return ExitStatus.CANCELLED;
- }
- }
-
- if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- if (LOG.isDebugEnabled()) {
- logErrorMessages(context);
- }
- return ExitStatus.ERRORS;
- }
-
- boolean needRecalcOutputDirs = false;
- if (Registry.is(PROP_PERFORM_INITIAL_REFRESH) || !Boolean.valueOf(REFRESH_DONE_KEY.get(myProject, Boolean.FALSE))) {
- REFRESH_DONE_KEY.set(myProject, Boolean.TRUE);
- final long refreshStart = System.currentTimeMillis();
-
- //need this to make sure the VFS is built
- final List outputsToRefresh = new ArrayList();
-
- final VirtualFile[] all = context.getAllOutputDirectories();
-
- final ProgressIndicator progressIndicator = context.getProgressIndicator();
-
- //final int totalCount = all.length + myGenerationCompilerModuleToOutputDirMap.size() * 2;
- progressIndicator.pushState();
- progressIndicator.setText("Inspecting output directories...");
- try {
- for (VirtualFile output : all) {
- if (output.isValid()) {
- walkChildren(output, context);
- }
- else {
- needRecalcOutputDirs = true;
- final File file = new File(output.getPath());
- if (!file.exists()) {
- final boolean created = file.mkdirs();
- if (!created) {
- context.addMessage(CompilerMessageCategory.ERROR, "Failed to create output directory " + file.getPath(), null, 0, 0);
- return ExitStatus.ERRORS;
- }
- }
- output = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
- if (output == null) {
- context.addMessage(CompilerMessageCategory.ERROR, "Failed to locate output directory " + file.getPath(), null, 0, 0);
- return ExitStatus.ERRORS;
- }
- }
- outputsToRefresh.add(output);
- }
- for (Pair pair : myGenerationCompilerModuleToOutputDirMap.keySet()) {
- final Pair generated = myGenerationCompilerModuleToOutputDirMap.get(pair);
- walkChildren(generated.getFirst(), context);
- outputsToRefresh.add(generated.getFirst());
- walkChildren(generated.getSecond(), context);
- outputsToRefresh.add(generated.getSecond());
- }
-
- RefreshQueue.getInstance().refresh(false, true, null, VfsUtil.toVirtualFileArray(outputsToRefresh));
- if (progressIndicator.isCanceled()) {
- return ExitStatus.CANCELLED;
- }
- }
- finally {
- progressIndicator.popState();
- }
-
- final long initialRefreshTime = System.currentTimeMillis() - refreshStart;
- CompilerUtil.logDuration("Initial VFS refresh", initialRefreshTime);
- }
-
- //DumbService.getInstance(myProject).waitForSmartMode();
- final Semaphore semaphore = new Semaphore();
- semaphore.down();
- DumbService.getInstance(myProject).runWhenSmart(new Runnable() {
- public void run() {
- semaphore.up();
- }
- });
- while (!semaphore.waitFor(500)) {
- if (context.getProgressIndicator().isCanceled()) {
- return ExitStatus.CANCELLED;
- }
- }
-
- if (needRecalcOutputDirs) {
- context.recalculateOutputDirs();
- }
-
- boolean didSomething = false;
-
- final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
- GenericCompilerRunner runner = new GenericCompilerRunner(context, isRebuild, onlyCheckStatus,
- compilerManager.getCompilers(GenericCompiler.class, myCompilerFilter));
- try {
- didSomething |= generateSources(compilerManager, context, forceCompile, onlyCheckStatus);
-
- didSomething |= invokeFileProcessingCompilers(compilerManager, context, SourceInstrumentingCompiler.class,
- FILE_PROCESSING_COMPILER_ADAPTER_FACTORY, forceCompile, true, onlyCheckStatus);
-
- didSomething |= invokeFileProcessingCompilers(compilerManager, context, SourceProcessingCompiler.class,
- FILE_PROCESSING_COMPILER_ADAPTER_FACTORY, forceCompile, true, onlyCheckStatus);
-
- final CompileScope intermediateSources = attachIntermediateOutputDirectories(new CompositeScope(CompileScope.EMPTY_ARRAY) {
- @NotNull
- public Module[] getAffectedModules() {
- return context.getCompileScope().getAffectedModules();
- }
- }, SOURCE_PROCESSING_ONLY);
- context.addScope(intermediateSources);
-
- didSomething |= translate(context, compilerManager, forceCompile, isRebuild, onlyCheckStatus);
-
- didSomething |= invokeFileProcessingCompilers(compilerManager, context, ClassInstrumentingCompiler.class,
- FILE_PROCESSING_COMPILER_ADAPTER_FACTORY, isRebuild, false, onlyCheckStatus);
- didSomething |= runner.invokeCompilers(GenericCompiler.CompileOrderPlace.CLASS_INSTRUMENTING);
-
- // explicitly passing forceCompile = false because in scopes that is narrower than ProjectScope it is impossible
- // to understand whether the class to be processed is in scope or not. Otherwise compiler may process its items even if
- // there were changes in completely independent files.
- didSomething |= invokeFileProcessingCompilers(compilerManager, context, ClassPostProcessingCompiler.class,
- FILE_PROCESSING_COMPILER_ADAPTER_FACTORY, isRebuild, false, onlyCheckStatus);
- didSomething |= runner.invokeCompilers(GenericCompiler.CompileOrderPlace.CLASS_POST_PROCESSING);
-
- didSomething |= invokeFileProcessingCompilers(compilerManager, context, PackagingCompiler.class,
- FILE_PACKAGING_COMPILER_ADAPTER_FACTORY,
- isRebuild, false, onlyCheckStatus);
- didSomething |= runner.invokeCompilers(GenericCompiler.CompileOrderPlace.PACKAGING);
-
- didSomething |= invokeFileProcessingCompilers(compilerManager, context, Validator.class, FILE_PROCESSING_COMPILER_ADAPTER_FACTORY,
- forceCompile, true, onlyCheckStatus);
- didSomething |= runner.invokeCompilers(GenericCompiler.CompileOrderPlace.VALIDATING);
- }
- catch (ExitException e) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(e);
- logErrorMessages(context);
- }
- return e.getExitStatus();
- }
- finally {
- // drop in case it has not been dropped yet.
- dropDependencyCache(context);
- final VirtualFile[] allOutputDirs = context.getAllOutputDirectories();
-
- if (didSomething && GENERATE_CLASSPATH_INDEX) {
- CompilerUtil.runInContext(context, "Generating classpath index...", new ThrowableRunnable(){
- public void run() {
- int count = 0;
- for (VirtualFile file : allOutputDirs) {
- context.getProgressIndicator().setFraction((double)++count / allOutputDirs.length);
- createClasspathIndex(file);
- }
- }
- });
- }
-
- }
-
- if (!onlyCheckStatus) {
- if (!executeCompileTasks(context, false)) {
- return ExitStatus.CANCELLED;
- }
- final int constantSearchesCount = ChangedConstantsDependencyProcessor.getConstantSearchesCount(context);
- LOG.debug("Constants searches: " + constantSearchesCount);
- }
-
- if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- if (LOG.isDebugEnabled()) {
- logErrorMessages(context);
- }
- return ExitStatus.ERRORS;
- }
- if (!didSomething) {
- return ExitStatus.UP_TO_DATE;
- }
- return ExitStatus.SUCCESS;
- }
- catch (ProcessCanceledException e) {
- return ExitStatus.CANCELLED;
- }
- }
-
- private void clearAffectedOutputPathsIfPossible(CompileContextEx context) {
- final MultiMap outputToModulesMap = new MultiMap();
- for (Module module : ModuleManager.getInstance(myProject).getModules()) {
- final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
- if (compilerModuleExtension == null) {
- continue;
- }
- final String outputPathUrl = compilerModuleExtension.getCompilerOutputUrl();
- if (outputPathUrl != null) {
- final String path = VirtualFileManager.extractPath(outputPathUrl);
- outputToModulesMap.putValue(new File(path), module);
- }
-
- final String outputPathForTestsUrl = compilerModuleExtension.getCompilerOutputUrlForTests();
- if (outputPathForTestsUrl != null) {
- final String path = VirtualFileManager.extractPath(outputPathForTestsUrl);
- outputToModulesMap.putValue(new File(path), module);
- }
- }
- final Set affectedModules = new HashSet(Arrays.asList(context.getCompileScope().getAffectedModules()));
- final List scopeOutputs = new ArrayList(affectedModules.size() * 2);
- for (File output : outputToModulesMap.keySet()) {
- if (affectedModules.containsAll(outputToModulesMap.get(output))) {
- scopeOutputs.add(output);
- }
- }
-
- final Set artifactsToBuild = ArtifactCompileScope.getArtifactsToBuild(myProject, context.getCompileScope(), true);
- for (Artifact artifact : artifactsToBuild) {
- final String outputFilePath = ((ArtifactImpl)artifact).getOutputDirectoryPathToCleanOnRebuild();
- if (outputFilePath != null) {
- scopeOutputs.add(new File(FileUtil.toSystemDependentName(outputFilePath)));
- }
- }
- if (scopeOutputs.size() > 0) {
- CompilerUtil.runInContext(context, CompilerBundle.message("progress.clearing.output"), new ThrowableRunnable() {
- public void run() {
- CompilerUtil.clearOutputDirectories(scopeOutputs);
- }
- });
- }
- }
-
- private static void logErrorMessages(final CompileContext context) {
- final CompilerMessage[] errors = context.getMessages(CompilerMessageCategory.ERROR);
- if (errors.length > 0) {
- LOG.debug("Errors reported: ");
- for (CompilerMessage error : errors) {
- LOG.debug("\t" + error.getMessage());
- }
- }
- }
-
- private static void walkChildren(VirtualFile from, final CompileContext context) {
- final VirtualFile[] files = from.getChildren();
- if (files != null && files.length > 0) {
- context.getProgressIndicator().checkCanceled();
- context.getProgressIndicator().setText2(from.getPresentableUrl());
- for (VirtualFile file : files) {
- walkChildren(file, context);
- }
- }
- }
-
- private static void createClasspathIndex(final VirtualFile file) {
- try {
- BufferedWriter writer = new BufferedWriter(new FileWriter(new File(VfsUtil.virtualToIoFile(file), "classpath.index")));
- try {
- writeIndex(writer, file, file);
- }
- finally {
- writer.close();
- }
- }
- catch (IOException e) {
- // Ignore. Failed to create optional classpath index
- }
- }
-
- private static void writeIndex(final BufferedWriter writer, final VirtualFile root, final VirtualFile file) throws IOException {
- writer.write(VfsUtilCore.getRelativePath(file, root, '/'));
- writer.write('\n');
-
- for (VirtualFile child : file.getChildren()) {
- writeIndex(writer, root, child);
- }
- }
-
- private static void dropDependencyCache(final CompileContextEx context) {
- CompilerUtil.runInContext(context, CompilerBundle.message("progress.saving.caches"), new ThrowableRunnable(){
- public void run() {
- context.getDependencyCache().resetState();
- }
- });
- }
-
- private boolean generateSources(final CompilerManager compilerManager,
- CompileContextEx context,
- final boolean forceCompile,
- final boolean onlyCheckStatus) throws ExitException {
- boolean didSomething = false;
-
- final SourceGeneratingCompiler[] sourceGenerators = compilerManager.getCompilers(SourceGeneratingCompiler.class, myCompilerFilter);
- for (final SourceGeneratingCompiler sourceGenerator : sourceGenerators) {
- if (context.getProgressIndicator().isCanceled()) {
- throw new ExitException(ExitStatus.CANCELLED);
- }
-
- final boolean generatedSomething = generateOutput(context, sourceGenerator, forceCompile, onlyCheckStatus);
-
- if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- throw new ExitException(ExitStatus.ERRORS);
- }
- didSomething |= generatedSomething;
- }
- return didSomething;
- }
-
- private boolean translate(final CompileContextEx context,
- final CompilerManager compilerManager,
- final boolean forceCompile,
- boolean isRebuild,
- final boolean onlyCheckStatus) throws ExitException {
-
- boolean didSomething = false;
-
- final TranslatingCompiler[] translators = compilerManager.getCompilers(TranslatingCompiler.class, myCompilerFilter);
-
-
- final List> sortedChunks = Collections.unmodifiableList(ApplicationManager.getApplication().runReadAction(new Computable>>() {
- public List> compute() {
- final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
- return ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(moduleManager.getModules()));
- }
- }));
-
- final DumbService dumbService = DumbService.getInstance(myProject);
- try {
- final Set processedModules = new HashSet();
- VirtualFile[] snapshot = null;
- final Map, Collection> chunkMap = new HashMap, Collection>();
- int total = 0;
- int processed = 0;
- for (final Chunk currentChunk : sortedChunks) {
- final TranslatorsOutputSink sink = new TranslatorsOutputSink(context, translators);
- final Set generatedTypes = new HashSet();
- Collection chunkFiles = chunkMap.get(currentChunk);
- final Set filesToRecompile = new HashSet();
- final Set allDependent = new HashSet();
- try {
- int round = 0;
- boolean compiledSomethingForThisChunk = false;
- Collection dependentFiles = Collections.emptyList();
- final Function>, Pair>> dependencyFilter = new DependentClassesCumulativeFilter();
-
- do {
- for (int currentCompiler = 0, translatorsLength = translators.length; currentCompiler < translatorsLength; currentCompiler++) {
- sink.setCurrentCompilerIndex(currentCompiler);
- final TranslatingCompiler compiler = translators[currentCompiler];
- if (context.getProgressIndicator().isCanceled()) {
- throw new ExitException(ExitStatus.CANCELLED);
- }
-
- dumbService.waitForSmartMode();
-
- if (snapshot == null || ContainerUtil.intersects(generatedTypes, compilerManager.getRegisteredInputTypes(compiler))) {
- // rescan snapshot if previously generated files may influence the input of this compiler
- final Set prevSnapshot = round > 0 && snapshot != null? new HashSet(Arrays.asList(snapshot)) : Collections.emptySet();
- snapshot = ApplicationManager.getApplication().runReadAction(new Computable() {
- public VirtualFile[] compute() {
- return context.getCompileScope().getFiles(null, true);
- }
- });
- recalculateChunkToFilesMap(context, sortedChunks, snapshot, chunkMap);
- if (round == 0) {
- chunkFiles = chunkMap.get(currentChunk);
- }
- else {
- final Set newFiles = new HashSet(chunkMap.get(currentChunk));
- newFiles.removeAll(prevSnapshot);
- newFiles.removeAll(chunkFiles);
- if (!newFiles.isEmpty()) {
- final ArrayList merged = new ArrayList(chunkFiles.size() + newFiles.size());
- merged.addAll(chunkFiles);
- merged.addAll(newFiles);
- chunkFiles = merged;
- }
- }
- total = snapshot.length * translatorsLength;
- }
-
- final CompileContextEx _context;
- if (compiler instanceof IntermediateOutputCompiler) {
- // wrap compile context so that output goes into intermediate directories
- final IntermediateOutputCompiler _compiler = (IntermediateOutputCompiler)compiler;
- _context = new CompileContextExProxy(context) {
- public VirtualFile getModuleOutputDirectory(final Module module) {
- return getGenerationOutputDir(_compiler, module, false);
- }
-
- public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
- return getGenerationOutputDir(_compiler, module, true);
- }
- };
- }
- else {
- _context = context;
- }
- final boolean compiledSomething =
- compileSources(_context, currentChunk, compiler, chunkFiles, round == 0? forceCompile : true, isRebuild, onlyCheckStatus, sink);
-
- processed += chunkFiles.size();
- _context.getProgressIndicator().setFraction(((double)processed) / total);
-
- if (compiledSomething) {
- generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(compiler));
- }
-
- didSomething |= compiledSomething;
- compiledSomethingForThisChunk |= didSomething;
-
- if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- break; // break the loop over compilers
- }
- }
-
- final boolean hasUnprocessedTraverseRoots = context.getDependencyCache().hasUnprocessedTraverseRoots();
- if (!isRebuild && (compiledSomethingForThisChunk || hasUnprocessedTraverseRoots)) {
- final Set compiledWithErrors = CacheUtils.getFilesCompiledWithErrors(context);
- filesToRecompile.removeAll(sink.getCompiledSources());
- filesToRecompile.addAll(compiledWithErrors);
-
- dependentFiles = CacheUtils.findDependentFiles(context, compiledWithErrors, dependencyFilter);
- if (!processedModules.isEmpty()) {
- for (Iterator it = dependentFiles.iterator(); it.hasNext();) {
- final VirtualFile next = it.next();
- final Module module = context.getModuleByFile(next);
- if (module != null && processedModules.contains(module)) {
- it.remove();
- }
- }
- }
-
- if (ourDebugMode) {
- if (!dependentFiles.isEmpty()) {
- for (VirtualFile dependentFile : dependentFiles) {
- System.out.println("FOUND TO RECOMPILE: " + dependentFile.getPresentableUrl());
- }
- }
- else {
- System.out.println("NO FILES TO RECOMPILE");
- }
- }
-
- if (!dependentFiles.isEmpty()) {
- filesToRecompile.addAll(dependentFiles);
- allDependent.addAll(dependentFiles);
- if (context.getProgressIndicator().isCanceled() || context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- break;
- }
- final List filesInScope = getFilesInScope(context, currentChunk, dependentFiles);
- if (filesInScope.isEmpty()) {
- break;
- }
- context.getDependencyCache().clearTraverseRoots();
- chunkFiles = filesInScope;
- total += chunkFiles.size() * translators.length;
- }
-
- didSomething |= (hasUnprocessedTraverseRoots != context.getDependencyCache().hasUnprocessedTraverseRoots());
- }
-
- round++;
- }
- while (!dependentFiles.isEmpty() && context.getMessageCount(CompilerMessageCategory.ERROR) == 0);
-
- if (CompilerConfiguration.MAKE_ENABLED) {
- if (!context.getProgressIndicator().isCanceled()) {
- // when cancelled pretend nothing was compiled and next compile will compile everything from the scratch
- final ProgressIndicator indicator = context.getProgressIndicator();
- final DependencyCache cache = context.getDependencyCache();
-
- indicator.pushState();
- indicator.setText(CompilerBundle.message("progress.updating.caches"));
- indicator.setText2("");
-
- cache.update();
-
- indicator.setText(CompilerBundle.message("progress.saving.caches"));
- cache.resetState();
- processedModules.addAll(currentChunk.getNodes());
- indicator.popState();
- }
- }
-
- if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- throw new ExitException(ExitStatus.ERRORS);
- }
-
- }
- catch (CacheCorruptedException e) {
- LOG.info(e);
- context.requestRebuildNextTime(e.getMessage());
- }
- finally {
- final int errorCount = context.getMessageCount(CompilerMessageCategory.ERROR);
- if (errorCount != 0) {
- filesToRecompile.addAll(allDependent);
- }
- if (filesToRecompile.size() > 0) {
- sink.add(null, Collections.emptyList(), VfsUtil.toVirtualFileArray(filesToRecompile));
- }
- if (errorCount == 0) {
- // perform update only if there were no errors, so it is guaranteed that the file was processd by all neccesary compilers
- sink.flushPostponedItems();
- }
- }
- }
- }
- catch (ProcessCanceledException e) {
- ProgressManager.getInstance().executeNonCancelableSection(new Runnable() {
- public void run() {
- try {
- final Collection deps = CacheUtils.findDependentFiles(context, Collections.emptySet(), null);
- if (deps.size() > 0) {
- TranslatingCompilerFilesMonitor.getInstance().update(context, null, Collections.emptyList(),
- VfsUtil.toVirtualFileArray(deps));
- }
- }
- catch (IOException ignored) {
- LOG.info(ignored);
- }
- catch (CacheCorruptedException ignored) {
- LOG.info(ignored);
- }
- catch (ExitException e1) {
- LOG.info(e1);
- }
- }
- });
- throw e;
- }
- finally {
- dropDependencyCache(context);
- if (didSomething) {
- TranslatingCompilerFilesMonitor.getInstance().updateOutputRootsLayout(myProject);
- }
- }
- return didSomething;
- }
-
- private static List getFilesInScope(final CompileContextEx context, final Chunk chunk, final Collection files) {
- final List filesInScope = new ArrayList(files.size());
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- for (VirtualFile file : files) {
- if (context.getCompileScope().belongs(file.getUrl())) {
- final Module module = context.getModuleByFile(file);
- if (chunk.getNodes().contains(module)) {
- filesInScope.add(file);
- }
- }
- }
- }
- });
- return filesInScope;
- }
-
- private static void recalculateChunkToFilesMap(CompileContextEx context, List> allChunks, VirtualFile[] snapshot, Map, Collection> chunkMap) {
- final Map> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(context, snapshot);
- for (Chunk moduleChunk : allChunks) {
- List files = Collections.emptyList();
- for (Module module : moduleChunk.getNodes()) {
- final List moduleFiles = moduleToFilesMap.get(module);
- if (moduleFiles != null) {
- files = ContainerUtil.concat(files, moduleFiles);
- }
- }
- chunkMap.put(moduleChunk, files);
- }
- }
-
- private interface FileProcessingCompilerAdapterFactory {
- FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler);
- }
-
- private boolean invokeFileProcessingCompilers(final CompilerManager compilerManager,
- CompileContextEx context,
- Class extends FileProcessingCompiler> fileProcessingCompilerClass,
- FileProcessingCompilerAdapterFactory factory,
- boolean forceCompile,
- final boolean checkScope,
- final boolean onlyCheckStatus) throws ExitException {
- boolean didSomething = false;
- final FileProcessingCompiler[] compilers = compilerManager.getCompilers(fileProcessingCompilerClass, myCompilerFilter);
- if (compilers.length > 0) {
- try {
- CacheDeferredUpdater cacheUpdater = new CacheDeferredUpdater();
- try {
- for (final FileProcessingCompiler compiler : compilers) {
- if (context.getProgressIndicator().isCanceled()) {
- throw new ExitException(ExitStatus.CANCELLED);
- }
-
- CompileContextEx _context = context;
- if (compiler instanceof IntermediateOutputCompiler) {
- final IntermediateOutputCompiler _compiler = (IntermediateOutputCompiler)compiler;
- _context = new CompileContextExProxy(context) {
- public VirtualFile getModuleOutputDirectory(final Module module) {
- return getGenerationOutputDir(_compiler, module, false);
- }
-
- public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
- return getGenerationOutputDir(_compiler, module, true);
- }
- };
- }
-
- final boolean processedSomething = processFiles(factory.create(_context, compiler), forceCompile, checkScope, onlyCheckStatus, cacheUpdater);
-
- if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- throw new ExitException(ExitStatus.ERRORS);
- }
-
- didSomething |= processedSomething;
- }
- }
- finally {
- cacheUpdater.doUpdate();
- }
- }
- catch (IOException e) {
- LOG.info(e);
- context.requestRebuildNextTime(e.getMessage());
- throw new ExitException(ExitStatus.ERRORS);
- }
- catch (ProcessCanceledException e) {
- throw e;
- }
- catch (ExitException e) {
- throw e;
- }
- catch (Exception e) {
- context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.exception", e.getMessage()), null, -1, -1);
- LOG.error(e);
- }
- }
-
- return didSomething;
- }
-
- private static Map> buildModuleToGenerationItemMap(GeneratingCompiler.GenerationItem[] items) {
- final Map> map = new HashMap>();
- for (GeneratingCompiler.GenerationItem item : items) {
- Module module = item.getModule();
- LOG.assertTrue(module != null);
- Set itemSet = map.get(module);
- if (itemSet == null) {
- itemSet = new HashSet();
- map.put(module, itemSet);
- }
- itemSet.add(item);
- }
- return map;
- }
-
- private void deleteAll(final CompileContextEx context) {
- CompilerUtil.runInContext(context, CompilerBundle.message("progress.clearing.output"), new ThrowableRunnable() {
- public void run() {
- final boolean isTestMode = ApplicationManager.getApplication().isUnitTestMode();
- final VirtualFile[] allSources = context.getProjectCompileScope().getFiles(null, true);
- if (myShouldClearOutputDirectory) {
- CompilerUtil.clearOutputDirectories(myAllOutputDirectories);
- }
- else { // refresh is still required
- try {
- for (final Compiler compiler : CompilerManager.getInstance(myProject).getCompilers(Compiler.class)) {
- try {
- if (compiler instanceof GeneratingCompiler) {
- final StateCache cache = getGeneratingCompilerCache((GeneratingCompiler)compiler);
- final Iterator urlIterator = cache.getUrlsIterator();
- while (urlIterator.hasNext()) {
- context.getProgressIndicator().checkCanceled();
- deleteFile(new File(VirtualFileManager.extractPath(urlIterator.next())));
- }
- }
- else if (compiler instanceof TranslatingCompiler) {
- final ArrayList> toDelete = new ArrayList>();
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- TranslatingCompilerFilesMonitor.getInstance().collectFiles(
- context,
- (TranslatingCompiler)compiler, Arrays.asList(allSources).iterator(),
- true /*pass true to make sure that every source in scope file is processed*/,
- false /*important! should pass false to enable collection of files to delete*/,
- new ArrayList(),
- toDelete
- );
- }
- });
- for (Trinity trinity : toDelete) {
- context.getProgressIndicator().checkCanceled();
- final File file = trinity.getFirst();
- deleteFile(file);
- if (isTestMode) {
- CompilerManagerImpl.addDeletedPath(file.getPath());
- }
- }
- }
- }
- catch (IOException e) {
- LOG.info(e);
- }
- }
- pruneEmptyDirectories(context.getProgressIndicator(), myAllOutputDirectories); // to avoid too much files deleted events
- }
- finally {
- CompilerUtil.refreshIODirectories(myAllOutputDirectories);
- }
- }
- dropScopesCaches();
-
- clearCompilerSystemDirectory(context);
- }
- });
- }
-
- private void dropScopesCaches() {
- // hack to be sure the classpath will include the output directories
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- ((ProjectRootManagerEx)ProjectRootManager.getInstance(myProject)).clearScopesCachesForModules();
- }
- });
- }
-
- private static void pruneEmptyDirectories(ProgressIndicator progress, final Set directories) {
- for (File directory : directories) {
- doPrune(progress, directory, directories);
- }
- }
-
- private static boolean doPrune(ProgressIndicator progress, final File directory, final Set outPutDirectories) {
- progress.checkCanceled();
- final File[] files = directory.listFiles();
- boolean isEmpty = true;
- if (files != null) {
- for (File file : files) {
- if (!outPutDirectories.contains(file)) {
- if (doPrune(progress, file, outPutDirectories)) {
- deleteFile(file);
- }
- else {
- isEmpty = false;
- }
- }
- else {
- isEmpty = false;
- }
- }
- }
- else {
- isEmpty = false;
- }
-
- return isEmpty;
- }
-
- private Set getAllOutputDirectories(CompileContext context) {
- final Set outputDirs = new OrderedSet((TObjectHashingStrategy)TObjectHashingStrategy.CANONICAL);
- final Module[] modules = ModuleManager.getInstance(myProject).getModules();
- for (final String path : CompilerPathsEx.getOutputPaths(modules)) {
- outputDirs.add(new File(path));
- }
- for (Pair pair : myGenerationCompilerModuleToOutputDirMap.keySet()) {
- outputDirs.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), false)));
- outputDirs.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), true)));
- }
- final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject);
- if (context.isAnnotationProcessorsEnabled()) {
- for (Module module : modules) {
- if (config.getAnnotationProcessingConfiguration(module).isEnabled()) {
- final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
- if (path != null) {
- outputDirs.add(new File(path));
- }
- }
- }
- }
- for (Artifact artifact : ArtifactManager.getInstance(myProject).getArtifacts()) {
- final String path = ((ArtifactImpl)artifact).getOutputDirectoryPathToCleanOnRebuild();
- if (path != null) {
- outputDirs.add(new File(FileUtil.toSystemDependentName(path)));
- }
- }
- return outputDirs;
- }
-
- private void clearCompilerSystemDirectory(final CompileContextEx context) {
- CompilerCacheManager.getInstance(myProject).clearCaches(context);
- FileUtil.delete(CompilerPathsEx.getZipStoreDirectory(myProject));
- dropDependencyCache(context);
-
- for (Pair pair : myGenerationCompilerModuleToOutputDirMap.keySet()) {
- final File[] outputs = {
- new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), false)),
- new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), true))
- };
- for (File output : outputs) {
- final File[] files = output.listFiles();
- if (files != null) {
- for (final File file : files) {
- final boolean deleteOk = deleteFile(file);
- if (!deleteOk) {
- context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.failed.to.delete", file.getPath()),
- null, -1, -1);
- }
- }
- }
- }
- }
- }
-
- /**
- * @param file a file to delete
- * @return true if and only if the file existed and was successfully deleted
- * Note: the behaviour is different from FileUtil.delete() which returns true if the file absent on the disk
- */
- private static boolean deleteFile(final File file) {
- File[] files = file.listFiles();
- if (files != null) {
- for (File file1 : files) {
- deleteFile(file1);
- }
- }
-
- for (int i = 0; i < 10; i++){
- if (file.delete()) {
- return true;
- }
- if (!file.exists()) {
- return false;
- }
- try {
- Thread.sleep(50);
- }
- catch (InterruptedException ignored) {
- }
- }
- return false;
- }
-
- private VirtualFile getGenerationOutputDir(final IntermediateOutputCompiler compiler, final Module module, final boolean forTestSources) {
- final Pair outputs =
- myGenerationCompilerModuleToOutputDirMap.get(new Pair(compiler, module));
- return forTestSources? outputs.getSecond() : outputs.getFirst();
- }
-
- private boolean generateOutput(final CompileContextEx context,
- final GeneratingCompiler compiler,
- final boolean forceGenerate,
- final boolean onlyCheckStatus) throws ExitException {
- final GeneratingCompiler.GenerationItem[] allItems = compiler.getGenerationItems(context);
- final List toGenerate = new ArrayList();
- final List filesToRefresh = new ArrayList();
- final List generatedFiles = new ArrayList();
- final List affectedModules = new ArrayList();
- try {
- final StateCache cache = getGeneratingCompilerCache(compiler);
- final Set pathsToRemove = new HashSet(cache.getUrls());
-
- final Map itemToOutputPathMap = new HashMap();
- final IOException[] ex = {null};
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- for (final GeneratingCompiler.GenerationItem item : allItems) {
- final Module itemModule = item.getModule();
- final String outputDirPath = CompilerPaths.getGenerationOutputPath(compiler, itemModule, item.isTestSource());
- final String outputPath = outputDirPath + "/" + item.getPath();
- itemToOutputPathMap.put(item, outputPath);
-
- try {
- final ValidityState savedState = cache.getState(outputPath);
-
- if (forceGenerate || savedState == null || !savedState.equalsTo(item.getValidityState())) {
- final String outputPathUrl = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, outputPath);
- if (context.getCompileScope().belongs(outputPathUrl)) {
- toGenerate.add(item);
- }
- else {
- pathsToRemove.remove(outputPath);
- }
- }
- else {
- pathsToRemove.remove(outputPath);
- }
- }
- catch (IOException e) {
- ex[0] = e;
- }
- }
- }
- });
- if (ex[0] != null) {
- throw ex[0];
- }
-
- if (onlyCheckStatus) {
- if (toGenerate.isEmpty() && pathsToRemove.isEmpty()) {
- return false;
- }
- if (LOG.isDebugEnabled()) {
- if (!toGenerate.isEmpty()) {
- LOG.debug("Found items to generate, compiler " + compiler.getDescription());
- }
- if (!pathsToRemove.isEmpty()) {
- LOG.debug("Found paths to remove, compiler " + compiler.getDescription());
- }
- }
- throw new ExitException(ExitStatus.CANCELLED);
- }
-
- if (!pathsToRemove.isEmpty()) {
- CompilerUtil.runInContext(context, CompilerBundle.message("progress.synchronizing.output.directory"), new ThrowableRunnable(){
- public void run() throws IOException {
- for (final String path : pathsToRemove) {
- final File file = new File(path);
- final boolean deleted = deleteFile(file);
- if (deleted) {
- cache.remove(path);
- filesToRefresh.add(file);
- }
- }
- }
- });
- }
-
- final Map> moduleToItemMap =
- buildModuleToGenerationItemMap(toGenerate.toArray(new GeneratingCompiler.GenerationItem[toGenerate.size()]));
- List modules = new ArrayList(moduleToItemMap.size());
- for (final Module module : moduleToItemMap.keySet()) {
- modules.add(module);
- }
- ModuleCompilerUtil.sortModules(myProject, modules);
-
- for (final Module module : modules) {
- CompilerUtil.runInContext(context, "Generating output from "+compiler.getDescription(),new ThrowableRunnable(){
- public void run() throws IOException {
- final Set items = moduleToItemMap.get(module);
- if (items != null && !items.isEmpty()) {
- final GeneratingCompiler.GenerationItem[][] productionAndTestItems = splitGenerationItems(items);
- for (GeneratingCompiler.GenerationItem[] _items : productionAndTestItems) {
- if (_items.length == 0) continue;
- final VirtualFile outputDir = getGenerationOutputDir(compiler, module, _items[0].isTestSource());
- final GeneratingCompiler.GenerationItem[] successfullyGenerated = compiler.generate(context, _items, outputDir);
-
- CompilerUtil.runInContext(context, CompilerBundle.message("progress.updating.caches"), new ThrowableRunnable() {
- public void run() throws IOException {
- if (successfullyGenerated.length > 0) {
- affectedModules.add(module);
- }
- for (final GeneratingCompiler.GenerationItem item : successfullyGenerated) {
- final String fullOutputPath = itemToOutputPathMap.get(item);
- cache.update(fullOutputPath, item.getValidityState());
- final File file = new File(fullOutputPath);
- filesToRefresh.add(file);
- generatedFiles.add(file);
- context.getProgressIndicator().setText2(file.getPath());
- }
- }
- });
- }
- }
- }
- });
- }
- }
- catch (IOException e) {
- LOG.info(e);
- context.requestRebuildNextTime(e.getMessage());
- throw new ExitException(ExitStatus.ERRORS);
- }
- finally {
- CompilerUtil.refreshIOFiles(filesToRefresh);
- if (!generatedFiles.isEmpty()) {
- DumbService.getInstance(myProject).waitForSmartMode();
- List vFiles = ApplicationManager.getApplication().runReadAction(new Computable>() {
- public List compute() {
- final ArrayList vFiles = new ArrayList(generatedFiles.size());
- for (File generatedFile : generatedFiles) {
- final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(generatedFile);
- if (vFile != null) {
- vFiles.add(vFile);
- }
- }
- return vFiles;
- }
- });
- if (forceGenerate) {
- context.addScope(new FileSetCompileScope(vFiles, affectedModules.toArray(new Module[affectedModules.size()])));
- }
- context.markGenerated(vFiles);
- }
- }
- return !toGenerate.isEmpty() || !filesToRefresh.isEmpty();
- }
-
- private static GeneratingCompiler.GenerationItem[][] splitGenerationItems(final Set items) {
- final List production = new ArrayList();
- final List tests = new ArrayList();
- for (GeneratingCompiler.GenerationItem item : items) {
- if (item.isTestSource()) {
- tests.add(item);
- }
- else {
- production.add(item);
- }
- }
- return new GeneratingCompiler.GenerationItem[][]{
- production.toArray(new GeneratingCompiler.GenerationItem[production.size()]),
- tests.toArray(new GeneratingCompiler.GenerationItem[tests.size()])
- };
- }
-
- private boolean compileSources(final CompileContextEx context,
- final Chunk moduleChunk,
- final TranslatingCompiler compiler,
- final Collection srcSnapshot,
- final boolean forceCompile,
- final boolean isRebuild,
- final boolean onlyCheckStatus,
- TranslatingCompiler.OutputSink sink) throws ExitException {
-
- final Set toCompile = new HashSet();
- final List> toDelete = new ArrayList>();
- context.getProgressIndicator().pushState();
-
- final boolean[] wereFilesDeleted = {false};
- try {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- TranslatingCompilerFilesMonitor.getInstance().collectFiles(
- context, compiler, srcSnapshot.iterator(), forceCompile, isRebuild, toCompile, toDelete
- );
- }
- });
-
- if (onlyCheckStatus) {
- if (toDelete.isEmpty() && toCompile.isEmpty()) {
- return false;
- }
- if (LOG.isDebugEnabled() || ourDebugMode) {
- if (!toDelete.isEmpty()) {
- final StringBuilder message = new StringBuilder();
- message.append("Found items to delete, compiler ").append(compiler.getDescription());
- for (Trinity trinity : toDelete) {
- message.append("\n").append(trinity.getFirst());
- }
- LOG.debug(message.toString());
- if (ourDebugMode) {
- System.out.println(message);
- }
- }
- if (!toCompile.isEmpty()) {
- final String message = "Found items to compile, compiler " + compiler.getDescription();
- LOG.debug(message);
- if (ourDebugMode) {
- System.out.println(message);
- }
- }
- }
- throw new ExitException(ExitStatus.CANCELLED);
- }
-
- if (!toDelete.isEmpty()) {
- try {
- wereFilesDeleted[0] = syncOutputDir(context, toDelete);
- }
- catch (CacheCorruptedException e) {
- LOG.info(e);
- context.requestRebuildNextTime(e.getMessage());
- }
- }
-
- if ((wereFilesDeleted[0] || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
- compiler.compile(context, moduleChunk, VfsUtil.toVirtualFileArray(toCompile), sink);
- }
- }
- finally {
- context.getProgressIndicator().popState();
- }
- return !toCompile.isEmpty() || wereFilesDeleted[0];
- }
-
- private static boolean syncOutputDir(final CompileContextEx context, final Collection> toDelete) throws CacheCorruptedException {
- final DependencyCache dependencyCache = context.getDependencyCache();
- final boolean isTestMode = ApplicationManager.getApplication().isUnitTestMode();
-
- final List filesToRefresh = new ArrayList();
- final boolean[] wereFilesDeleted = {false};
- CompilerUtil.runInContext(context, CompilerBundle.message("progress.synchronizing.output.directory"), new ThrowableRunnable(){
- public void run() throws CacheCorruptedException {
- final long start = System.currentTimeMillis();
- try {
- for (final Trinity trinity : toDelete) {
- final File outputPath = trinity.getFirst();
- context.getProgressIndicator().checkCanceled();
- context.getProgressIndicator().setText2(outputPath.getPath());
- filesToRefresh.add(outputPath);
- if (isTestMode) {
- LOG.assertTrue(outputPath.exists());
- }
- if (!deleteFile(outputPath)) {
- if (isTestMode) {
- if (outputPath.exists()) {
- LOG.error("Was not able to delete output file: " + outputPath.getPath());
- }
- else {
- CompilerManagerImpl.addDeletedPath(outputPath.getPath());
- }
- }
- continue;
- }
- wereFilesDeleted[0] = true;
-
- // update zip here
- //final String outputDir = myOutputFinder.lookupOutputPath(outputPath);
- //if (outputDir != null) {
- // try {
- // context.updateZippedOuput(outputDir, FileUtil.toSystemIndependentName(outputPath.getPath()).substring(outputDir.length() + 1));
- // }
- // catch (IOException e) {
- // LOG.info(e);
- // }
- //}
-
- final String className = trinity.getSecond();
- if (className != null) {
- final int id = dependencyCache.getSymbolTable().getId(className);
- dependencyCache.addTraverseRoot(id);
- final boolean sourcePresent = trinity.getThird().booleanValue();
- if (!sourcePresent) {
- dependencyCache.markSourceRemoved(id);
- }
- }
- if (isTestMode) {
- CompilerManagerImpl.addDeletedPath(outputPath.getPath());
- }
- }
- }
- finally {
- CompilerUtil.logDuration("Sync output directory", System.currentTimeMillis() - start);
- CompilerUtil.refreshIOFiles(filesToRefresh);
- }
- }
- });
- return wereFilesDeleted[0];
- }
-
- // [mike] performance optimization - this method is accessed > 15,000 times in Aurora
- private String getModuleOutputPath(final Module module, boolean inTestSourceContent) {
- final Map map = inTestSourceContent ? myModuleTestOutputPaths : myModuleOutputPaths;
- String path = map.get(module);
- if (path == null) {
- path = CompilerPaths.getModuleOutputPath(module, inTestSourceContent);
- map.put(module, path);
- }
-
- return path;
- }
-
- private boolean processFiles(final FileProcessingCompilerAdapter adapter,
- final boolean forceCompile,
- final boolean checkScope,
- final boolean onlyCheckStatus, final CacheDeferredUpdater cacheUpdater) throws ExitException, IOException {
- final CompileContextEx context = (CompileContextEx)adapter.getCompileContext();
- final FileProcessingCompilerStateCache cache = getFileProcessingCompilerCache(adapter.getCompiler());
- final FileProcessingCompiler.ProcessingItem[] items = adapter.getProcessingItems();
- if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
- return false;
- }
- if (LOG.isDebugEnabled() && items.length > 0) {
- LOG.debug("Start processing files by " + adapter.getCompiler().getDescription());
- }
- final CompileScope scope = context.getCompileScope();
- final List toProcess = new ArrayList();
- final Set allUrls = new HashSet();
- final IOException[] ex = {null};
- DumbService.getInstance(myProject).waitForSmartMode();
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- try {
- for (FileProcessingCompiler.ProcessingItem item : items) {
- final VirtualFile file = item.getFile();
- final String url = file.getUrl();
- allUrls.add(url);
- if (!forceCompile && cache.getTimestamp(url) == file.getTimeStamp()) {
- final ValidityState state = cache.getExtState(url);
- final ValidityState itemState = item.getValidityState();
- if (state != null ? state.equalsTo(itemState) : itemState == null) {
- continue;
- }
- }
- if (LOG.isDebugEnabled()) {
- LOG.debug("Adding item to process: " + url + "; saved ts= " + cache.getTimestamp(url) + "; VFS ts=" + file.getTimeStamp());
- }
- toProcess.add(item);
- }
- }
- catch (IOException e) {
- ex[0] = e;
- }
- }
- });
-
- if (ex[0] != null) {
- throw ex[0];
- }
-
- final Collection urls = cache.getUrls();
- final List urlsToRemove = new ArrayList();
- if (!urls.isEmpty()) {
- CompilerUtil.runInContext(context, CompilerBundle.message("progress.processing.outdated.files"), new ThrowableRunnable(){
- public void run() throws IOException {
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- for (final String url : urls) {
- if (!allUrls.contains(url)) {
- if (!checkScope || scope.belongs(url)) {
- urlsToRemove.add(url);
- }
- }
- }
- }
- });
- if (!onlyCheckStatus && !urlsToRemove.isEmpty()) {
- for (final String url : urlsToRemove) {
- adapter.processOutdatedItem(context, url, cache.getExtState(url));
- cache.remove(url);
- }
- }
- }
- });
- }
-
- if (onlyCheckStatus) {
- if (urlsToRemove.isEmpty() && toProcess.isEmpty()) {
- return false;
- }
- if (LOG.isDebugEnabled()) {
- if (!urlsToRemove.isEmpty()) {
- LOG.debug("Found urls to remove, compiler " + adapter.getCompiler().getDescription());
- for (String url : urlsToRemove) {
- LOG.debug("\t" + url);
- }
- }
- if (!toProcess.isEmpty()) {
- LOG.debug("Found items to compile, compiler " + adapter.getCompiler().getDescription());
- for (FileProcessingCompiler.ProcessingItem item : toProcess) {
- LOG.debug("\t" + item.getFile().getPresentableUrl());
- }
- }
- }
- throw new ExitException(ExitStatus.CANCELLED);
- }
-
- if (toProcess.isEmpty()) {
- return false;
- }
-
- final FileProcessingCompiler.ProcessingItem[] processed =
- adapter.process(toProcess.toArray(new FileProcessingCompiler.ProcessingItem[toProcess.size()]));
-
- if (processed.length == 0) {
- return true;
- }
- CompilerUtil.runInContext(context, CompilerBundle.message("progress.updating.caches"), new ThrowableRunnable() {
- public void run() {
- final List vFiles = new ArrayList(processed.length);
- for (FileProcessingCompiler.ProcessingItem aProcessed : processed) {
- final VirtualFile file = aProcessed.getFile();
- vFiles.add(file);
- if (LOG.isDebugEnabled()) {
- LOG.debug("\tFile processed " + file.getPresentableUrl() + "; ts=" + file.getTimeStamp());
- }
-
- //final String path = file.getPath();
- //final String outputDir = myOutputFinder.lookupOutputPath(path);
- //if (outputDir != null) {
- // context.updateZippedOuput(outputDir, path.substring(outputDir.length() + 1));
- //}
- }
- LocalFileSystem.getInstance().refreshFiles(vFiles);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Files after VFS refresh:");
- for (VirtualFile file : vFiles) {
- LOG.debug("\t" + file.getPresentableUrl() + "; ts=" + file.getTimeStamp());
- }
- }
- for (FileProcessingCompiler.ProcessingItem item : processed) {
- cacheUpdater.addFileForUpdate(item, cache);
- }
- }
- });
- return true;
- }
-
- private FileProcessingCompilerStateCache getFileProcessingCompilerCache(FileProcessingCompiler compiler) throws IOException {
- return CompilerCacheManager.getInstance(myProject).getFileProcessingCompilerCache(compiler);
- }
-
- private StateCache getGeneratingCompilerCache(final GeneratingCompiler compiler) throws IOException {
- return CompilerCacheManager.getInstance(myProject).getGeneratingCompilerCache(compiler);
- }
-
- public void executeCompileTask(final CompileTask task, final CompileScope scope, final String contentName, final Runnable onTaskFinished) {
- final CompilerTask progressManagerTask =
- new CompilerTask(myProject, true, contentName, false);
- final CompileContextImpl compileContext = new CompileContextImpl(myProject, progressManagerTask, scope, null, false, false);
-
- FileDocumentManager.getInstance().saveAllDocuments();
-
- progressManagerTask.start(new Runnable() {
- public void run() {
- try {
- task.execute(compileContext);
- }
- catch (ProcessCanceledException ex) {
- // suppressed
- }
- finally {
- if (onTaskFinished != null) {
- onTaskFinished.run();
- }
- }
- }
- }, null);
- }
-
- private boolean executeCompileTasks(final CompileContext context, final boolean beforeTasks) {
- final CompilerManager manager = CompilerManager.getInstance(myProject);
- final ProgressIndicator progressIndicator = context.getProgressIndicator();
- progressIndicator.pushState();
- try {
- CompileTask[] tasks = beforeTasks ? manager.getBeforeTasks() : manager.getAfterTasks();
- if (tasks.length > 0) {
- progressIndicator.setText(beforeTasks
- ? CompilerBundle.message("progress.executing.precompile.tasks")
- : CompilerBundle.message("progress.executing.postcompile.tasks"));
- for (CompileTask task : tasks) {
- if (!task.execute(context)) {
- return false;
- }
- }
- }
- }
- finally {
- progressIndicator.popState();
- WindowManager.getInstance().getStatusBar(myProject).setInfo("");
- if (progressIndicator instanceof CompilerTask) {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- public void run() {
- ((CompilerTask)progressIndicator).showCompilerContent();
- }
- });
- }
- }
- return true;
- }
-
- private boolean validateCompilerConfiguration(final CompileScope scope, boolean checkOutputAndSourceIntersection) {
- try {
- final Module[] scopeModules = scope.getAffectedModules()/*ModuleManager.getInstance(myProject).getModules()*/;
- final List modulesWithoutOutputPathSpecified = new ArrayList();
- boolean isProjectCompilePathSpecified = true;
- final List modulesWithoutJdkAssigned = new ArrayList();
- final Set nonExistingOutputPaths = new HashSet();
- final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject);
- final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
- for (final Module module : scopeModules) {
- if (!compilerManager.isValidationEnabled(module)) {
- continue;
- }
- final boolean hasSources = hasSources(module, false);
- final boolean hasTestSources = hasSources(module, true);
- if (!hasSources && !hasTestSources) {
- // If module contains no sources, shouldn't have to select JDK or output directory (SCR #19333)
- // todo still there may be problems with this approach if some generated files are attributed by this module
- continue;
- }
- final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
- if (jdk == null) {
- modulesWithoutJdkAssigned.add(module.getName());
- }
- final String outputPath = getModuleOutputPath(module, false);
- final String testsOutputPath = getModuleOutputPath(module, true);
- if (outputPath == null && testsOutputPath == null) {
- modulesWithoutOutputPathSpecified.add(module.getName());
- }
- else {
- if (outputPath != null) {
- final File file = new File(outputPath.replace('/', File.separatorChar));
- if (!file.exists()) {
- nonExistingOutputPaths.add(file);
- }
- }
- else {
- if (hasSources) {
- modulesWithoutOutputPathSpecified.add(module.getName());
- }
- }
- if (testsOutputPath != null) {
- final File f = new File(testsOutputPath.replace('/', File.separatorChar));
- if (!f.exists()) {
- nonExistingOutputPaths.add(f);
- }
- }
- else {
- if (hasTestSources) {
- modulesWithoutOutputPathSpecified.add(module.getName());
- }
- }
- if (!useOutOfProcessBuild()) {
- if (config.getAnnotationProcessingConfiguration(module).isEnabled()) {
- final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
- if (path == null) {
- final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(module.getProject());
- if (extension == null || extension.getCompilerOutputUrl() == null) {
- isProjectCompilePathSpecified = false;
- }
- else {
- modulesWithoutOutputPathSpecified.add(module.getName());
- }
- }
- else {
- final File file = new File(path);
- if (!file.exists()) {
- nonExistingOutputPaths.add(file);
- }
- }
- }
- }
- }
- }
- if (!modulesWithoutJdkAssigned.isEmpty()) {
- showNotSpecifiedError("error.jdk.not.specified", modulesWithoutJdkAssigned, ProjectBundle.message("modules.classpath.title"));
- return false;
- }
-
- if (!isProjectCompilePathSpecified) {
- final String message = CompilerBundle.message("error.project.output.not.specified");
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- LOG.error(message);
- }
-
- Messages.showMessageDialog(myProject, message, CommonBundle.getErrorTitle(), Messages.getErrorIcon());
- ProjectSettingsService.getInstance(myProject).openProjectSettings();
- return false;
- }
-
- if (!modulesWithoutOutputPathSpecified.isEmpty()) {
- showNotSpecifiedError("error.output.not.specified", modulesWithoutOutputPathSpecified, CommonContentEntriesEditor.NAME);
- return false;
- }
-
- if (!nonExistingOutputPaths.isEmpty()) {
- for (File file : nonExistingOutputPaths) {
- final boolean succeeded = file.mkdirs();
- if (!succeeded) {
- if (file.exists()) {
- // for overlapping paths, this one might have been created as an intermediate path on a previous iteration
- continue;
- }
- Messages.showMessageDialog(myProject, CompilerBundle.message("error.failed.to.create.directory", file.getPath()),
- CommonBundle.getErrorTitle(), Messages.getErrorIcon());
- return false;
- }
- }
- final Boolean refreshSuccess =
- new WriteAction() {
- @Override
- protected void run(Result result) throws Throwable {
- LocalFileSystem.getInstance().refreshIoFiles(nonExistingOutputPaths);
- Boolean res = Boolean.TRUE;
- for (File file : nonExistingOutputPaths) {
- if (LocalFileSystem.getInstance().findFileByIoFile(file) == null) {
- res = Boolean.FALSE;
- break;
- }
- }
- result.setResult(res);
- }
- }.execute().getResultObject();
-
- if (!refreshSuccess.booleanValue()) {
- return false;
- }
- dropScopesCaches();
- }
-
- if (checkOutputAndSourceIntersection && myShouldClearOutputDirectory) {
- if (!validateOutputAndSourcePathsIntersection()) {
- return false;
- }
- // myShouldClearOutputDirectory may change in validateOutputAndSourcePathsIntersection()
- CompilerPathsEx.CLEAR_ALL_OUTPUTS_KEY.set(scope, myShouldClearOutputDirectory);
- }
- else {
- CompilerPathsEx.CLEAR_ALL_OUTPUTS_KEY.set(scope, false);
- }
- final List> chunks = ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(scopeModules));
- for (final Chunk chunk : chunks) {
- final Set chunkModules = chunk.getNodes();
- if (chunkModules.size() <= 1) {
- continue; // no need to check one-module chunks
- }
- for (Module chunkModule : chunkModules) {
- if (config.getAnnotationProcessingConfiguration(chunkModule).isEnabled()) {
- showCyclesNotSupportedForAnnotationProcessors(chunkModules.toArray(new Module[chunkModules.size()]));
- return false;
- }
- }
- Sdk jdk = null;
- LanguageLevel languageLevel = null;
- for (final Module module : chunkModules) {
- final Sdk moduleJdk = ModuleRootManager.getInstance(module).getSdk();
- if (jdk == null) {
- jdk = moduleJdk;
- }
- else {
- if (!jdk.equals(moduleJdk)) {
- showCyclicModulesHaveDifferentJdksError(chunkModules.toArray(new Module[chunkModules.size()]));
- return false;
- }
- }
-
- LanguageLevel moduleLanguageLevel = LanguageLevelUtil.getEffectiveLanguageLevel(module);
- if (languageLevel == null) {
- languageLevel = moduleLanguageLevel;
- }
- else {
- if (!languageLevel.equals(moduleLanguageLevel)) {
- showCyclicModulesHaveDifferentLanguageLevel(chunkModules.toArray(new Module[chunkModules.size()]));
- return false;
- }
- }
- }
- }
- final Compiler[] allCompilers = compilerManager.getCompilers(Compiler.class);
- for (Compiler compiler : allCompilers) {
- if (!compiler.validateConfiguration(scope)) {
- return false;
- }
- }
- return true;
- }
- catch (Throwable e) {
- LOG.info(e);
- return false;
- }
- }
-
- private boolean useOutOfProcessBuild() {
- return CompilerWorkspaceConfiguration.getInstance(myProject).useOutOfProcessBuild();
- }
-
- private void showCyclicModulesHaveDifferentLanguageLevel(Module[] modulesInChunk) {
- LOG.assertTrue(modulesInChunk.length > 0);
- String moduleNameToSelect = modulesInChunk[0].getName();
- final String moduleNames = getModulesString(modulesInChunk);
- Messages.showMessageDialog(myProject, CompilerBundle.message("error.chunk.modules.must.have.same.language.level", moduleNames),
- CommonBundle.getErrorTitle(), Messages.getErrorIcon());
- showConfigurationDialog(moduleNameToSelect, null);
- }
-
- private void showCyclicModulesHaveDifferentJdksError(Module[] modulesInChunk) {
- LOG.assertTrue(modulesInChunk.length > 0);
- String moduleNameToSelect = modulesInChunk[0].getName();
- final String moduleNames = getModulesString(modulesInChunk);
- Messages.showMessageDialog(myProject, CompilerBundle.message("error.chunk.modules.must.have.same.jdk", moduleNames),
- CommonBundle.getErrorTitle(), Messages.getErrorIcon());
- showConfigurationDialog(moduleNameToSelect, null);
- }
-
- private void showCyclesNotSupportedForAnnotationProcessors(Module[] modulesInChunk) {
- LOG.assertTrue(modulesInChunk.length > 0);
- String moduleNameToSelect = modulesInChunk[0].getName();
- final String moduleNames = getModulesString(modulesInChunk);
- Messages.showMessageDialog(myProject, CompilerBundle.message("error.annotation.processing.not.supported.for.module.cycles", moduleNames),
- CommonBundle.getErrorTitle(), Messages.getErrorIcon());
- showConfigurationDialog(moduleNameToSelect, null);
- }
-
- private static String getModulesString(Module[] modulesInChunk) {
- final StringBuilder moduleNames = StringBuilderSpinAllocator.alloc();
- try {
- for (Module module : modulesInChunk) {
- if (moduleNames.length() > 0) {
- moduleNames.append("\n");
- }
- moduleNames.append("\"").append(module.getName()).append("\"");
- }
- return moduleNames.toString();
- }
- finally {
- StringBuilderSpinAllocator.dispose(moduleNames);
- }
- }
-
- private static boolean hasSources(Module module, boolean checkTestSources) {
- final ContentEntry[] contentEntries = ModuleRootManager.getInstance(module).getContentEntries();
- for (final ContentEntry contentEntry : contentEntries) {
- final SourceFolder[] sourceFolders = contentEntry.getSourceFolders();
- for (final SourceFolder sourceFolder : sourceFolders) {
- if (sourceFolder.getFile() == null) {
- continue; // skip invalid source folders
- }
- if (checkTestSources) {
- if (sourceFolder.isTestSource()) {
- return true;
- }
- }
- else {
- if (!sourceFolder.isTestSource()) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- private void showNotSpecifiedError(@NonNls final String resourceId, List modules, String editorNameToSelect) {
- String nameToSelect = null;
- final StringBuilder names = StringBuilderSpinAllocator.alloc();
- final String message;
- try {
- final int maxModulesToShow = 10;
- for (String name : modules.size() > maxModulesToShow ? modules.subList(0, maxModulesToShow) : modules) {
- if (nameToSelect == null) {
- nameToSelect = name;
- }
- if (names.length() > 0) {
- names.append(",\n");
- }
- names.append("\"");
- names.append(name);
- names.append("\"");
- }
- if (modules.size() > maxModulesToShow) {
- names.append(",\n...");
- }
- message = CompilerBundle.message(resourceId, modules.size(), names.toString());
- }
- finally {
- StringBuilderSpinAllocator.dispose(names);
- }
-
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- LOG.error(message);
- }
-
- Messages.showMessageDialog(myProject, message, CommonBundle.getErrorTitle(), Messages.getErrorIcon());
- showConfigurationDialog(nameToSelect, editorNameToSelect);
- }
-
- private boolean validateOutputAndSourcePathsIntersection() {
- final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
- List allOutputs = new ArrayList();
- ContainerUtil.addAll(allOutputs, CompilerPathsEx.getOutputDirectories(allModules));
- for (Artifact artifact : ArtifactManager.getInstance(myProject).getArtifacts()) {
- ContainerUtil.addIfNotNull(artifact.getOutputFile(), allOutputs);
- }
- final Set affectedOutputPaths = new HashSet();
- CompilerUtil.computeIntersectingPaths(myProject, allOutputs, affectedOutputPaths);
- affectedOutputPaths.addAll(ArtifactCompilerUtil.getArtifactOutputsContainingSourceFiles(myProject));
-
- if (!affectedOutputPaths.isEmpty()) {
- if (CompilerUtil.askUserToContinueWithNoClearing(myProject, affectedOutputPaths)) {
- myShouldClearOutputDirectory = false;
- return true;
- }
- else {
- return false;
- }
- }
- return true;
- }
-
- private void showConfigurationDialog(String moduleNameToSelect, String tabNameToSelect) {
- ProjectSettingsService.getInstance(myProject).showModuleConfigurationDialog(moduleNameToSelect, tabNameToSelect);
- }
-
- private static VirtualFile lookupVFile(final LocalFileSystem lfs, final String path) {
- final File file = new File(path);
-
- VirtualFile vFile = lfs.findFileByIoFile(file);
- if (vFile != null) {
- return vFile;
- }
-
- final boolean justCreated = file.mkdirs();
- vFile = lfs.refreshAndFindFileByIoFile(file);
-
- if (vFile == null) {
- assert false: "Virtual file not found for " + file.getPath() + "; mkdirs() exit code is " + justCreated + "; file exists()? " + file.exists();
- }
-
- return vFile;
- }
-
- private static class CacheDeferredUpdater {
- private final Map>> myData = new java.util.HashMap>>();
-
- public void addFileForUpdate(final FileProcessingCompiler.ProcessingItem item, FileProcessingCompilerStateCache cache) {
- final VirtualFile file = item.getFile();
- List> list = myData.get(file);
- if (list == null) {
- list = new ArrayList>();
- myData.put(file, list);
- }
- list.add(new Pair(cache, item));
- }
-
- public void doUpdate() throws IOException{
- final IOException[] ex = {null};
- ApplicationManager.getApplication().runReadAction(new Runnable() {
- public void run() {
- try {
- for (Map.Entry>> entry : myData.entrySet()) {
- for (Pair pair : entry.getValue()) {
- final FileProcessingCompiler.ProcessingItem item = pair.getSecond();
- pair.getFirst().update(entry.getKey(), item.getValidityState());
- }
- }
- }
- catch (IOException e) {
- ex[0] = e;
- }
- }
- });
- if (ex[0] != null) {
- throw ex[0];
- }
- }
- }
-
- private static class TranslatorsOutputSink implements TranslatingCompiler.OutputSink {
- final Map> myPostponedItems = new HashMap>();
- private final CompileContextEx myContext;
- private final TranslatingCompiler[] myCompilers;
- private int myCurrentCompilerIdx;
- private final Set myCompiledSources = new HashSet();
- //private LinkedBlockingQueue myFutures = new LinkedBlockingQueue();
-
- private TranslatorsOutputSink(CompileContextEx context, TranslatingCompiler[] compilers) {
- myContext = context;
- myCompilers = compilers;
- }
-
- public void setCurrentCompilerIndex(int index) {
- myCurrentCompilerIdx = index;
- }
-
- public Set getCompiledSources() {
- return Collections.unmodifiableSet(myCompiledSources);
- }
-
- public void add(final String outputRoot, final Collection items, final VirtualFile[] filesToRecompile) {
- for (TranslatingCompiler.OutputItem item : items) {
- final VirtualFile file = item.getSourceFile();
- if (file != null) {
- myCompiledSources.add(file);
- }
- }
- final TranslatingCompiler compiler = myCompilers[myCurrentCompilerIdx];
- if (compiler instanceof IntermediateOutputCompiler) {
- final LocalFileSystem lfs = LocalFileSystem.getInstance();
- final List outputs = new ArrayList();
- for (TranslatingCompiler.OutputItem item : items) {
- final VirtualFile vFile = lfs.findFileByPath(item.getOutputPath());
- if (vFile != null) {
- outputs.add(vFile);
- }
- }
- myContext.markGenerated(outputs);
- }
- final int nextCompilerIdx = myCurrentCompilerIdx + 1;
- try {
- if (nextCompilerIdx < myCompilers.length ) {
- final Map> updateNow = new java.util.HashMap>();
- // process postponed
- for (Map.Entry> entry : myPostponedItems.entrySet()) {
- final String outputDir = entry.getKey();
- final Collection postponed = entry.getValue();
- for (Iterator it = postponed.iterator(); it.hasNext();) {
- TranslatingCompiler.OutputItem item = it.next();
- boolean shouldPostpone = false;
- for (int idx = nextCompilerIdx; idx < myCompilers.length; idx++) {
- shouldPostpone = myCompilers[idx].isCompilableFile(item.getSourceFile(), myContext);
- if (shouldPostpone) {
- break;
- }
- }
- if (!shouldPostpone) {
- // the file is not compilable by the rest of compilers, so it is safe to update it now
- it.remove();
- addItemToMap(updateNow, outputDir, item);
- }
- }
- }
- // process items from current compilation
- for (TranslatingCompiler.OutputItem item : items) {
- boolean shouldPostpone = false;
- for (int idx = nextCompilerIdx; idx < myCompilers.length; idx++) {
- shouldPostpone = myCompilers[idx].isCompilableFile(item.getSourceFile(), myContext);
- if (shouldPostpone) {
- break;
- }
- }
- if (shouldPostpone) {
- // the file is compilable by the next compiler in row, update should be postponed
- addItemToMap(myPostponedItems, outputRoot, item);
- }
- else {
- addItemToMap(updateNow, outputRoot, item);
- }
- }
-
- if (updateNow.size() == 1) {
- final Map.Entry> entry = updateNow.entrySet().iterator().next();
- final String outputDir = entry.getKey();
- final Collection itemsToUpdate = entry.getValue();
- TranslatingCompilerFilesMonitor.getInstance().update(myContext, outputDir, itemsToUpdate, filesToRecompile);
- }
- else {
- for (Map.Entry> entry : updateNow.entrySet()) {
- final String outputDir = entry.getKey();
- final Collection itemsToUpdate = entry.getValue();
- TranslatingCompilerFilesMonitor.getInstance().update(myContext, outputDir, itemsToUpdate, VirtualFile.EMPTY_ARRAY);
- }
- if (filesToRecompile.length > 0) {
- TranslatingCompilerFilesMonitor.getInstance().update(myContext, null, Collections.emptyList(), filesToRecompile);
- }
- }
- }
- else {
- TranslatingCompilerFilesMonitor.getInstance().update(myContext, outputRoot, items, filesToRecompile);
- }
- }
- catch (IOException e) {
- LOG.info(e);
- myContext.requestRebuildNextTime(e.getMessage());
- }
- }
-
- private static void addItemToMap(Map> map, String outputDir, TranslatingCompiler.OutputItem item) {
- Collection collection = map.get(outputDir);
- if (collection == null) {
- collection = new ArrayList();
- map.put(outputDir, collection);
- }
- collection.add(item);
- }
-
- public void flushPostponedItems() {
- final TranslatingCompilerFilesMonitor filesMonitor = TranslatingCompilerFilesMonitor.getInstance();
- try {
- for (Map.Entry> entry : myPostponedItems.entrySet()) {
- final String outputDir = entry.getKey();
- final Collection items = entry.getValue();
- filesMonitor.update(myContext, outputDir, items, VirtualFile.EMPTY_ARRAY);
- }
- }
- catch (IOException e) {
- LOG.info(e);
- myContext.requestRebuildNextTime(e.getMessage());
- }
- }
- }
-
- private static class DependentClassesCumulativeFilter implements Function>, Pair>> {
-
- private final TIntHashSet myProcessedNames = new TIntHashSet();
- private final Set