diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index c883baebc48c..aabceb3d9fed 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -648,6 +648,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 77fc541298b1..d7412724d55b 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -88,6 +88,7 @@
+
diff --git a/RegExpSupport/src/org/intellij/lang/regexp/DefaultRegExpPropertiesProvider.java b/RegExpSupport/src/org/intellij/lang/regexp/DefaultRegExpPropertiesProvider.java
index 520d9542668e..1b94fc0c97c4 100644
--- a/RegExpSupport/src/org/intellij/lang/regexp/DefaultRegExpPropertiesProvider.java
+++ b/RegExpSupport/src/org/intellij/lang/regexp/DefaultRegExpPropertiesProvider.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.intellij.lang.regexp;
import com.intellij.openapi.util.text.StringUtil;
@@ -134,22 +149,21 @@ public final class DefaultRegExpPropertiesProvider {
}
public boolean isValidCategory(@NotNull String category) {
- if (category.startsWith("In")) {
- try {
- return Character.UnicodeBlock.forName(category.substring(2)) != null;
- } catch (IllegalArgumentException e) {
- return false;
- }
+ if (category.startsWith("In")) {
+ try {
+ return Character.UnicodeBlock.forName(category.substring(2)) != null;
}
- if (category.startsWith("Is")) {
- category = category.substring(2);
+ catch (IllegalArgumentException e) {
+ return false;
}
- for (String[] name : myPropertyNames) {
- if (name[0].equals(category)) {
- return true;
- }
+ }
+ category = StringUtil.trimStart(category, "Is");
+ for (String[] name : myPropertyNames) {
+ if (name[0].equals(category)) {
+ return true;
}
- return false;
+ }
+ return false;
}
@Nullable
diff --git a/build/conf/classVersions.txt b/build/conf/classVersions.txt
index b42573e0be0a..639a4e8503c7 100644
--- a/build/conf/classVersions.txt
+++ b/build/conf/classVersions.txt
@@ -44,6 +44,8 @@
1.8 => redist/annotations-java8.jar
1.3 => plugins/junit/lib/junit-rt.jar
+1.6 => lib/external-system-rt.jar
+
1.6 => plugins/gradle/lib/gradle-tooling-extension-api.jar
1.6 => plugins/gradle/lib/gradle-tooling-extension-impl.jar
diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant
index da1fbd1fd875..22b39bcc16de 100644
--- a/build/scripts/layouts.gant
+++ b/build/scripts/layouts.gant
@@ -181,6 +181,8 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir
jar("extensions.jar") { module("extensions")}
+ jar("external-system-rt.jar") { module("external-system-rt")}
+
jar([name: "idea.jar", duplicate: "preserve"]) {
implementationModules.each { module it}
}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkClasspath.java b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkClasspath.java
index 0883913855ae..926fc39375fb 100644
--- a/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkClasspath.java
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkClasspath.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -21,6 +21,7 @@ import com.intellij.compiler.ant.taskdefs.PathRef;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.ArrayUtil;
@@ -163,9 +164,7 @@ public class ModuleChunkClasspath extends Path {
// Module source entry?
for (String url : getCompilationClasses(module, ((GenerationOptionsImpl)genOptions), generateRuntimeClasspath,
generateTestClasspath, dependencyLevel == 0)) {
- if (url.endsWith(JarFileSystem.JAR_SEPARATOR)) {
- url = url.substring(0, url.length() - JarFileSystem.JAR_SEPARATOR.length());
- }
+ url = StringUtil.trimEnd(url, JarFileSystem.JAR_SEPARATOR);
final String propertyRef = genOptions.getPropertyRefForUrl(url);
if (propertyRef != null) {
pathItems.add(new PathElementItem(propertyRef));
diff --git a/java/java-impl/src/com/intellij/internal/UsedIconsListingAction.java b/java/java-impl/src/com/intellij/internal/UsedIconsListingAction.java
index 293819bf63be..65eb2d2c54bc 100644
--- a/java/java-impl/src/com/intellij/internal/UsedIconsListingAction.java
+++ b/java/java-impl/src/com/intellij/internal/UsedIconsListingAction.java
@@ -29,6 +29,7 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -89,9 +90,7 @@ public class UsedIconsListingAction extends AnAction {
String str = (String)value;
if (str.startsWith("\"")) {
str = str.substring(0);
- if (str.endsWith("\"")) {
- str = str.substring(0, str.length() - 1);
- }
+ str = StringUtil.trimEnd(str, "\"");
}
if (!str.startsWith("/")) {
diff --git a/java/java-impl/src/com/intellij/unscramble/UnscrambleListener.java b/java/java-impl/src/com/intellij/unscramble/UnscrambleListener.java
index 156fe4c2eda3..f0e279528494 100644
--- a/java/java-impl/src/com/intellij/unscramble/UnscrambleListener.java
+++ b/java/java-impl/src/com/intellij/unscramble/UnscrambleListener.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.util.Alarm;
@@ -77,9 +78,7 @@ public class UnscrambleListener extends ApplicationActivationListener.Adapter {
for (String line : stacktrace.split("\n")) {
line = line.trim();
if (line.length() == 0) continue;
- if (line.endsWith("\r")) {
- line = line.substring(0, line.length() - 1);
- }
+ line = StringUtil.trimEnd(line, "\r");
if (STACKTRACE_LINE.matcher(line).matches()) {
linesCount++;
}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java
index 60f56a4a96c5..5b68a03f362b 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java
@@ -40,6 +40,7 @@ import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
import com.intellij.codeInspection.htmlInspections.RequiredAttributesInspectionBase;
import com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection;
import com.intellij.diagnostic.PerformanceWatcher;
+import com.intellij.diagnostic.ThreadDumper;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
@@ -2118,13 +2119,19 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
}
private void waitForDaemon() {
- long deadline = System.currentTimeMillis() + 10000;
+ long deadline = System.currentTimeMillis() + 60_000;
while (!myDaemonCodeAnalyzer.isRunning()) {
- if (System.currentTimeMillis() > deadline) fail("Too long waiting for daemon to start");
+ if (System.currentTimeMillis() > deadline) {
+ System.out.println(ThreadDumper.dumpThreadsToString());
+ fail("Too long waiting for daemon to start");
+ }
UIUtil.dispatchAllInvocationEvents();
}
while (myDaemonCodeAnalyzer.isRunning()) {
- if (System.currentTimeMillis() > deadline) fail("Too long waiting for daemon to finish");
+ if (System.currentTimeMillis() > deadline) {
+ System.out.println(ThreadDumper.dumpThreadsToString());
+ fail("Too long waiting for daemon to finish");
+ }
UIUtil.dispatchAllInvocationEvents();
}
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentTest.java
index beed9ac5521a..f5266d02c9bf 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/IndentTest.java
@@ -149,17 +149,13 @@ public class IndentTest extends LightIdeaTestCase {
});
}
}, null, null);
-
+
String textAfter = loadFile(fileNameAfter);
String fileText = file.getText();
- if (textAfter.startsWith("\n")) {
- textAfter = textAfter.substring(1);
- }
- if (fileText.startsWith("\n")) {
- fileText = fileText.substring(1);
- }
-
+ textAfter = StringUtil.trimStart(textAfter, "\n");
+ fileText = StringUtil.trimStart(fileText, "\n");
+
assertEquals(textAfter, fileText);
}
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/TabIndentingTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/TabIndentingTest.java
index 7644c9dcbc2a..03ea132fa4ee 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/TabIndentingTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/TabIndentingTest.java
@@ -128,7 +128,7 @@ public class TabIndentingTest extends LightIdeaTestCase {
doTest("SCR6197.java", "SCR6197_after.java");
}
- private void doTest(String fileNameBefore, String fileNameAfter) throws Exception{
+ private void doTest(String fileNameBefore, String fileNameAfter) throws Exception {
String text = loadFile(fileNameBefore);
final PsiFile file = createFile(fileNameBefore, text);
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
@@ -147,18 +147,14 @@ public class TabIndentingTest extends LightIdeaTestCase {
});
}
}, null, null);
-
+
String textAfter = loadFile(fileNameAfter);
String fileText = file.getText();
- if (textAfter.startsWith("\n")) {
- textAfter = textAfter.substring(1);
- }
- if (fileText.startsWith("\n")) {
- fileText = fileText.substring(1);
- }
-
+ textAfter = StringUtil.trimStart(textAfter, "\n");
+ fileText = StringUtil.trimStart(fileText, "\n");
+
if (!textAfter.equals(fileText)) {
System.err.println("Expected:");
System.err.println(textAfter);
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/WrapperTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/WrapperTest.java
index 5a0508f89447..fa747d2720c4 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/WrapperTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/WrapperTest.java
@@ -17,6 +17,7 @@ package com.intellij.psi.formatter.java;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
public class WrapperTest extends JavaFormatterTestCase {
@@ -28,9 +29,7 @@ public class WrapperTest extends JavaFormatterTestCase {
@Override
protected String prepareText(final String text) {
String result = text;
- if (result.startsWith("\n")) {
- result = result.substring(1);
- }
+ result = StringUtil.trimStart(result, "\n");
return result;
}
diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
index f429d0ede370..0afd2d66a48d 100644
--- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
+++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
@@ -308,9 +308,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
List streamsToClose = new ArrayList();
for (String relativePath : relativePaths) {
- if (relativePath.startsWith("/")) {
- relativePath = relativePath.substring(1);
- }
+ relativePath = StringUtil.trimStart(relativePath, "/");
final VirtualFile fromFile = fromDir.findFileByRelativePath(relativePath);
assertNotNull(fromDir.getPath() + "/" + relativePath, fromFile);
VirtualFile toFile = toDir.findFileByRelativePath(relativePath);
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
index 768baa78943a..78fb3318f714 100644
--- a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
@@ -17,6 +17,7 @@ package com.intellij.testFramework.fixtures;
import com.intellij.lang.Language;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -102,6 +103,10 @@ public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase {
myFixture.setTestDataPath(getTestDataPath());
myModule = myFixture.getModule();
+
+ // various tests can use different mocking techniques for font-related code
+ // so we must reset our font cache, to avoid potential impact of tests on other tests
+ ComplementaryFontsRegistry.resetCaches();
}
/**
diff --git a/java/testFramework/src/com/siyeh/ig/LightInspectionTestCase.java b/java/testFramework/src/com/siyeh/ig/LightInspectionTestCase.java
index fa85710f0c14..3a1d6f8cddc8 100644
--- a/java/testFramework/src/com/siyeh/ig/LightInspectionTestCase.java
+++ b/java/testFramework/src/com/siyeh/ig/LightInspectionTestCase.java
@@ -16,6 +16,7 @@
package com.siyeh.ig;
import com.intellij.codeInspection.InspectionProfileEntry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.util.ArrayUtil;
import org.intellij.lang.annotations.Language;
@@ -107,9 +108,7 @@ public abstract class LightInspectionTestCase extends LightCodeInsightFixtureTes
basePath.append(word).append('/');
}
String lastWord = words[lastWordIndex];
- if (lastWord.endsWith("Inspection")) {
- lastWord = lastWord.substring(0, lastWord.length() - 10);
- }
+ lastWord = StringUtil.trimEnd(lastWord, "Inspection");
final int length = lastWord.length();
boolean upperCase = false;
for (int i = 0; i < length; i++) {
diff --git a/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java b/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java
index d851e2da635d..fb42e0f95e80 100644
--- a/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java
+++ b/platform/analysis-api/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.search.scope.packageSet;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -22,7 +23,7 @@ public class NamedPackageSetReference extends PackageSetBase {
private final String myName;
public NamedPackageSetReference(String name) {
- myName = name.startsWith("$") ? name.substring(1) : name;
+ myName = StringUtil.trimStart(name, "$");
}
@Override
diff --git a/platform/built-in-server/src/org/jetbrains/ide/AboutHttpService.java b/platform/built-in-server/src/org/jetbrains/ide/AboutHttpService.java
index 11c05002b9fd..f45c6f309ede 100644
--- a/platform/built-in-server/src/org/jetbrains/ide/AboutHttpService.java
+++ b/platform/built-in-server/src/org/jetbrains/ide/AboutHttpService.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeRegistry;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PlatformUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
@@ -83,9 +84,7 @@ class AboutHttpService extends RestService {
if (!PlatformUtils.isIdeaUltimate()) {
String productName = ApplicationNamesInfo.getInstance().getProductName();
appName = appName.replace(productName + " (" + productName + ")", productName);
- if (appName.startsWith("JetBrains ")) {
- appName = appName.substring("JetBrains ".length());
- }
+ appName = StringUtil.trimStart(appName, "JetBrains ");
}
writer.name("name").value(appName);
diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
index 25895bce1077..ef6a0c962725 100644
--- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
+++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java
@@ -550,9 +550,7 @@ public class VfsUtilCore {
uri = uri.substring("file:/".length());
if (!SystemInfo.isWindows) uri = "/" + uri;
}
- else if (uri.startsWith("file:")) {
- uri = uri.substring("file:".length());
- }
+ else uri = StringUtil.trimStart(uri, "file:");
VirtualFile file = null;
diff --git a/platform/platform-impl/src/com/intellij/concurrency/JobSchedulerImpl.java b/platform/core-impl/src/com/intellij/concurrency/JobSchedulerImpl.java
similarity index 88%
rename from platform/platform-impl/src/com/intellij/concurrency/JobSchedulerImpl.java
rename to platform/core-impl/src/com/intellij/concurrency/JobSchedulerImpl.java
index 7b252e9c16d0..4620657262bd 100644
--- a/platform/platform-impl/src/com/intellij/concurrency/JobSchedulerImpl.java
+++ b/platform/core-impl/src/com/intellij/concurrency/JobSchedulerImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -19,6 +19,6 @@
*/
package com.intellij.concurrency;
-public abstract class JobSchedulerImpl {
+public class JobSchedulerImpl extends JobScheduler {
public static final int CORES_COUNT = Runtime.getRuntime().availableProcessors();
}
diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
index 7ad7f86f4d48..a20e1d29b889 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl;
+import com.intellij.concurrency.JobSchedulerImpl;
import com.intellij.diagnostic.ThreadDumper;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationAdapter;
@@ -35,28 +36,33 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
+import com.intellij.util.concurrency.BoundedTaskExecutorService;
import com.intellij.util.containers.Queue;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
+import org.jetbrains.ide.PooledThreadExecutor;
import javax.swing.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
public class DocumentCommitThread extends DocumentCommitProcessor implements Runnable, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.DocumentCommitThread");
private static final String NAME = "Document commit thread";
+ private final ExecutorService executor = new BoundedTaskExecutorService(PooledThreadExecutor.INSTANCE, JobSchedulerImpl.CORES_COUNT, this);
+
private final Queue documentsToCommit = new Queue(10);
private final List documentsToApplyInEDT = new ArrayList(10); // guarded by documentsToCommit
private final ApplicationEx myApplication;
private volatile boolean isDisposed;
private CommitTask currentTask; // guarded by documentsToCommit
- private volatile boolean threadFinished;
private volatile boolean myEnabled; // true if we can do commits. set to false temporarily during the write action.
private int runningWriteActions; // accessed in EDT only
@@ -108,9 +114,6 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
}
});
log("Starting thread", null, false);
- Thread thread = new Thread(this, NAME);
- thread.setDaemon(true);
- thread.start();
}
@Override
@@ -120,17 +123,6 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
documentsToCommit.clear();
}
cancel("Stop thread");
- wakeUpQueue();
- while (!threadFinished) {
- wakeUpQueue();
- synchronized (documentsToCommit) {
- try {
- documentsToCommit.wait(10);
- }
- catch (InterruptedException ignored) {
- }
- }
- }
}
private void disable(@NonNls Object reason) {
@@ -146,10 +138,8 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
log("Enabled", null, false, reason);
}
- private void wakeUpQueue() {
- synchronized (documentsToCommit) {
- documentsToCommit.notifyAll();
- }
+ private Future> wakeUpQueue() {
+ return executor.submit(this);
}
private void cancel(@NonNls @NotNull Object reason) {
@@ -220,8 +210,14 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
s += "; Uncommitted: " + task.document;
}
}
+ synchronized (documentsToCommit) {
+ int size = documentsToCommit.size();
+ if (size != 0) {
+ s += " (" + size + " documents are still in queue)";
+ }
+ }
-// System.err.println(s);
+ //System.out.println(s);
synchronized (log) {
log.append(s).append("\n");
@@ -291,26 +287,19 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
@Override
public void run() {
- threadFinished = false;
- try {
- while (!isDisposed) {
- try {
- pollQueue();
- }
- catch(Throwable e) {
- LOG.error(e);
- }
+ while (!isDisposed) {
+ try {
+ boolean polled = pollQueue();
+ if (!polled) break;
+ }
+ catch(Throwable e) {
+ LOG.error(e);
}
}
- finally {
- threadFinished = true;
- }
- // ping the thread waiting for close
- wakeUpQueue();
- log("Good bye", null, false);
}
- private void pollQueue() {
+ // returns true if queue changed
+ private boolean pollQueue() {
boolean success = false;
Document document = null;
Project project = null;
@@ -319,8 +308,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
ProgressIndicator indicator;
synchronized (documentsToCommit) {
if (!myEnabled || documentsToCommit.isEmpty()) {
- documentsToCommit.wait(1000);
- return;
+ return false;
}
task = documentsToCommit.pullFirst();
document = task.document;
@@ -331,11 +319,11 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
if (project.isDisposed() || !((PsiDocumentManagerBase)PsiDocumentManager.getInstance(project)).isInUncommittedSet(document)) {
log("Abandon and proceed to next",task, false);
- return;
+ return true;
}
if (task.removed) {
- return; // document has been marked as removed, e.g. by synchronous commit
+ return true; // document has been marked as removed, e.g. by synchronous commit
}
startNewTask(task, "Pulled new task");
@@ -373,11 +361,6 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
log("PCE", task, false, e);
success = false;
}
- catch (InterruptedException e) {
- // app must be closing
- log("IE", task, false, e);
- cancel(e);
- }
catch (Throwable e) {
LOG.error(e);
cancel(e);
@@ -389,6 +372,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
}
currentTask = null; // do not cancel, it's being invokeLatered
}
+ return true;
}
@Override
@@ -491,7 +475,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
return null;
}
- Runnable finishRunnable = new Runnable() {
+ return new Runnable() {
@Override
public void run() {
myApplication.assertIsDispatchThread();
@@ -539,7 +523,6 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
}
}
};
- return finishRunnable;
}
@NotNull
@@ -584,6 +567,6 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
@Override
public String toString() {
- return "Document commit thread; application: "+myApplication+"; isDisposed: "+isDisposed+"; threadFinished: "+threadFinished+"; myEnabled: "+myEnabled+"; runningWriteActions: "+runningWriteActions;
+ return "Document commit thread; application: "+myApplication+"; isDisposed: "+isDisposed+"; myEnabled: "+myEnabled+"; runningWriteActions: "+runningWriteActions;
}
}
diff --git a/platform/external-system-api/external-system-api.iml b/platform/external-system-api/external-system-api.iml
index 560cd417f4ad..e04ae61c2ae1 100644
--- a/platform/external-system-api/external-system-api.iml
+++ b/platform/external-system-api/external-system-api.iml
@@ -1,6 +1,6 @@
-
+
@@ -14,5 +14,6 @@
+
\ No newline at end of file
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ModuleData.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ModuleData.java
index 8bb80bdb3037..0dd514a23718 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ModuleData.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ModuleData.java
@@ -88,6 +88,11 @@ public class ModuleData extends AbstractNamedData implements Named, ExternalConf
.toCanonicalPath(myModuleFileDirectoryPath + "/" + getInternalName() + ModuleFileType.DOT_DEFAULT_EXTENSION);
}
+ @NotNull
+ public String getModuleFileDirectoryPath() {
+ return myModuleFileDirectoryPath;
+ }
+
public void setModuleFileDirectoryPath(@NotNull String path) {
myModuleFileDirectoryPath = path;
}
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/AbstractModuleDataService.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/AbstractModuleDataService.java
index c63b86c46f4f..21e6325651a6 100644
--- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/AbstractModuleDataService.java
+++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/AbstractModuleDataService.java
@@ -95,11 +95,14 @@ public abstract class AbstractModuleDataService extends Ab
final ModifiableModuleModel modifiableModel = modelsProvider.getModifiableModuleModel();
final String[] groupPath;
- if (isOneToOneMapping || node.getData().getIdeModuleGroup() == null || projectData == null) {
+ if (isOneToOneMapping || projectData == null) {
groupPath = node.getData().getIdeModuleGroup();
}
else {
- groupPath = ArrayUtil.prepend(projectData.getInternalName() + " modules", node.getData().getIdeModuleGroup());
+ final String externalProjectGroup = projectData.getInternalName() + " modules";
+ groupPath = node.getData().getIdeModuleGroup() == null
+ ? new String[]{externalProjectGroup}
+ : ArrayUtil.prepend(externalProjectGroup, node.getData().getIdeModuleGroup());
}
modifiableModel.setModuleGroupPath(module, groupPath);
ModifiableRootModel modifiableRootModel = modelsProvider.getModifiableRootModel(module);
diff --git a/platform/external-system-rt/external-system-rt.iml b/platform/external-system-rt/external-system-rt.iml
new file mode 100644
index 000000000000..a58c68919b9f
--- /dev/null
+++ b/platform/external-system-rt/external-system-rt.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSystemException.java b/platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/ExternalSystemException.java
similarity index 100%
rename from platform/external-system-api/src/com/intellij/openapi/externalSystem/model/ExternalSystemException.java
rename to platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/ExternalSystemException.java
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java b/platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java
similarity index 100%
rename from platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java
rename to platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/ExternalSystemSourceType.java
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/IExternalSystemSourceType.java b/platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/IExternalSystemSourceType.java
similarity index 100%
rename from platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/IExternalSystemSourceType.java
rename to platform/external-system-rt/src/com/intellij/openapi/externalSystem/model/project/IExternalSystemSourceType.java
diff --git a/platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java b/platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java
index 0066c260f1b3..c88d45c1160b 100644
--- a/platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java
+++ b/platform/indexing-api/src/com/intellij/psi/search/IndexPattern.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.search;
+import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -81,9 +82,7 @@ public class IndexPattern {
}
myPattern = Pattern.compile(myPatternString, flags);
String optimizedPattern = myPatternString;
- if (optimizedPattern.startsWith(".*")) {
- optimizedPattern = optimizedPattern.substring(".*".length());
- }
+ optimizedPattern = StringUtil.trimStart(optimizedPattern, ".*");
myOptimizedIndexingPattern = Pattern.compile(optimizedPattern, flags);
}
catch(PatternSyntaxException e){
diff --git a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
index e7fb55c2ff52..a2417f671801 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
+++ b/platform/lang-api/src/com/intellij/codeInsight/lookup/LookupElementBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -66,6 +66,7 @@ public final class LookupElementBuilder extends LookupElement {
this(lookupString, object, null, null, null, Collections.singleton(lookupString), true);
}
+ @NotNull
public static LookupElementBuilder create(@NotNull String lookupString) {
return new LookupElementBuilder(lookupString, lookupString);
}
diff --git a/platform/lang-api/src/com/intellij/ide/actions/CreateElementActionBase.java b/platform/lang-api/src/com/intellij/ide/actions/CreateElementActionBase.java
index cfee9818c139..b2a54ff7ff63 100644
--- a/platform/lang-api/src/com/intellij/ide/actions/CreateElementActionBase.java
+++ b/platform/lang-api/src/com/intellij/ide/actions/CreateElementActionBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.InputValidator;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NonNls;
@@ -115,9 +116,7 @@ public abstract class CreateElementActionBase extends AnAction {
public static String filterMessage(String message) {
if (message == null) return null;
@NonNls final String ioExceptionPrefix = "java.io.IOException:";
- if (message.startsWith(ioExceptionPrefix)) {
- message = message.substring(ioExceptionPrefix.length());
- }
+ message = StringUtil.trimStart(message, ioExceptionPrefix);
return message;
}
diff --git a/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java b/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java
index 60d3819df9e2..8e1ebeb998ee 100644
--- a/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java
+++ b/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -32,6 +32,7 @@ import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.*;
import com.intellij.ui.components.JBList;
import com.intellij.util.containers.hash.HashSet;
@@ -211,9 +212,7 @@ class BeforeRunStepsPanel extends JPanel {
Map.Entry entry = iterator.next();
BeforeRunTaskProvider provider = entry.getKey();
String name = provider.getName();
- if (name.startsWith("Run ")) {
- name = name.substring(4);
- }
+ name = StringUtil.trimStart(name, "Run ");
if (sb.length() > 0) {
sb.append(", ");
}
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index 141db44b637d..9f7e41f69394 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -1330,9 +1330,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
hit = hit.replace(" ", " "); //avoid extra spaces from mnemonics and xml conversion
String text = hit.trim();
- if (text.endsWith(":")) {
- text = text.substring(0, text.length() - 1);
- }
+ text = StringUtil.trimEnd(text, ":");
return text;
}
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/UrlUtil.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/UrlUtil.java
index 7eb88034c6e3..db26d1a35bcd 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/UrlUtil.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/UrlUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -17,6 +17,7 @@ package com.intellij.ide.fileTemplates.impl;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.io.URLUtil;
import java.io.BufferedInputStream;
@@ -87,9 +88,7 @@ public class UrlUtil {
private static List getChildPathsFromJar(URL root) throws IOException {
final List paths = new ArrayList();
String file = root.getFile();
- if (file.startsWith(FILE_PROTOCOL_PREFIX)) {
- file = file.substring(FILE_PROTOCOL_PREFIX.length());
- }
+ file = StringUtil.trimStart(file, FILE_PROTOCOL_PREFIX);
final int jarSeparatorIndex = file.indexOf(JAR_SEPARATOR);
assert jarSeparatorIndex > 0;
diff --git a/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java b/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
index 896068aac412..6e84402ae9e2 100644
--- a/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
+++ b/platform/platform-api/src/com/intellij/execution/process/ColoredOutputTypeRegistry.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.execution.process;
import com.intellij.execution.ui.ConsoleViewContentType;
@@ -7,6 +22,7 @@ import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -76,12 +92,8 @@ public class ColoredOutputTypeRegistry {
if (attribute.startsWith("\u001B[")) {
attribute = attribute.substring(2);
}
- else if (attribute.startsWith("[")) {
- attribute = attribute.substring(1);
- }
- if (attribute.endsWith("m")) {
- attribute = attribute.substring(0, attribute.length() - 1);
- }
+ else attribute = StringUtil.trimStart(attribute, "[");
+ attribute = StringUtil.trimEnd(attribute, "m");
if (attribute.equals("0")) {
return ProcessOutputTypes.STDOUT;
}
diff --git a/platform/platform-api/src/com/intellij/openapi/roots/ui/LightFilePointer.java b/platform/platform-api/src/com/intellij/openapi/roots/ui/LightFilePointer.java
index c124ad10856c..ab1b543a829b 100644
--- a/platform/platform-api/src/com/intellij/openapi/roots/ui/LightFilePointer.java
+++ b/platform/platform-api/src/com/intellij/openapi/roots/ui/LightFilePointer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.roots.ui;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -70,9 +71,7 @@ public class LightFilePointer implements VirtualFilePointer {
public static String toPresentableUrl(String url) {
String path = VirtualFileManager.extractPath(url);
- if (path.endsWith(JarFileSystem.JAR_SEPARATOR)) {
- path = path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length());
- }
+ path = StringUtil.trimEnd(path, JarFileSystem.JAR_SEPARATOR);
return path.replace('/', File.separatorChar);
}
diff --git a/platform/platform-impl/src/com/intellij/application/options/pathMacros/PathMacroTable.java b/platform/platform-impl/src/com/intellij/application/options/pathMacros/PathMacroTable.java
index 9950186c194a..0669e0b717cf 100644
--- a/platform/platform-impl/src/com/intellij/application/options/pathMacros/PathMacroTable.java
+++ b/platform/platform-impl/src/com/intellij/application/options/pathMacros/PathMacroTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.PathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.JBColor;
import com.intellij.util.ui.Table;
@@ -128,7 +129,7 @@ public class PathMacroTable extends Table {
final String value = pair.getSecond();
if (value != null && value.trim().length() > 0) {
String path = value.replace(File.separatorChar, '/');
- if (path.endsWith("/")) path = path.substring(0, path.length() - 1);
+ path = StringUtil.trimEnd(path, "/");
myPathMacros.setMacro(pair.getFirst(), path);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
index 38daf69a2601..b624510b6cb2 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/CreateLauncherScriptAction.java
@@ -149,7 +149,7 @@ public class CreateLauncherScriptAction extends DumbAwareAction {
String runPath = PathManager.getHomePath();
String productName = ApplicationNamesInfo.getInstance().getProductName().toLowerCase(Locale.US);
if (!SystemInfo.isMac) runPath += "/bin/" + productName + ".sh";
- else if (runPath.endsWith(CONTENTS)) runPath = runPath.substring(0, runPath.length() - CONTENTS.length());
+ else runPath = StringUtil.trimEnd(runPath, CONTENTS);
ClassLoader loader = CreateLauncherScriptAction.class.getClassLoader();
assert loader != null;
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java
index 367cb823fca9..fa8359127337 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java
@@ -61,7 +61,7 @@ public abstract class EditorGutterComponentEx extends JComponent implements Edit
public abstract int getAnnotationsAreaWidth();
@Nullable
- public abstract Point getPoint(GutterIconRenderer renderer);
+ public abstract Point getCenterPoint(GutterIconRenderer renderer);
public abstract void setLineNumberConvertor(@NotNull TIntFunction lineNumberConvertor);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
index ff2b6a12f776..b22f109a841f 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretImpl.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.editor.impl;
+import com.intellij.diagnostic.Dumpable;
import com.intellij.diagnostic.LogMessageEx;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.application.ApplicationManager;
@@ -47,7 +48,7 @@ import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.List;
-public class CaretImpl extends UserDataHolderBase implements Caret {
+public class CaretImpl extends UserDataHolderBase implements Caret, Dumpable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.CaretImpl");
private final EditorImpl myEditor;
@@ -1484,6 +1485,33 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
return myEditor.myUseNewRendering && myEditor.myView.isAtBidiRunBoundary(myVisibleCaret);
}
+ @NotNull
+ @Override
+ public String dumpState() {
+ return "{valid: " + isValid +
+ ", offset: " + myOffset +
+ ", logical pos: " + myLogicalCaret +
+ ", visual pos: " + myVisibleCaret +
+ ", visual line start: " + myVisualLineStart +
+ ", visual line end: " + myVisualLineEnd +
+ ", savedBeforeBulkCaretMarker: " + savedBeforeBulkCaretMarker +
+ ", skip change requests: " + mySkipChangeRequests +
+ ", desired selection start column: " + myDesiredSelectionStartColumn +
+ ", desired selection end column: " + myDesiredSelectionEndColumn +
+ ", report caret moves: " + myReportCaretMoves +
+ ", desired x: " + myDesiredX +
+ ", selection marker: " + mySelectionMarker +
+ ", rangeMarker start position: " + myRangeMarkerStartPosition +
+ ", rangeMarker end position: " + myRangeMarkerEndPosition +
+ ", rangeMarker end position is lead: " + myRangeMarkerEndPositionIsLead +
+ ", selection start before change: " + startBefore +
+ ", selection end after change: " + endBefore +
+ ", unknown direction: " + myUnknownDirection +
+ ", virtual space offset: " + myVirtualSpaceOffset +
+ ", virtual selection start offset: " + myStartVirtualOffset +
+ ", virtual selection end offset: " + myEndVirtualOffset + '}';
+ }
+
/**
* Encapsulates information about target vertical range info - its 'y' coordinate and height in pixels.
*/
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
index 81f1d2ec873a..dde8d538cfcc 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/CaretModelImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@
*/
package com.intellij.openapi.editor.impl;
+import com.intellij.diagnostic.Dumpable;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.*;
@@ -36,12 +37,14 @@ import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.EventDispatcher;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
-public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, Disposable {
+public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener, Disposable, Dumpable {
private final EditorImpl myEditor;
private final EventDispatcher myCaretListeners = EventDispatcher.create(CaretListener.class);
@@ -512,6 +515,21 @@ public class CaretModelImpl implements CaretModel, PrioritizedDocumentListener,
myCaretListeners.getMulticaster().caretRemoved(new CaretEvent(myEditor, caret, caret.getLogicalPosition(), caret.getLogicalPosition()));
}
+ @NotNull
+ @Override
+ public String dumpState() {
+ return "[in update: " + myIsInUpdate +
+ ", document changed: " + isDocumentChanged +
+ ", perform caret merging: " + myPerformCaretMergingAfterCurrentOperation +
+ ", current caret: " + myCurrentCaret +
+ ", all carets: " + ContainerUtil.map(myCarets, new Function() {
+ @Override
+ public String fun(CaretImpl caret) {
+ return caret.dumpState();
+ }
+ }) + "]";
+ }
+
private static class VisualPositionComparator implements Comparator {
private static final VisualPositionComparator INSTANCE = new VisualPositionComparator();
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
index 90bd1862449b..184e52b4d3a3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
@@ -57,10 +57,7 @@ import com.intellij.openapi.wm.impl.IdeGlassPaneImpl;
import com.intellij.ui.HintHint;
import com.intellij.ui.JBColor;
import com.intellij.ui.awt.RelativePoint;
-import com.intellij.util.Function;
-import com.intellij.util.IconUtil;
-import com.intellij.util.NullableFunction;
-import com.intellij.util.SmartList;
+import com.intellij.util.*;
import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
@@ -242,14 +239,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
if (clip.height < 0) return;
Graphics2D g = IdeBackgroundUtil.withEditorBackground(g_, this);
- AffineTransform old = g.getTransform();
-
- if (isMirrored()) {
- final AffineTransform transform = new AffineTransform(old);
- transform.scale(-1, 1);
- transform.translate(-getWidth(), 0);
- g.setTransform(transform);
- }
+ AffineTransform old = setMirrorTransformIfNeeded(g, 0, getWidth());
EditorUIUtil.setupAntialiasing(g);
Color backgroundColor = getBackground();
@@ -277,7 +267,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hint);
}
- g.setTransform(old);
+ if (old != null) g.setTransform(old);
}
finally {
((ApplicationImpl)ApplicationManager.getApplication()).editorPaintFinish();
@@ -379,8 +369,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
if (w == 0) return;
- AffineTransform old = g.getTransform();
- g.setTransform(getMirrorTransform(old, x, w));
+ AffineTransform old = setMirrorTransformIfNeeded(g, x, w);
try {
Color color = myEditor.getColorsScheme().getColor(EditorColors.ANNOTATIONS_COLOR);
g.setColor(color != null ? color : JBColor.blue);
@@ -422,7 +411,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
}
finally {
- g.setTransform(old);
+ if (old != null) g.setTransform(old);
}
}
@@ -498,8 +487,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
g.setColor(color != null ? color : JBColor.blue);
g.setFont(myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
- AffineTransform old = g.getTransform();
- g.setTransform(getMirrorTransform(old, getLineNumberAreaOffset(), getLineNumberAreaWidth()));
+ AffineTransform old = setMirrorTransformIfNeeded(g, getLineNumberAreaOffset(), getLineNumberAreaWidth());
try {
for (int i = startLineNumber; i < endLineNumber; i++) {
LogicalPosition logicalPosition = myEditor.visualToLogicalPosition(new VisualPosition(i, 0));
@@ -526,7 +514,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
}
}
finally {
- g.setTransform(old);
+ if (old != null) g.setTransform(old);
}
}
@@ -810,13 +798,12 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
public void process(int x, int y, GutterMark renderer) {
Icon icon = scaleIcon(renderer.getIcon());
- AffineTransform old = g.getTransform();
- g.setTransform(getMirrorTransform(old, x, icon.getIconWidth()));
+ AffineTransform old = setMirrorTransformIfNeeded(g, x, icon.getIconWidth());
try {
icon.paintIcon(EditorGutterComponentImpl.this, g, x, y);
}
finally {
- g.setTransform(old);
+ if (old != null) g.setTransform(old);
}
}
});
@@ -875,7 +862,10 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
private Icon scaleIcon(Icon icon) {
if (Registry.is("editor.scale.gutter.icons") && icon instanceof ScalableIcon) {
- return ((ScalableIcon)icon).scale((float)myEditor.getLineHeight() / JBUI.scale(17f));
+ float scale = myEditor.getLineHeight() / JBUI.scale(16f);
+ if (Math.abs(1f - scale) > 0.10f) {
+ return ((ScalableIcon)icon).scale(scale);
+ }
}
return icon;
}
@@ -1261,10 +1251,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
return myEditor.getVerticalScrollbarOrientation() != EditorEx.VERTICAL_SCROLLBAR_RIGHT;
}
- @NotNull
- private AffineTransform getMirrorTransform(@NotNull AffineTransform old, int offset, int width) {
- final AffineTransform transform = new AffineTransform(old);
+ @Nullable
+ private AffineTransform setMirrorTransformIfNeeded(Graphics2D g, int offset, int width) {
if (isMirrored()) {
+ AffineTransform old = g.getTransform();
+ AffineTransform transform = new AffineTransform(old);
//transform.translate(getWidth(), 0); // revert mirroring transform
//transform.scale(-1, 1); // revert mirroring transform
//transform.translate(getWidth() - offset - width, 0); // move range start to the X==0
@@ -1272,8 +1263,12 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
transform.scale(-1, 1);
transform.translate(-offset * 2 - width, 0);
+ g.setTransform(transform);
+ return old;
+ }
+ else {
+ return null;
}
- return transform;
}
@Nullable
@@ -1579,14 +1574,15 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
@Override
@Nullable
- public Point getPoint(final GutterIconRenderer renderer) {
+ public Point getCenterPoint(final GutterIconRenderer renderer) {
final Ref result = Ref.create();
for (int line : myLineToGutterRenderers.keys()) {
processIconsRow(line, myLineToGutterRenderers.get(line), new LineGutterIconRendererProcessor() {
@Override
public void process(int x, int y, GutterMark r) {
if (result.isNull() && r.equals(renderer)) {
- result.set(new Point(x, y));
+ Icon icon = scaleIcon(r.getIcon());
+ result.set(new Point(x + icon.getIconWidth() / 2, y + icon.getIconHeight() / 2));
}
}
}, true);
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
index e1eceabefaf2..49353230a96c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
@@ -3149,6 +3149,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
+ "', allow caret inside tab: " + mySettings.isCaretInsideTabs()
+ ", allow caret after line end: " + mySettings.isVirtualSpace()
+ ", soft wraps: " + (mySoftWrapModel.isSoftWrappingEnabled() ? "on" : "off")
+ + ", caret model: " + getCaretModel().dumpState()
+ ", soft wraps data: " + getSoftWrapModel().dumpState()
+ "\n\nfolding data: " + getFoldingModel().dumpState()
+ (myDocument instanceof DocumentImpl ? "\n\ndocument info: " + ((DocumentImpl)myDocument).dumpState() : "")
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorSizeManager.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorSizeManager.java
index 44d5cefa4ee8..fa1414aa0f75 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorSizeManager.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorSizeManager.java
@@ -362,6 +362,8 @@ class EditorSizeManager implements PrioritizedDocumentListener, Disposable, Fold
@NotNull
@Override
public String dumpState() {
- return "[line widths: " + myLineWidths + "]";
+ return "[cached width: " + myWidthInPixels +
+ ", max line with extension width: " + myMaxLineWithExtensionWidth +
+ ", line widths: " + myLineWidths + "]";
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorView.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorView.java
index fdcefe798d64..c54f04754089 100644
--- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorView.java
+++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorView.java
@@ -469,6 +469,14 @@ public class EditorView implements TextDrawingCallback, Disposable, Dumpable {
@NotNull
@Override
public String dumpState() {
- return "[Size manager: " + mySizeManager.dumpState() + "]";
+ return "[prefix text: " + myPrefixText +
+ ", prefix attributes: " + myPrefixAttributes +
+ ", space width: " + myPlainSpaceWidth +
+ ", line height: " + myLineHeight +
+ ", descent: " + myDescent +
+ ", char height: " + myCharHeight +
+ ", max char width: " + myMaxCharWidth +
+ ", tab size: " + myTabSize +
+ " ,size manager: " + mySizeManager.dumpState() + "]";
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
index 612cb57f74fc..b0d975512276 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java
@@ -21,7 +21,6 @@ import com.intellij.ide.plugins.PluginManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.impl.TransferToPooledThreadQueue;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
@@ -51,6 +50,7 @@ import com.intellij.openapi.vfs.newvfs.impl.StubVirtualFile;
import com.intellij.psi.SingleRootFileViewProvider;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.*;
+import com.intellij.util.concurrency.BoundedTaskExecutorService;
import com.intellij.util.containers.ConcurrentPackedBitsArray;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.URLUtil;
@@ -63,12 +63,15 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
+import org.jetbrains.ide.PooledThreadExecutor;
import java.io.*;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.*;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -245,7 +248,10 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
if (toLog()) {
log("F: after() queued to redetect: " + files);
}
- reDetectQueue.offerIfAbsent(files);
+
+ if (filesToRedetect.addAll(files)) {
+ awakeReDetectExecutor();
+ }
}
}
});
@@ -340,23 +346,38 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
System.out.println(message + " - "+Thread.currentThread());
}
- private final TransferToPooledThreadQueue> reDetectQueue = new TransferToPooledThreadQueue>("File type re-detect", Conditions.alwaysFalse(), -1, new Processor>() {
- @Override
- public boolean process(Collection files) {
- reDetect(files);
- return true;
- }
- });
+ private final BoundedTaskExecutorService reDetectExecutor = new BoundedTaskExecutorService(PooledThreadExecutor.INSTANCE, 1, this);
+ private final BlockingQueue filesToRedetect = new LinkedBlockingDeque();
+
+ private void awakeReDetectExecutor() {
+ reDetectExecutor.submit(new Runnable() {
+ private static final int CHUNK = 10;
+ @Override
+ public void run() {
+ List files = new ArrayList();
+ int drained = filesToRedetect.drainTo(files, CHUNK);
+ reDetect(files);
+ if (drained == CHUNK) {
+ awakeReDetectExecutor();
+ }
+ }
+ });
+ }
@TestOnly
public void drainReDetectQueue() {
- reDetectQueue.waitFor();
+ try {
+ reDetectExecutor.waitAllTasksExecuted();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
@TestOnly
@NotNull
Collection dumpReDetectQueue() {
- return ContainerUtil.flatten(reDetectQueue.dump());
+ return new ArrayList(filesToRedetect);
}
@TestOnly
@@ -603,6 +624,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
private volatile FileAttribute autoDetectedAttribute;
// read auto-detection flags from the persistent FS file attributes. If file attributes are absent, return 0 for flags
// returns three bits value for AUTO_DETECTED_AS_TEXT_MASK, AUTO_DETECTED_AS_BINARY_MASK and AUTO_DETECT_WAS_RUN_MASK bits
+ // protected for Upsource
protected byte readFlagsFromCache(@NotNull VirtualFile file) {
DataInputStream stream = autoDetectedAttribute.readAttribute(file);
boolean wasAutoDetectRun = false;
@@ -627,6 +649,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
// store auto-detection flags to the persistent FS file attributes
// writes AUTO_DETECTED_AS_TEXT_MASK, AUTO_DETECTED_AS_BINARY_MASK bits only
+ // protected for Upsource
protected void writeFlagsToCache(@NotNull VirtualFile file, int flags) {
DataOutputStream stream = autoDetectedAttribute.writeAttribute(file);
try {
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/JBProtocolOpenProjectCommand.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/JBProtocolOpenProjectCommand.java
index 0c846dd9963b..b41460cb2144 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/impl/JBProtocolOpenProjectCommand.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/JBProtocolOpenProjectCommand.java
@@ -17,6 +17,7 @@ package com.intellij.openapi.project.impl;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.application.JBProtocolCommand;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import org.jetbrains.annotations.NotNull;
@@ -36,9 +37,7 @@ public class JBProtocolOpenProjectCommand extends JBProtocolCommand {
@Override
public void perform(String target, Map parameters) {
String path = URLDecoder.decode(target);
- if (path.startsWith(LocalFileSystem.PROTOCOL_PREFIX)) {
- path = path.substring(LocalFileSystem.PROTOCOL_PREFIX.length());
- }
+ path = StringUtil.trimStart(path, LocalFileSystem.PROTOCOL_PREFIX);
ProjectUtil.openProject(path, null, true);
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java
index 78b297d68e57..f3b3af9d2fa4 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/EncodingManagerImpl.java
@@ -22,9 +22,9 @@
*/
package com.intellij.openapi.vfs.encoding;
+import com.intellij.concurrency.JobSchedulerImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.impl.TransferToPooledThreadQueue;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
@@ -48,13 +48,14 @@ import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Alarm;
import com.intellij.util.ObjectUtils;
-import com.intellij.util.Processor;
+import com.intellij.util.concurrency.BoundedTaskExecutorService;
import com.intellij.util.xmlb.annotations.Attribute;
import gnu.trove.Equality;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.ide.PooledThreadExecutor;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -99,19 +100,7 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
private final Alarm updateEncodingFromContent = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, this);
private static final Key CACHED_CHARSET_FROM_CONTENT = Key.create("CACHED_CHARSET_FROM_CONTENT");
- private final TransferToPooledThreadQueue> myChangedDocuments = new TransferToPooledThreadQueue>(
- "Encoding detection thread",
- ApplicationManager.getApplication().getDisposed(),
- -1, // drain the whole queue, do not reschedule
- new Processor>() {
- @Override
- public boolean process(Reference ref) {
- Document document = ref.get();
- if (document == null) return true; // document gced, don't bother
- handleDocument(document);
- return true;
- }
- });
+ private final BoundedTaskExecutorService changedDocumentExecutor = new BoundedTaskExecutorService(PooledThreadExecutor.INSTANCE, JobSchedulerImpl.CORES_COUNT, this);
public EncodingManagerImpl(@NotNull EditorFactory editorFactory) {
editorFactory.getEventMulticaster().addDocumentListener(new DocumentAdapter() {
@@ -130,15 +119,22 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
@NonNls public static final String PROP_CACHED_ENCODING_CHANGED = "cachedEncoding";
+ private static final Key DETECTING_ENCODING_KEY = Key.create("DETECTING_ENCODING_KEY");
private void handleDocument(@NotNull final Document document) {
- VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
- if (virtualFile == null) return;
- Project project = guessProject(virtualFile);
- if (project != null && project.isDisposed()) return;
- Charset charset = LoadTextUtil.charsetFromContentOrNull(project, virtualFile, document.getImmutableCharSequence());
- Charset oldCached = getCachedCharsetFromContent(document);
- if (!Comparing.equal(charset, oldCached)) {
- setCachedCharsetFromContent(charset, oldCached, document);
+ if (document.getUserData(DETECTING_ENCODING_KEY) == null) return;
+ try {
+ VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
+ if (virtualFile == null) return;
+ Project project = guessProject(virtualFile);
+ if (project != null && project.isDisposed()) return;
+ Charset charset = LoadTextUtil.charsetFromContentOrNull(project, virtualFile, document.getImmutableCharSequence());
+ Charset oldCached = getCachedCharsetFromContent(document);
+ if (!Comparing.equal(charset, oldCached)) {
+ setCachedCharsetFromContent(charset, oldCached, document);
+ }
+ }
+ finally {
+ document.putUserData(DETECTING_ENCODING_KEY, null);
}
}
@@ -178,7 +174,23 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
}
void queueUpdateEncodingFromContent(@NotNull Document document) {
- myChangedDocuments.offerIfAbsent(new WeakReference(document), REFERENCE_EQUALITY);
+ document.putUserData(DETECTING_ENCODING_KEY, "");
+ changedDocumentExecutor.execute(new DocumentEncodingDetectRequest(document));
+ }
+
+ private static class DocumentEncodingDetectRequest implements Runnable {
+ private final Reference ref;
+
+ private DocumentEncodingDetectRequest(@NotNull Document document) {
+ ref = new WeakReference(document);
+ }
+
+ @Override
+ public void run() {
+ Document document = ref.get();
+ if (document == null) return; // document gced, don't bother
+ ((EncodingManagerImpl)getInstance()).handleDocument(document);
+ }
}
@Override
@@ -220,7 +232,7 @@ public class EncodingManagerImpl extends EncodingManager implements PersistentSt
}
public void clearDocumentQueue() {
- myChangedDocuments.stop();
+ changedDocumentExecutor.clearAndCancelAll();
}
@Nullable
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java
index 962c15f317eb..65a45613ec47 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java
@@ -158,9 +158,7 @@ public abstract class LocalFileSystemBase extends LocalFileSystem {
final String[] names = new String[roots.length];
for (int i = 0; i < names.length; i++) {
String name = roots[i].getPath();
- if (name.endsWith(File.separator)) {
- name = name.substring(0, name.length() - File.separator.length());
- }
+ name = StringUtil.trimEnd(name, File.separator);
names[i] = name;
}
return names;
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java
index 12765fedb7a7..bda8002b975c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/RefreshQueueImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vfs.newvfs;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
@@ -26,11 +27,12 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.vfs.VfsBundle;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
-import com.intellij.util.ConcurrencyUtil;
+import com.intellij.util.concurrency.BoundedTaskExecutorService;
import com.intellij.util.io.storage.HeavyProcessLatch;
import gnu.trove.TLongObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.ide.PooledThreadExecutor;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
@@ -38,10 +40,10 @@ import java.util.concurrent.ExecutorService;
/**
* @author max
*/
-public class RefreshQueueImpl extends RefreshQueue {
+public class RefreshQueueImpl extends RefreshQueue implements Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.newvfs.RefreshQueueImpl");
- private final ExecutorService myQueue = ConcurrencyUtil.newSingleThreadExecutor("FS Synchronizer");
+ private final ExecutorService myQueue = new BoundedTaskExecutorService(PooledThreadExecutor.INSTANCE, 1, this);
private final ProgressIndicator myRefreshIndicator = RefreshProgress.create(VfsBundle.message("file.synchronize.progress"));
private final TLongObjectHashMap mySessions = new TLongObjectHashMap();
private final FrequentEventDetector myEventCounter = new FrequentEventDetector(100, 100, FrequentEventDetector.Level.ERROR);
@@ -149,4 +151,9 @@ public class RefreshQueueImpl extends RefreshQueue {
return !refreshQueue.mySessions.isEmpty();
}
}
+
+ @Override
+ public void dispose() {
+
+ }
}
\ No newline at end of file
diff --git a/platform/platform-impl/src/com/intellij/platform/LocationNameFieldsBinding.java b/platform/platform-impl/src/com/intellij/platform/LocationNameFieldsBinding.java
index f4b719465ddc..6c0cd917cf89 100644
--- a/platform/platform-impl/src/com/intellij/platform/LocationNameFieldsBinding.java
+++ b/platform/platform-impl/src/com/intellij/platform/LocationNameFieldsBinding.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -23,6 +23,7 @@ import com.intellij.openapi.ui.TextComponentAccessor;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.DocumentAdapter;
import org.jetbrains.annotations.NotNull;
@@ -88,9 +89,7 @@ public class LocationNameFieldsBinding {
}
myModifyingLocation = true;
String path = locationField.getText().trim();
- if (path.endsWith(File.separator)) {
- path = path.substring(0, path.length() - File.separator.length());
- }
+ path = StringUtil.trimEnd(path, File.separator);
int ind = path.lastIndexOf(File.separator);
if (ind != -1) {
String projectName = path.substring(ind + 1, path.length());
diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java
index 7cb58d98b896..22460eaaeb95 100644
--- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.editor;
+import com.intellij.diagnostic.Dumpable;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.event.DocumentEvent;
@@ -52,6 +53,7 @@ public class EditorPaintingTest extends AbstractEditorTest {
public void testWholeLineHighlighterAtDocumentEnd() throws Exception {
initText("foo");
addLineHighlighter(0, 3, HighlighterLayer.WARNING, null, Color.red);
+ System.out.println(((Dumpable)myEditor).dumpState()); // temporary code to find the cause of blinking
checkResult();
}
diff --git a/platform/platform-tests/testSrc/com/intellij/util/concurrency/BoundedTaskExecutorTest.java b/platform/platform-tests/testSrc/com/intellij/util/concurrency/BoundedTaskExecutorTest.java
new file mode 100644
index 000000000000..78074775f229
--- /dev/null
+++ b/platform/platform-tests/testSrc/com/intellij/util/concurrency/BoundedTaskExecutorTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.concurrency;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.util.ConcurrencyUtil;
+import com.intellij.util.TimeoutUtil;
+import junit.framework.TestCase;
+
+import java.util.Random;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class BoundedTaskExecutorTest extends TestCase {
+ public void testReallyBound() throws InterruptedException, ExecutionException {
+ for (int maxTasks=1; maxTasks<5;maxTasks++) {
+ System.out.println("maxTasks = " + maxTasks);
+ ExecutorService backendExecutor = Executors.newCachedThreadPool(ConcurrencyUtil.newNamedThreadFactory("maxTasks = " + maxTasks));
+ BoundedTaskExecutorService executor = new BoundedTaskExecutorService(backendExecutor, maxTasks);
+ AtomicInteger running = new AtomicInteger();
+ AtomicInteger max = new AtomicInteger();
+ AtomicInteger executed = new AtomicInteger();
+ int N = 10000;
+ for (int i = 0; i < N; i++) {
+ executor.execute(() -> {
+ int r = running.incrementAndGet();
+ try {
+ TimeoutUtil.sleep(1);
+ max.accumulateAndGet(r, Math::max);
+ executed.incrementAndGet();
+ }
+ finally {
+ running.decrementAndGet();
+ }
+ });
+ }
+ executor.waitAllTasksExecuted();
+ assertEquals(0, executor.shutdownNow().size());
+ assertTrue(executor.awaitTermination(10, TimeUnit.SECONDS));
+ backendExecutor.shutdownNow();
+ assertTrue(backendExecutor.awaitTermination(100, TimeUnit.SECONDS));
+ assertEquals(maxTasks, max.get());
+ assertEquals(N, executed.get());
+ }
+ }
+
+ public void testCallableReallyReturnsValue() throws Exception{
+ ExecutorService backendExecutor = Executors.newCachedThreadPool(ConcurrencyUtil.newNamedThreadFactory(getName()));
+ BoundedTaskExecutorService executor = new BoundedTaskExecutorService(backendExecutor, 1);
+
+ Future f1 = executor.submit(() -> 42);
+ Integer result = f1.get();
+ assertEquals(42, result.intValue());
+ executor.shutdownNow();
+ assertTrue(executor.awaitTermination(1, TimeUnit.SECONDS));
+ backendExecutor.shutdownNow();
+ assertTrue(backendExecutor.awaitTermination(100, TimeUnit.SECONDS));
+ }
+
+ public void testEarlyCancelPreventsRunning() throws ExecutionException, InterruptedException {
+ AtomicBoolean run = new AtomicBoolean();
+ ExecutorService backendExecutor = Executors.newCachedThreadPool(ConcurrencyUtil.newNamedThreadFactory(getName()));
+ BoundedTaskExecutorService executor = new BoundedTaskExecutorService(backendExecutor, 1);
+
+ int delay = 500;
+ Future> s1 = executor.submit((Runnable)() -> TimeoutUtil.sleep(delay));
+ Future f1 = executor.submit(() -> {
+ run.set(true);
+ return 42;
+ });
+ f1.cancel(false);
+ TimeoutUtil.sleep(delay+200);
+ assertTrue(f1.isDone());
+ assertTrue(f1.isCancelled());
+ assertFalse(run.get());
+ assertTrue(s1.isDone());
+ executor.shutdownNow();
+ assertTrue(executor.awaitTermination(1, TimeUnit.SECONDS));
+ backendExecutor.shutdownNow();
+ assertTrue(backendExecutor.awaitTermination(100, TimeUnit.SECONDS));
+ }
+
+ public void testStressWhenSomeTasksCallOtherTasksGet() throws ExecutionException, InterruptedException {
+ ExecutorService backendExecutor = Executors.newCachedThreadPool(ConcurrencyUtil.newNamedThreadFactory(getName()));
+ for (int maxSimultaneousTasks = 1; maxSimultaneousTasks<20;maxSimultaneousTasks++) {
+ final Disposable myDisposable = Disposer.newDisposable();
+ BoundedTaskExecutorService executor = new BoundedTaskExecutorService(backendExecutor, maxSimultaneousTasks, myDisposable);
+ AtomicInteger running = new AtomicInteger();
+ AtomicInteger maxThreads = new AtomicInteger();
+
+ try {
+ int N = 5000;
+ Future[] futures = new Future[N];
+ Random random = new Random();
+ for (int i = 0; i < N; i++) {
+ final int finalI = i;
+ final int finalMaxSimultaneousTasks = maxSimultaneousTasks;
+ futures[i] = executor.submit((Runnable)() -> {
+ maxThreads.accumulateAndGet(running.incrementAndGet(), Math::max);
+
+ try {
+ int r = random.nextInt(finalMaxSimultaneousTasks);
+ int prev = finalI - r;
+ if (prev != finalI && prev >= 0) {
+ try {
+ futures[prev].get();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ TimeoutUtil.sleep(r);
+ }
+ finally {
+ running.decrementAndGet();
+ }
+ });
+ }
+ executor.waitAllTasksExecuted();
+ for (Future future : futures) {
+ assertTrue(future.isDone());
+ }
+ }
+ finally {
+ Disposer.dispose(myDisposable);
+ assertTrue(executor.isShutdown());
+ }
+
+ assertTrue("Max threads was: "+maxThreads+" but bound was: "+maxSimultaneousTasks, maxThreads.get() <= maxSimultaneousTasks);
+ }
+ backendExecutor.shutdownNow();
+ assertTrue(backendExecutor.awaitTermination(100, TimeUnit.SECONDS));
+ }
+
+ public void testSequentialSubmitsMustExecuteSequentially() throws ExecutionException, InterruptedException {
+ ExecutorService backendExecutor = Executors.newCachedThreadPool(ConcurrencyUtil.newNamedThreadFactory(getName()));
+ BoundedTaskExecutorService executor = new BoundedTaskExecutorService(backendExecutor, 1);
+ int N = 100000;
+ StringBuffer log = new StringBuffer(N*4);
+ StringBuffer expected = new StringBuffer(N*4);
+
+ Future[] futures = new Future[N];
+ for (int i = 0; i < N; i++) {
+ final int finalI = i;
+ futures[i] = executor.submit(() -> log.append(finalI).append(" "));
+ }
+ for (int i = 0; i < N; i++) {
+ expected.append(i).append(" ");
+ futures[i].get();
+ }
+
+ String logs = log.toString();
+ assertEquals(expected.toString(), logs);
+ executor.shutdownNow();
+ assertTrue(executor.awaitTermination(1, TimeUnit.SECONDS));
+ backendExecutor.shutdownNow();
+ assertTrue(backendExecutor.awaitTermination(100, TimeUnit.SECONDS));
+ }
+}
diff --git a/platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.java b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.java
index 120605d93292..b4a97c938b61 100644
--- a/platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.java
+++ b/platform/projectModel-api/src/com/intellij/openapi/project/ProjectUtilCore.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -83,9 +83,7 @@ public class ProjectUtilCore {
}
String projectName = FileUtil.toSystemIndependentName(location);
- if (projectName.endsWith("/")) {
- projectName = projectName.substring(0, projectName.length() - 1);
- }
+ projectName = StringUtil.trimEnd(projectName, "/");
final int lastSlash = projectName.lastIndexOf('/');
if (lastSlash >= 0 && lastSlash + 1 < projectName.length()) {
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java
index c2ed28929c2d..be2d7a654feb 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/SimpleProjectRoot.java
@@ -17,6 +17,7 @@
package com.intellij.openapi.projectRoots.impl;
import com.intellij.openapi.projectRoots.ex.ProjectRoot;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -58,9 +59,7 @@ public class SimpleProjectRoot implements ProjectRoot {
@NotNull
public String getPresentableString() {
String path = VirtualFileManager.extractPath(myUrl);
- if (path.endsWith(URLUtil.JAR_SEPARATOR)) {
- path = path.substring(0, path.length() - URLUtil.JAR_SEPARATOR.length());
- }
+ path = StringUtil.trimEnd(path, URLUtil.JAR_SEPARATOR);
return path.replace('/', File.separatorChar);
}
diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt
index f522e5a5b0f6..f960bfb483a4 100644
--- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt
+++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt
@@ -39,8 +39,8 @@ import java.util.concurrent.atomic.AtomicBoolean
abstract class DebugProcessImpl>(session: XDebugSession,
val connection: C,
private val editorsProvider: XDebuggerEditorsProvider,
- private val smartStepIntoHandler: XSmartStepIntoHandler<*>?,
- protected val executionResult: ExecutionResult?) : XDebugProcess(session) {
+ private val smartStepIntoHandler: XSmartStepIntoHandler<*>? = null,
+ protected val executionResult: ExecutionResult? = null) : XDebugProcess(session) {
protected val repeatStepInto: AtomicBoolean = AtomicBoolean()
@Volatile protected var lastStep: StepAction? = null
@Volatile protected var lastCallFrame: CallFrame? = null
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
index 44ff3ddc45b9..acd78a94cb74 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/TestsPresentationUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -237,11 +237,9 @@ public class TestsPresentationUtil {
}
if (parentStartsWith) {
presentationCandidate = name.substring(parentName.length());
-
+
// remove "." separator
- if (presentationCandidate.startsWith(".")) {
- presentationCandidate = presentationCandidate.substring(1);
- }
+ presentationCandidate = StringUtil.trimStart(presentationCandidate, ".");
}
}
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
index 98ff484985d5..4f3279dbe97e 100644
--- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java
@@ -45,7 +45,7 @@ import com.intellij.openapi.command.undo.UndoManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
-import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
+import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry;
import com.intellij.openapi.editor.impl.EditorFactoryImpl;
import com.intellij.openapi.editor.impl.EditorImpl;
import com.intellij.openapi.extensions.Extensions;
@@ -303,7 +303,9 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
VirtualFilePointerManagerImpl filePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance();
filePointerManager.storePointers();
- System.out.println("soft wraps enabled: " + EditorSettingsExternalizable.getInstance().isUseSoftWraps()); // temporary code to find out cause of test blinking
+ // various tests can use different mocking techniques for font-related code
+ // so we must reset our font cache, to avoid potential impact of tests on other tests
+ ComplementaryFontsRegistry.resetCaches();
}
});
}
diff --git a/platform/testFramework/src/com/intellij/testFramework/ThreadTracker.java b/platform/testFramework/src/com/intellij/testFramework/ThreadTracker.java
index f84cb57e7807..58c82ae05dad 100644
--- a/platform/testFramework/src/com/intellij/testFramework/ThreadTracker.java
+++ b/platform/testFramework/src/com/intellij/testFramework/ThreadTracker.java
@@ -79,6 +79,7 @@ public class ThreadTracker {
wellKnownOffenders.add("IDEA Test Case Thread");
wellKnownOffenders.add("Image Fetcher ");
wellKnownOffenders.add("Java2D Disposer");
+ wellKnownOffenders.add("JDI Target VM Interface");
wellKnownOffenders.add("JobScheduler FJ pool ");
wellKnownOffenders.add("JPS thread pool");
wellKnownOffenders.add("Keep-Alive-Timer");
diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
index 8c7c14871e61..6dcf1fd6c7a6 100644
--- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
+++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
@@ -149,10 +149,6 @@ public abstract class UsefulTestCase extends TestCase {
ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest);
// turn off Disposer debugging for performance tests
oldDisposerDebug = Disposer.setDebugMode(Disposer.isDebugMode() && !isPerformanceTest);
-
- // various tests can use different mocking techniques for font-related code
- // so we must reset our font cache, to avoid potential impact of tests on other tests
- ComplementaryFontsRegistry.resetCaches();
}
@Override
diff --git a/platform/testFramework/test-framework-java8/FixtureRule.kt b/platform/testFramework/test-framework-java8/FixtureRule.kt
index e4bca84c931b..0d9d5b3806f3 100644
--- a/platform/testFramework/test-framework-java8/FixtureRule.kt
+++ b/platform/testFramework/test-framework-java8/FixtureRule.kt
@@ -91,12 +91,12 @@ class ProjectRule() : ExternalResource() {
}
}
- override final fun before() {
+ override public final fun before() {
IdeaTestApplication.getInstance()
TestRunnerUtil.replaceIdeEventQueueSafely()
}
- override fun after() {
+ override public fun after() {
if (projectOpened.compareAndSet(true, false)) {
sharedProject?.let { runInEdtAndWait { (ProjectManager.getInstance() as ProjectManagerImpl).closeProject(it, false, false, false) } }
}
diff --git a/platform/util/src/com/intellij/openapi/util/IconLoader.java b/platform/util/src/com/intellij/openapi/util/IconLoader.java
index bf68ba3cc773..1bb7082fd170 100644
--- a/platform/util/src/com/intellij/openapi/util/IconLoader.java
+++ b/platform/util/src/com/intellij/openapi/util/IconLoader.java
@@ -433,18 +433,19 @@ public final class IconLoader {
scaledIcons = new HashMap(1);
}
- Icon result = scaledIcons.get(scaleFactor);
+ // TODO: consider clearing the cache on SCALE change
+ Icon result = scaledIcons.get(scaleFactor * SCALE);
if (result != null) {
return result;
}
- final Image image = ImageLoader.loadFromUrl(myUrl, UIUtil.isUnderDarcula(), scaleFactor >= 1.5f, filter);
+ final Image image = ImageLoader.loadFromUrl(myUrl, UIUtil.isUnderDarcula(), (scaleFactor * SCALE) >= 1.5f, filter);
if (image != null) {
int width = (int)(getIconWidth() * scaleFactor);
int height = (int)(getIconHeight() * scaleFactor);
final BufferedImage resizedImage = Scalr.resize(ImageUtil.toBufferedImage(image), Scalr.Method.ULTRA_QUALITY, width, height);
result = getIcon(resizedImage);
- scaledIcons.put(scaleFactor, result);
+ scaledIcons.put(scaleFactor * SCALE, result);
return result;
}
diff --git a/platform/util/src/com/intellij/openapi/util/io/UniqueNameBuilder.java b/platform/util/src/com/intellij/openapi/util/io/UniqueNameBuilder.java
index 7ebbc1b788af..c7d2237dd273 100644
--- a/platform/util/src/com/intellij/openapi/util/io/UniqueNameBuilder.java
+++ b/platform/util/src/com/intellij/openapi/util/io/UniqueNameBuilder.java
@@ -1,9 +1,25 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.intellij.openapi.util.io;
+import com.intellij.openapi.util.text.StringUtil;
import gnu.trove.THashMap;
import gnu.trove.TIntObjectHashMap;
-import java.util.*;
+import java.util.Map;
/**
* @author yole
@@ -40,12 +56,12 @@ public class UniqueNameBuilder {
private final Node myRootNode = new Node('\0', null);
public void addPath(T key, String value) {
- if (value.startsWith(myRoot)) value = value.substring(myRoot.length());
+ value = StringUtil.trimStart(value, myRoot);
myPaths.put(key, value);
Node current = myRootNode;
- for(int i = value.length() - 1; i >=0; --i) {
+ for (int i = value.length() - 1; i >= 0; --i) {
char ch = value.charAt(i);
Node node = current.myChildren.get(ch);
if (node == null) current.myChildren.put(ch, node = new Node(ch, current));
diff --git a/platform/util/src/com/intellij/ui/ColorUtil.java b/platform/util/src/com/intellij/ui/ColorUtil.java
index 965e2b22ab9b..9eb0dc278b83 100644
--- a/platform/util/src/com/intellij/ui/ColorUtil.java
+++ b/platform/util/src/com/intellij/ui/ColorUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -19,6 +19,7 @@
*/
package com.intellij.ui;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -108,9 +109,7 @@ public class ColorUtil {
* @return Color object
*/
public static Color fromHex(String str) {
- if (str.startsWith("#")) {
- str = str.substring(1);
- }
+ str = StringUtil.trimStart(str, "#");
if (str.length() == 3) {
return new Color(
17 * Integer.valueOf(String.valueOf(str.charAt(0)), 16).intValue(),
diff --git a/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java b/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
index 7e1c4372347d..167a607735f5 100644
--- a/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
+++ b/platform/util/src/com/intellij/util/concurrency/BoundedTaskExecutor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2015 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.
@@ -15,90 +15,180 @@
*/
package com.intellij.util.concurrency;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.util.Function;
+import com.intellij.util.ReflectionUtil;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
-import java.util.Queue;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
-public class BoundedTaskExecutor implements Executor {
- protected final Executor myBackendExecutor;
+/**
+ * ExecutorService which limits the number of tasks running simultaneously.
+ * The number of submitted tasks is unrestricted.
+ */
+public class BoundedTaskExecutor extends AbstractExecutorService {
+ private volatile boolean myShutdown;
+ private final Executor myBackendExecutor;
private final int myMaxTasks;
- private final AtomicInteger myInProgress = new AtomicInteger(0);
- private final Queue myTaskQueue = new LinkedBlockingQueue();
-
- private final Runnable USER_TASK_RUNNER = new Runnable() {
- @Override
- public void run() {
- final FutureTask task = myTaskQueue.poll();
- try {
- if (task != null && !task.isCancelled()) {
- task.run();
- }
- }
- finally {
- myInProgress.decrementAndGet();
- if (!myTaskQueue.isEmpty()) {
- processQueue();
- }
- }
- }
- };
+ // number of tasks running (or trying to run)
+ private final AtomicInteger myInProgress = new AtomicInteger();
+ private final BlockingQueue myTaskQueue = new LinkedBlockingQueue();
public BoundedTaskExecutor(@NotNull Executor backendExecutor, int maxSimultaneousTasks) {
myBackendExecutor = backendExecutor;
- assert maxSimultaneousTasks >= 1 : maxSimultaneousTasks;
- myMaxTasks = Math.max(maxSimultaneousTasks, 1);
+ if (maxSimultaneousTasks < 1) {
+ throw new IllegalArgumentException("maxSimultaneousTasks must be >=1 but got: "+maxSimultaneousTasks);
+ }
+ myMaxTasks = maxSimultaneousTasks;
+ }
+
+ /**
+ * Constructor which automatically shuts down this executor when {@code parent} is disposed.
+ */
+ public BoundedTaskExecutor(@NotNull Executor backendExecutor, int maxSimultaneousTasks, @NotNull Disposable parent) {
+ this(backendExecutor, maxSimultaneousTasks);
+ Disposer.register(parent, new Disposable() {
+ @Override
+ public void dispose() {
+ shutdownNow();
+ }
+ });
+ }
+
+ // for diagnostics
+ public static Object info(Object task) {
+ if (task instanceof FutureTask) {
+ task = ReflectionUtil.getField(task.getClass(), task, Callable.class, "callable");
+ }
+ if (task instanceof Callable && task.getClass().getName().equals("java.util.concurrent.Executors$RunnableAdapter")) {
+ task = ReflectionUtil.getField(task.getClass(), task, Runnable.class, "task");
+ }
+ return task;
+ }
+
+ @Override
+ public void shutdown() {
+ if (myShutdown) throw new IllegalStateException("Already shutdown");
+ myShutdown = true;
+ }
+
+ @NotNull
+ @Override
+ public List shutdownNow() {
+ shutdown();
+ return clearAndCancelAll();
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return myShutdown;
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return myShutdown;
+ }
+
+ @Override
+ public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) throws InterruptedException {
+ if (!isShutdown()) throw new IllegalStateException("you must call shutdown() first");
+ return true;
}
@Override
public void execute(@NotNull Runnable task) {
- submit(task);
+ myTaskQueue.offer(task);
+ int inProgress = myInProgress.incrementAndGet();
+
+ tryToPollAndExecuteNext(inProgress);
}
-
- public Future> submit(@NotNull Runnable task) {
- return this.submit(task, null);
- }
-
- @NotNull
- public Future submit(Runnable task, T result) {
- final RunnableFuture future = queueTask(new FutureTask(task, result));
- if (future == null) {
- throw new RuntimeException("Failed to queue task: " + task);
- }
- return future;
- }
-
- @NotNull
- public Future submit(@NotNull Callable task) {
- final RunnableFuture future = queueTask(new FutureTask(task));
- if (future == null) {
- throw new RuntimeException("Failed to queue task: " + task);
- }
- return future;
- }
-
- @Nullable
- private RunnableFuture queueTask(@NotNull FutureTask futureTask) {
- if (myTaskQueue.offer(futureTask)) {
- processQueue();
- return futureTask;
- }
- return null;
- }
-
- protected void processQueue() {
- while (true) {
- final int count = myInProgress.get();
- if (count >= myMaxTasks) {
- return;
- }
- if (myInProgress.compareAndSet(count, count + 1)) {
+ private void tryToPollAndExecuteNext(int inProgress) {
+ while (!isShutdown()) {
+ assert inProgress > 0 : inProgress;
+ Runnable next;
+ if (inProgress <= myMaxTasks && (next = myTaskQueue.poll()) != null) {
+ myBackendExecutor.execute(wrap(next));
break;
}
+ if (myInProgress.compareAndSet(inProgress, inProgress-1)) {
+ break;
+ }
+ inProgress = myInProgress.get();
}
- myBackendExecutor.execute(USER_TASK_RUNNER);
+ }
+
+ @NotNull
+ private Runnable wrap(@NotNull final Runnable task) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ try {
+ task.run();
+ }
+ finally {
+ tryToPollAndExecuteNext(myInProgress.get());
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(info(task));
+ }
+ };
+ }
+
+ @TestOnly
+ public void waitAllTasksExecuted() throws ExecutionException, InterruptedException {
+ final CountDownLatch started = new CountDownLatch(myMaxTasks);
+ final CountDownLatch readyToFinish = new CountDownLatch(1);
+ // start myMaxTasks runnables which will spread to all available executor threads
+ // and wait for them all to finish
+ List futures = ContainerUtil.map(Collections.nCopies(myMaxTasks, null), new Function
- *
- * @param build contains information about the root Gradle project and its sub-projects. Such information includes the physical path of
- * the root Gradle project and its sub-projects.
- * @param path the Gradle "logical" path. This path uses colon as separator, and may or may not be equal to the physical path of a
- * Gradle project.
- * @return the physical path of the module's root directory.
- */
- @Nullable
- static File getModuleDirPath(@NotNull GradleBuild build, @NotNull String path) {
- for (BasicGradleProject project : build.getProjects()) {
- if (project.getPath().equals(path)) {
- return project.getProjectDirectory();
- }
- }
- return null;
- }
-
/**
* Stores information about given directories at the given content root
*
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/DefaultProjectResolverContext.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/DefaultProjectResolverContext.java
new file mode 100644
index 000000000000..ffdab0cad888
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/DefaultProjectResolverContext.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2000-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.service.project;
+
+import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
+import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.util.UserDataHolderBase;
+import org.gradle.tooling.CancellationTokenSource;
+import org.gradle.tooling.ProjectConnection;
+import org.gradle.tooling.model.idea.IdeaModule;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.ProjectImportAction;
+import org.jetbrains.plugins.gradle.settings.GradleExecutionSettings;
+
+import java.util.Collection;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/8/2015
+ */
+public class DefaultProjectResolverContext extends UserDataHolderBase implements ProjectResolverContext {
+ @NotNull private final ExternalSystemTaskId myExternalSystemTaskId;
+ @NotNull private final String myProjectPath;
+ @Nullable private final GradleExecutionSettings mySettings;
+ @NotNull private final ExternalSystemTaskNotificationListener myListener;
+ private ProjectConnection myConnection;
+ @Nullable private CancellationTokenSource myCancellationTokenSource;
+ private final boolean myIsPreviewMode;
+ @NotNull
+ private ProjectImportAction.AllModels myModels;
+
+ public DefaultProjectResolverContext(@NotNull final ExternalSystemTaskId externalSystemTaskId,
+ @NotNull final String projectPath,
+ @Nullable final GradleExecutionSettings settings,
+ @NotNull final ExternalSystemTaskNotificationListener listener,
+ final boolean isPreviewMode) {
+ this(externalSystemTaskId, projectPath, settings, null, listener, isPreviewMode);
+ }
+
+
+ public DefaultProjectResolverContext(@NotNull final ExternalSystemTaskId externalSystemTaskId,
+ @NotNull final String projectPath,
+ @Nullable final GradleExecutionSettings settings,
+ final ProjectConnection connection,
+ @NotNull final ExternalSystemTaskNotificationListener listener,
+ final boolean isPreviewMode) {
+ myExternalSystemTaskId = externalSystemTaskId;
+ myProjectPath = projectPath;
+ mySettings = settings;
+ myConnection = connection;
+ myListener = listener;
+ myIsPreviewMode = isPreviewMode;
+ }
+
+ @NotNull
+ public ExternalSystemTaskId getExternalSystemTaskId() {
+ return myExternalSystemTaskId;
+ }
+
+ @Nullable
+ public String getIdeProjectPath() {
+ return mySettings != null ? mySettings.getIdeProjectPath() : null;
+ }
+
+ @NotNull
+ public String getProjectPath() {
+ return myProjectPath;
+ }
+
+ @Nullable
+ public GradleExecutionSettings getSettings() {
+ return mySettings;
+ }
+
+ @NotNull
+ public ProjectConnection getConnection() {
+ return myConnection;
+ }
+
+ public void setConnection(@NotNull ProjectConnection connection) {
+ myConnection = connection;
+ }
+
+ @Nullable
+ public CancellationTokenSource getCancellationTokenSource() {
+ return myCancellationTokenSource;
+ }
+
+ public void setCancellationTokenSource(@Nullable CancellationTokenSource cancellationTokenSource) {
+ myCancellationTokenSource = cancellationTokenSource;
+ }
+
+ @NotNull
+ public ExternalSystemTaskNotificationListener getListener() {
+ return myListener;
+ }
+
+ public boolean isPreviewMode() {
+ return myIsPreviewMode;
+ }
+
+ @NotNull
+ public ProjectImportAction.AllModels getModels() {
+ return myModels;
+ }
+
+ public void setModels(@NotNull ProjectImportAction.AllModels models) {
+ myModels = models;
+ }
+
+ @Nullable
+ public T getExtraProject(Class modelClazz) {
+ return myModels.getExtraProject(null, modelClazz);
+ }
+
+ @Nullable
+ public T getExtraProject(@Nullable IdeaModule module, Class modelClazz) {
+ return myModels.getExtraProject(module, modelClazz);
+ }
+
+ @NotNull
+ public Collection findModulesWithModel(@NotNull Class modelClazz) {
+ return myModels.findModulesWithModel(modelClazz);
+ }
+
+ public boolean hasModulesWithModel(@NotNull Class modelClazz) {
+ return myModels.hasModulesWithModel(modelClazz);
+ }
+
+ public void checkCancelled() {
+ if (myCancellationTokenSource != null && myCancellationTokenSource.token().isCancellationRequested()) {
+ throw new ProcessCanceledException();
+ }
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
index 5f7cf97109d6..f10eb2a2eedb 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
@@ -105,18 +105,17 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver resultProjectDataNode = myHelper.execute(
- projectPath, settings,
- new ProjectConnectionDataNodeFunction(
- id, projectPath, settings, listener, isPreviewMode, projectResolverChain, false)
+ projectPath, settings, new ProjectConnectionDataNodeFunction(resolverContext, projectResolverChain, false)
);
// auto-discover buildSrc project if needed
final String buildSrcProjectPath = projectPath + "/buildSrc";
- handleBuildSrcProject(
- resultProjectDataNode,
- new ProjectConnectionDataNodeFunction(id, buildSrcProjectPath, settings, listener, isPreviewMode, projectResolverChain, true)
- );
+ DefaultProjectResolverContext buildSrcResolverCtx =
+ new DefaultProjectResolverContext(id, buildSrcProjectPath, settings, listener, isPreviewMode);
+ resolverContext.copyUserDataTo(buildSrcResolverCtx);
+ handleBuildSrcProject(resultProjectDataNode, new ProjectConnectionDataNodeFunction(buildSrcResolverCtx, projectResolverChain, true));
return resultProjectDataNode;
}
@@ -131,7 +130,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver doResolveProjectInfo(@NotNull final ProjectResolverContext resolverCtx,
+ private DataNode doResolveProjectInfo(@NotNull final DefaultProjectResolverContext resolverCtx,
@NotNull final GradleProjectResolverExtension projectResolverChain,
boolean isBuildSrcProject)
throws IllegalArgumentException, IllegalStateException {
@@ -200,6 +199,7 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver resultProjectDataNode,
@NotNull final ProjectConnectionDataNodeFunction projectConnectionDataNodeFunction) {
- if (!new File(projectConnectionDataNodeFunction.myProjectPath).isDirectory()) {
+ final String projectPath = projectConnectionDataNodeFunction.myResolverContext.getProjectPath();
+ if (!new File(projectPath).isDirectory()) {
return;
}
- if (projectConnectionDataNodeFunction.myIsPreviewMode) {
+ if (projectConnectionDataNodeFunction.myResolverContext.isPreviewMode()) {
ModuleData buildSrcModuleData =
- new ModuleData(":buildSrc", GradleConstants.SYSTEM_ID, StdModuleTypes.JAVA.getId(), "buildSrc",
- projectConnectionDataNodeFunction.myProjectPath, projectConnectionDataNodeFunction.myProjectPath);
+ new ModuleData(":buildSrc", GradleConstants.SYSTEM_ID, StdModuleTypes.JAVA.getId(), "buildSrc", projectPath, projectPath);
resultProjectDataNode.createChild(ProjectKeys.MODULE, buildSrcModuleData);
return;
}
final DataNode buildSrcModuleDataNode =
- GradleProjectResolverUtil.findModule(resultProjectDataNode, projectConnectionDataNodeFunction.myProjectPath);
+ GradleProjectResolverUtil.findModule(resultProjectDataNode, projectPath);
// check if buildSrc project was already exposed in settings.gradle file
if (buildSrcModuleDataNode != null) return;
final DataNode buildSrcProjectDataDataNode = myHelper.execute(
- projectConnectionDataNodeFunction.myProjectPath, projectConnectionDataNodeFunction.mySettings, projectConnectionDataNodeFunction);
+ projectPath, projectConnectionDataNodeFunction.myResolverContext.getSettings(), projectConnectionDataNodeFunction);
if (buildSrcProjectDataDataNode != null) {
for (DataNode moduleNode : ExternalSystemApiUtil.getChildren(buildSrcProjectDataDataNode, ProjectKeys.MODULE)) {
@@ -658,26 +658,13 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver> {
- @NotNull private final ExternalSystemTaskId myId;
- @NotNull private final String myProjectPath;
- @Nullable private final GradleExecutionSettings mySettings;
- @NotNull private final ExternalSystemTaskNotificationListener myListener;
- private final boolean myIsPreviewMode;
@NotNull private final GradleProjectResolverExtension myProjectResolverChain;
private final boolean myIsBuildSrcProject;
+ private DefaultProjectResolverContext myResolverContext;
- public ProjectConnectionDataNodeFunction(@NotNull ExternalSystemTaskId id,
- @NotNull String projectPath,
- @Nullable GradleExecutionSettings settings,
- @NotNull ExternalSystemTaskNotificationListener listener,
- boolean isPreviewMode,
- @NotNull GradleProjectResolverExtension projectResolverChain,
- boolean isBuildSrcProject) {
- myId = id;
- myProjectPath = projectPath;
- mySettings = settings;
- myListener = listener;
- myIsPreviewMode = isPreviewMode;
+ public ProjectConnectionDataNodeFunction(@NotNull DefaultProjectResolverContext resolverContext,
+ @NotNull GradleProjectResolverExtension projectResolverChain, boolean isBuildSrcProject) {
+ myResolverContext = resolverContext;
myProjectResolverChain = projectResolverChain;
myIsBuildSrcProject = isBuildSrcProject;
}
@@ -685,13 +672,12 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver fun(ProjectConnection connection) {
try {
- return doResolveProjectInfo(
- new ProjectResolverContext(myId, myProjectPath, mySettings, connection, myListener, myIsPreviewMode),
- myProjectResolverChain, myIsBuildSrcProject);
+ myResolverContext.setConnection(connection);
+ return doResolveProjectInfo(myResolverContext, myProjectResolverChain, myIsBuildSrcProject);
}
catch (RuntimeException e) {
LOG.info("Gradle project resolve error", e);
- throw myProjectResolverChain.getUserFriendlyError(e, myProjectPath, null);
+ throw myProjectResolverChain.getUserFriendlyError(e, myResolverContext.getProjectPath(), null);
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtil.java
index c53def95c073..3b0188a3fea7 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolverUtil.java
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.gradle.service.project;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.externalSystem.model.DataNode;
import com.intellij.openapi.externalSystem.model.Key;
import com.intellij.openapi.externalSystem.model.ProjectKeys;
@@ -22,6 +23,8 @@ import com.intellij.openapi.externalSystem.model.project.*;
import com.intellij.openapi.externalSystem.model.task.TaskData;
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.externalSystem.util.ExternalSystemDebugEnvironment;
+import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
@@ -30,6 +33,8 @@ import com.intellij.util.BooleanFunction;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.gradle.tooling.model.GradleProject;
+import org.gradle.tooling.model.gradle.BasicGradleProject;
+import org.gradle.tooling.model.gradle.GradleBuild;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.util.GradleVersion;
import org.jetbrains.annotations.NotNull;
@@ -39,8 +44,10 @@ import org.jetbrains.plugins.gradle.ExternalDependencyId;
import org.jetbrains.plugins.gradle.model.*;
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData;
import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.jetbrains.plugins.gradle.util.GradleUtil;
import java.io.File;
+import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Queue;
@@ -50,9 +57,107 @@ import java.util.Queue;
* @since 10/6/2015
*/
public class GradleProjectResolverUtil {
+ private static final Logger LOG = Logger.getInstance(GradleProjectResolverUtil.class);
@NotNull
private static final Key