Merge remote-tracking branch 'origin/master' into develar/is
authorVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Mon, 18 Jul 2016 11:58:00 +0000 (13:58 +0200)
committerVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Mon, 18 Jul 2016 11:58:00 +0000 (13:58 +0200)
37 files changed:
build/groovy/org/jetbrains/intellij/build/impl/LibraryLicensesListGenerator.groovy
java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
java/java-tests/testSrc/com/intellij/codeInsight/GenerateEquals15Test.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java
platform/analysis-impl/src/com/intellij/codeHighlighting/RainbowHighlighter.java
platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java
platform/configuration-store-impl/src/FileBasedStorage.kt
platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java
platform/core-impl/src/com/intellij/openapi/progress/impl/CoreProgressManager.java
platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonCodeAnalyzerImpl.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SlowLineMarkersPass.java
platform/platform-api/src/com/intellij/openapi/actionSystem/DataConstants.java
platform/platform-api/src/com/intellij/openapi/actionSystem/ex/ActionUtil.java
platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java
platform/testFramework/src/_LastInSuiteTest.java
platform/testFramework/src/com/intellij/TestAll.java
platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java
platform/testFramework/src/com/intellij/testFramework/LightPlatformCodeInsightTestCase.java
platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
platform/util/src/com/intellij/openapi/util/TextRange.java
platform/util/src/com/intellij/openapi/util/io/StreamUtil.java
platform/util/src/com/intellij/util/PausesStat.java
platform/util/src/com/intellij/util/containers/UnsignedShortArrayList.java [new file with mode: 0644]
platform/util/src/com/intellij/util/text/DateFormatUtil.java
platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/VariableAccessVisitor.java
plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java
plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java
plugins/git4idea/testData/repo/symbolic-refs/current-branch.txt
python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralReferenceSearcher.java
spellchecker/src/com/intellij/spellchecker/jetbrains.dic

index a7b3073da7dbc1cba801f806e4e0ed34d1f25a9a..bc625a824b11584030606e769d18df9a3d52fd38 100644 (file)
@@ -133,7 +133,7 @@ class LibraryLicensesListGenerator {
       errorMessage << "Licenses aren't specified for ${withoutLicenses.size()} libraries:"
       withoutLicenses.sort(true, String.CASE_INSENSITIVE_ORDER)
       withoutLicenses.each { errorMessage << it }
-      errorMessage << "If a library is packaged into IDEA installation information about its license must be added to libLicenses.gant file"
+      errorMessage << "If a library is packaged into IDEA installation information about its license must be added into one of *LibraryLicenses.groovy files"
       errorMessage << "If a library is used in tests only change its scope to 'Test'"
       errorMessage << "If a library is used for compilation only change its scope to 'Provided'"
       projectBuilder.error(errorMessage.join("\n"))
index 8cf092e4317680b6e86b560a8592e7e67715bf6b..0b06c9168b16e8d1fd45248938d1e0a8048b4aaa 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.FoldingGroup;
 import com.intellij.openapi.progress.ProgressIndicatorProvider;
+import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.DumbService;
 import com.intellij.openapi.project.IndexNotReadyException;
@@ -522,6 +523,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
 
     PsiClass[] classes = file.getClasses();
     for (PsiClass aClass : classes) {
+      ProgressManager.checkCanceled();
       ProgressIndicatorProvider.checkCanceled();
       addElementsToFold(descriptors, aClass, document, true, quick);
     }
index b6b728192713b6c34c6ee309c757f8cd342dc942..a540eceacad88327153999cc5c64f299d4ef6ece 100644 (file)
@@ -25,12 +25,14 @@ public class FileComparisonFailure extends ComparisonFailure implements KnownExc
   private final String myFilePath;
   private final String myActualFilePath;
 
-  public FileComparisonFailure(String message, String expected, String actual, String filePath) {
-    this(message, expected, actual, filePath, null);
+  public FileComparisonFailure(String message, /*@NotNull */String expected, /*@NotNull */String actual, String expectedFilePath) {
+    this(message, expected, actual, expectedFilePath, null);
   }
 
-  public FileComparisonFailure(String message, String expected, String actual, String expectedFilePath, String actualFilePath) {
+  public FileComparisonFailure(String message, /*@NotNull */String expected, /*@NotNull */String actual, String expectedFilePath, String actualFilePath) {
     super(message, expected, actual);
+    if (expected == null) throw new NullPointerException("'expected' must not be null");
+    if (actual == null) throw new NullPointerException("'actual' must not be null");
     myExpected = expected;
     myActual = actual;
     myFilePath = expectedFilePath;
@@ -60,7 +62,7 @@ public class FileComparisonFailure extends ComparisonFailure implements KnownExc
   private static class MyPacketFactory extends ComparisonDetailsExtractor {
     private final String myFilePath;
 
-    public MyPacketFactory(ComparisonFailure assertion, String expected, String actual, String filePath) {
+    MyPacketFactory(ComparisonFailure assertion, String expected, String actual, String filePath) {
       super(assertion, expected, actual);
       myFilePath = filePath;
     }
index be02e9c483c4a33b77994e72d8b4304fcfd9d551..6cff93155fd600706c5baec9ad909ca618b246e7 100644 (file)
@@ -17,7 +17,7 @@ package com.intellij.codeInsight;
 
 import com.intellij.codeInsight.generation.EqualsHashCodeTemplatesManager;
 import com.intellij.psi.PsiField;
-import com.intellij.util.Function;
+import com.intellij.util.Functions;
 
 /**
  * @author dsl
@@ -28,32 +28,32 @@ public class GenerateEquals15Test extends GenerateEqualsTestCase {
   }
 
   public void testDifferentTypes() throws Exception {
-    doTest(Function.ID, Function.ID, fields -> PsiField.EMPTY_ARRAY, true
+    doTest(Functions.id(), Functions.id(), fields -> PsiField.EMPTY_ARRAY, true
     );
   }
 
   public void testDifferentTypesGetters() throws Exception {
-    doTest(Function.ID, Function.ID, fields -> PsiField.EMPTY_ARRAY, true, true);
+    doTest(Functions.id(), Functions.id(), fields -> PsiField.EMPTY_ARRAY, true, true);
   }
 
   public void testDifferentTypesAllNotNull() throws Exception {
-    doTest(Function.ID, Function.ID, Function.ID, true);
+    doTest(Functions.id(), Functions.id(), Functions.id(), true);
   }
 
   public void testDifferentTypesSuperEqualsAndHashCode() throws Exception {
-    doTest(Function.ID, Function.ID, Function.ID, true);
+    doTest(Functions.id(), Functions.id(), Functions.id(), true);
   }
 
   public void testDifferentTypesNoDouble() throws Exception {
-    doTest(Function.ID, Function.ID, Function.ID, true);
+    doTest(Functions.id(), Functions.id(), Functions.id(), true);
   }
 
   public void testNameConflicts() throws Exception {
-    doTest(Function.ID, Function.ID, Function.ID, true);
+    doTest(Functions.id(), Functions.id(), Functions.id(), true);
   }
 
   public void testClassWithTypeParams() throws Exception {
-    doTest(Function.ID, Function.ID, Function.ID, true);
+    doTest(Functions.id(), Functions.id(), Functions.id(), true);
   }
 
   public void testDifferentTypesSuperEqualsAndHashCodeApache3() throws Exception {
@@ -71,7 +71,7 @@ public class GenerateEquals15Test extends GenerateEqualsTestCase {
   private void doTestWithTemplate(String templateName) throws Exception {
     try {
       EqualsHashCodeTemplatesManager.getInstance().setDefaultTemplate(templateName);
-      doTest(Function.ID, Function.ID, Function.ID, true);
+      doTest(Functions.id(), Functions.id(), Functions.id(), true);
     }
     finally {
       EqualsHashCodeTemplatesManager.getInstance().setDefaultTemplate(EqualsHashCodeTemplatesManager.INTELLI_J_DEFAULT);
index e9f0b8b7543ddc9e05d6f3ee8005b036f318c193..9edddb3fe94e9f285d8fc2949f9ce836c2a117e2 100644 (file)
@@ -58,10 +58,7 @@ import com.intellij.lang.annotation.ExternalAnnotator;
 import com.intellij.lang.annotation.HighlightSeverity;
 import com.intellij.lang.java.JavaLanguage;
 import com.intellij.openapi.Disposable;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.DataConstants;
-import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.IdeActions;
+import com.intellij.openapi.actionSystem.*;
 import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
 import com.intellij.openapi.application.AccessToken;
 import com.intellij.openapi.application.ApplicationManager;
@@ -144,6 +141,7 @@ import java.util.concurrent.atomic.AtomicReference;
 /**
  * @author cdr
  */
+@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
 @SkipSlowTestLocally
 public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
   private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/typing/";
@@ -677,7 +675,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
     assertEquals("Variable 'e' is already defined in the scope", error.getDescription());
     PsiElement element = getFile().findElementAt(getEditor().getCaretModel().getOffset()).getParent();
 
-    DataContext dataContext = SimpleDataContext.getSimpleContext(DataConstants.PSI_ELEMENT, element, ((EditorEx)getEditor()).getDataContext());
+    DataContext dataContext = SimpleDataContext.getSimpleContext(CommonDataKeys.PSI_ELEMENT.getName(), element, ((EditorEx)getEditor()).getDataContext());
     new InlineRefactoringActionHandler().invoke(getProject(), getEditor(), getFile(), dataContext);
 
     Collection<HighlightInfo> afterTyping = highlightErrors();
@@ -1579,66 +1577,37 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
     int N = Math.max(5, Timings.adjustAccordingToMySpeed(80, true));
     System.out.println("N = " + N);
     final long[] interruptTimes = new long[N];
-    List<Thread> watchers = new ArrayList<>();
     for (int i = 0; i < N; i++) {
       codeAnalyzer.restart();
       final int finalI = i;
       final long start = System.currentTimeMillis();
-      Runnable interrupt = () -> {
-        long now = System.currentTimeMillis();
-        if (now - start < 100) {
-          // wait to engage all highlighting threads
-          return;
-        }
-        final AtomicLong typingStart = new AtomicLong();
-        final DaemonProgressIndicator progress = codeAnalyzer.getUpdateProgress();
-        Thread watcher = new Thread("reactivity watcher") {
-          @Override
-          public void run() {
-            while (true) {
-              final long start1 = typingStart.get();
-              if (start1 == -1) break;
-              if (start1 == 0) {
-                try {
-                  Thread.sleep(5);
-                }
-                catch (InterruptedException e1) {
-                  throw new RuntimeException(e1);
-                }
-                continue;
+      final AtomicLong typingStart = new AtomicLong();
+      Thread watcher = new Thread("reactivity watcher") {
+        @Override
+        public void run() {
+          while (true) {
+            final long start1 = typingStart.get();
+            if (start1 == -1) break;
+            if (start1 == 0) {
+              try {
+                Thread.sleep(5);
               }
-              long now = System.currentTimeMillis();
-              if (now - start1 > 500) {
-                // too long, see WTF
-                PerformanceWatcher.dumpThreadsToConsole("Too long interrupt: " +
-                                                        (now - start1) +
-                                                        "; Progress canceled=" +
-                                                        progress.isCanceled() +
-                                                        "\n----------------------------");
-                System.err.println("----all threads---");
-                for (Thread thread : Thread.getAllStackTraces().keySet()) {
-                  boolean canceled = CoreProgressManager.isCanceledThread(thread);
-                  if (canceled) {
-                    System.err.println("Thread " + thread + " is canceled");
-                  }
-                }
-                System.err.println("----///////---");
-                break;
+              catch (InterruptedException e1) {
+                throw new RuntimeException(e1);
               }
+              continue;
+            }
+            long elapsed = System.currentTimeMillis() - start1;
+            if (elapsed > 500) {
+              // too long, see WTF
+              String message = "Too long interrupt: " + elapsed +
+                               "; Progress: " + codeAnalyzer.getUpdateProgress() +
+                               "\n----------------------------";
+              dumpThreadsToConsole();
+              throw new RuntimeException(message);
             }
           }
-        };
-        watcher.start();
-        watchers.add(watcher);
-        typingStart.set(System.currentTimeMillis());
-        type(' ');
-        typingStart.set(-1);
-        long end = System.currentTimeMillis();
-        long interruptTime = end - now;
-        interruptTimes[finalI] = interruptTime;
-        assertNull(codeAnalyzer.getUpdateProgress());
-        System.out.println(interruptTime);
-        throw new ProcessCanceledException();
+        }
       };
       try {
         PsiFile file = getFile();
@@ -1647,20 +1616,53 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
         CodeInsightTestFixtureImpl.ensureIndexesUpToDate(project);
         TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(editor);
         PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+        watcher.start();
+        Runnable interrupt = () -> {
+          long now = System.currentTimeMillis();
+          if (now - start < 100) {
+            // wait to engage all highlighting threads
+            return;
+          }
+          typingStart.set(System.currentTimeMillis());
+          type(' ');
+          long end = System.currentTimeMillis();
+          long interruptTime = end - now;
+          interruptTimes[finalI] = interruptTime;
+          assertNull(codeAnalyzer.getUpdateProgress());
+          System.out.println(interruptTime);
+          throw new ProcessCanceledException();
+        };
+        long hiStart = System.currentTimeMillis();
         codeAnalyzer.runPasses(file, editor.getDocument(), textEditor, ArrayUtil.EMPTY_INT_ARRAY, false, interrupt);
+        long hiEnd = System.currentTimeMillis();
         DaemonProgressIndicator progress = codeAnalyzer.getUpdateProgress();
-        throw new RuntimeException("should have been interrupted: "+progress);
+        String message = "Should have been interrupted: " + progress + "; Elapsed: " + (hiEnd - hiStart) + "ms";
+        dumpThreadsToConsole();
+        throw new RuntimeException(message);
       }
       catch (ProcessCanceledException ignored) {
       }
+      finally {
+        typingStart.set(-1); // cancel watcher
+        watcher.join();
+      }
     }
 
     long ave = ArrayUtil.averageAmongMedians(interruptTimes, 3);
     System.out.println("Average among the N/3 median times: " + ave + "ms");
     assertTrue(ave < 300);
-    for (Thread watcher : watchers) {
-      watcher.join();
+  }
+
+  private static void dumpThreadsToConsole() {
+    PerformanceWatcher.dumpThreadsToConsole("");
+    System.err.println("----all threads---");
+    for (Thread thread : Thread.getAllStackTraces().keySet()) {
+      boolean canceled = CoreProgressManager.isCanceledThread(thread);
+      if (canceled) {
+        System.err.println("Thread " + thread + " indicator is canceled");
+      }
     }
+    System.err.println("----///////---");
   }
 
   public void testTypingLatencyPerformance() throws Throwable {
index f31fd8494c6dc8d5b35f8920c8656810dbee2607..2ba41926c5b85c7f89f6b400936d4de4c4a76e02 100644 (file)
@@ -36,15 +36,10 @@ import java.util.List;
 import java.util.stream.Collectors;
 
 public class RainbowHighlighter {
-  private final float[] myFloats;
   @NotNull private final TextAttributesScheme myColorsScheme;
 
   public RainbowHighlighter(@Nullable TextAttributesScheme colorsScheme) {
     myColorsScheme = colorsScheme != null ? colorsScheme : EditorColorsManager.getInstance().getGlobalScheme();
-    TextAttributes attributes = myColorsScheme.getAttributes(DefaultLanguageHighlighterColors.CONSTANT);
-    Color foregroundColor = attributes.getForegroundColor();
-    float[] components = foregroundColor.getRGBColorComponents(null);
-    myFloats = Color.RGBtoHSB((int)(255 * components[0]), (int)(255 * components[0]), (int)(255 * components[0]), null);
   }
 
   public static final HighlightInfoType RAINBOW_ELEMENT = new HighlightInfoType.HighlightInfoTypeImpl(HighlightSeverity.INFORMATION, DefaultLanguageHighlighterColors.CONSTANT);
@@ -72,7 +67,7 @@ public class RainbowHighlighter {
 
     final float colors = 36.0f;
     final float v = Math.round(Math.abs(colors * hash) / Integer.MAX_VALUE) / colors;
-    return Color.getHSBColor(v, 0.7f, myFloats[2] + .3f);
+    return Color.getHSBColor(v, 0.7f, .3f);
   }
 
   public HighlightInfo getInfo(@Nullable String nameKey, @Nullable PsiElement id, @Nullable TextAttributesKey colorKey) {
index d228c87b3614fff685bd7ffaf56cd39e2245a0b7..f2c83228205ce7fc52f23147cdf907a67006b273 100644 (file)
@@ -183,21 +183,16 @@ public class HighlightInfo implements Segment {
     TextAttributes attributes = getAttributesByType(element, type, colorsScheme);
     if (element != null &&
         RainbowHighlighter.isRainbowEnabled() &&
-        !isByPass(element) &&
         isLikeVariable(type.getAttributesKey())) {
-      String text = element.getContainingFile().getText();
-      String name = text.substring(startOffset, endOffset);
-      attributes = new RainbowHighlighter(colorsScheme).getAttributes(name, attributes);
+      PsiFile containingFile = element.getContainingFile();
+      if (!RainbowVisitor.existsPassSuitableForFile(containingFile)) {
+        CharSequence text = containingFile.getViewProvider().getContents().subSequence(startOffset, endOffset);
+        attributes = new RainbowHighlighter(colorsScheme).getAttributes(text.toString(), attributes);
+      }
     }
     return attributes;
   }
 
-  @Contract("null -> false")
-  public static boolean isByPass(@Nullable PsiElement element) {
-    return element != null
-           && RainbowVisitor.existsPassSuitableForFile(element.getContainingFile());
-  }
-
   @Contract("null -> false")
   private static boolean isLikeVariable(TextAttributesKey key) {
     if (key == null) return false;
index ed4fd0cf9f7d79b58c1046fb5ac7c702df37dd24..da3320122ea92edd61f5c52714190fdc0932a6f6 100644 (file)
@@ -273,4 +273,4 @@ fun deleteFile(requestor: Any, virtualFile: VirtualFile) {
   runWriteAction { virtualFile.delete(requestor) }
 }
 
-internal class ReadOnlyModificationException(val file: VirtualFile, val session: StateStorage.SaveSession?) : RuntimeException()
\ No newline at end of file
+internal class ReadOnlyModificationException(val file: VirtualFile, val session: StateStorage.SaveSession?) : RuntimeException("File is read-only: "+file)
\ No newline at end of file
index 17fffb76466c0c1dbee408a42aca3bf7920ffd0d..3497d6ec8c3edf3a7e8254ecf8b735da123079c3 100644 (file)
@@ -39,6 +39,7 @@ public abstract class ApplicationAdapter implements ApplicationListener {
   public void writeActionFinished(@NotNull Object action) {
   }
 
+  @Override
   public void afterWriteActionFinished(@NotNull Object action) {
   }
 }
\ No newline at end of file
index a902109fe94acb1e173555ef617972d156195d4b..5b384707cdcdf1943d52ec3e018ed31758e9b432 100644 (file)
@@ -35,6 +35,7 @@ import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.SmartHashSet;
 import com.intellij.util.io.storage.HeavyProcessLatch;
 import gnu.trove.THashMap;
+import gnu.trove.THashSet;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -62,7 +63,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
   // the active indicator for the thread id
   private static final ConcurrentLongObjectMap<ProgressIndicator> currentIndicators = ContainerUtil.createConcurrentLongObjectMap();
   // threads which are running under canceled indicator
-  static final Set<Thread> threadsUnderCanceledIndicator = ContainerUtil.newConcurrentSet();
+  static final Set<Thread> threadsUnderCanceledIndicator = new THashSet<Thread>(); // guarded by threadsUnderIndicator
   private static volatile boolean shouldCheckCanceled;
 
   /** active (i.e. which have {@link #executeProcessUnderProgress(Runnable, ProgressIndicator)} method running) indicators
@@ -639,7 +640,9 @@ public class CoreProgressManager extends ProgressManager implements Disposable {
 
   @TestOnly
   public static boolean isCanceledThread(@NotNull Thread thread) {
-    return threadsUnderCanceledIndicator.contains(thread);
+    synchronized (threadsUnderIndicator) {
+      return threadsUnderCanceledIndicator.contains(thread);
+    }
   }
 
   @NotNull
index 0a069a9ca0c8ab1ad21f8eef8ba4449ca5351cc6..f4a77ecc2759b2562a9c2603e9151be77e719fe1 100644 (file)
@@ -15,7 +15,6 @@
  */
 package com.intellij.psi.impl;
 
-import com.intellij.diagnostic.ThreadDumper;
 import com.intellij.lang.ASTNode;
 import com.intellij.lang.FileASTNode;
 import com.intellij.openapi.Disposable;
@@ -86,7 +85,6 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
   private volatile boolean isDisposed;
   private CommitTask currentTask; // guarded by lock
   private boolean myEnabled; // true if we can do commits. set to false temporarily during the write action.  guarded by lock
-  private int runningWriteActions; // accessed in EDT only
 
   public static DocumentCommitThread getInstance() {
     return (DocumentCommitThread)ServiceManager.getService(DocumentCommitProcessor.class);
@@ -97,33 +95,18 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
     application.invokeLater(new Runnable() {
       @Override
       public void run() {
-        assert runningWriteActions == 0;
         if (application.isDisposed()) return;
         assert !application.isWriteAccessAllowed() || application.isUnitTestMode(); // crazy stuff happens in tests, e.g. UIUtil.dispatchInvocationEvents() inside write action
         application.addApplicationListener(new ApplicationAdapter() {
           @Override
           public void beforeWriteActionStart(@NotNull Object action) {
-            int writeActionsBefore = runningWriteActions++;
-            if (writeActionsBefore == 0) {
-              disable("Write action started: " + action);
-            }
+            disable("Write action started: " + action);
           }
 
           @Override
-          public void writeActionFinished(@NotNull Object action) {
+          public void afterWriteActionFinished(@NotNull Object action) {
             // crazy things happen when running tests, like starting write action in one thread but firing its end in the other
-            int writeActionsAfter = runningWriteActions = Math.max(0,runningWriteActions-1);
-            if (writeActionsAfter == 0) {
-              enable("Write action finished: " + action);
-            }
-            else {
-              if (writeActionsAfter < 0) {
-                System.err.println("mismatched listeners: " + writeActionsAfter + ";\n==== log==="+log+"\n====end log==="+
-                                   ";\n=======threaddump====\n" +
-                                   ThreadDumper.dumpThreadsToString()+"\n=====END threaddump=======");
-                assert false;
-              }
-            }
+            enable("Write action finished: " + action);
           }
         }, DocumentCommitThread.this);
 
@@ -685,7 +668,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
 
   @Override
   public String toString() {
-    return "Document commit thread; application: "+myApplication+"; isDisposed: "+isDisposed+"; myEnabled: "+isEnabled()+"; runningWriteActions: "+runningWriteActions;
+    return "Document commit thread; application: "+myApplication+"; isDisposed: "+isDisposed+"; myEnabled: "+isEnabled();
   }
 
   @TestOnly
index b2c2a94358815c0fb66b69617c99429c2ea819f2..9a5f9f01b017a9a6d96b37fc4dbf0947196a1dac 100644 (file)
@@ -416,6 +416,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements Pers
     }
   }
 
+  @TestOnly
   private boolean waitInOtherThread(int millis, boolean canChangeDocument) throws Throwable {
     Disposable disposable = Disposer.newDisposable();
     // last hope protection against PsiModificationTrackerImpl.incCounter() craziness (yes, Kotlin)
@@ -461,6 +462,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements Pers
     }
   }
 
+  @TestOnly
   void waitForTermination() {
     myPassExecutorService.cancelAll(true);
   }
@@ -960,6 +962,7 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzerEx implements Pers
     return myEditorTracker.getActiveEditors();
   }
 
+  @TestOnly
   private static void wrap(@NotNull ThrowableRunnable runnable) {
     try {
       runnable.run();
index 762df47b98085eda8a7accf1ee64a33f17c7419c..a6102236fcb46a9066ff17b7694e09e5ce42dc20 100644 (file)
@@ -38,6 +38,7 @@ import com.intellij.openapi.editor.markup.SeparatorPlacement;
 import com.intellij.openapi.progress.EmptyProgressIndicator;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.DumbService;
 import com.intellij.openapi.project.IndexNotReadyException;
@@ -163,12 +164,12 @@ public class LineMarkersPass extends TextEditorHighlightingPass implements LineM
                              @NotNull ProgressIndicator progress) throws ProcessCanceledException {
     ApplicationManager.getApplication().assertReadAccessAllowed();
     //noinspection ForLoopReplaceableByForEach
-    for (int i = 0, elementsSize = elements.size(); i < elementsSize; i++) {
+    for (int i = 0; i < elements.size(); i++) {
       PsiElement element = elements.get(i);
-      progress.checkCanceled();
 
       //noinspection ForLoopReplaceableByForEach
-      for (int j = 0, providersSize = providers.size(); j < providersSize; j++) {
+      for (int j = 0; j < providers.size(); j++) {
+        ProgressManager.checkCanceled();
         LineMarkerProvider provider = providers.get(j);
         LineMarkerInfo info;
         try {
index 0996b8b88a8f517b6513591c84c80f0a8065b872..bbcc5b8f6067aff1395f46e3a932e5b49172a776 100644 (file)
@@ -24,6 +24,7 @@ import com.intellij.lang.Language;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.progress.ProcessCanceledException;
 import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -75,6 +76,7 @@ class SlowLineMarkersPass extends TextEditorHighlightingPass implements LineMark
                              @NotNull List<LineMarkerInfo> result,
                              @NotNull ProgressIndicator progress) throws ProcessCanceledException {
     for (LineMarkerProvider provider : providers) {
+      ProgressManager.checkCanceled();
       provider.collectSlowLineMarkers(elements, result);
     }
   }
index 7c8b01316138696357a3bbefdcb1905e2ad0d7b6..5dcf68f05f528d3e23693dd484c36ea3883e2541 100644 (file)
@@ -28,7 +28,7 @@ public interface DataConstants {
   /**
    * Returns {@link com.intellij.openapi.project.Project}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#PROJECT} instead
+   * @deprecated use {@link PlatformDataKeys#PROJECT} instead
    */
   String PROJECT = CommonDataKeys.PROJECT.getName();
 
@@ -42,42 +42,42 @@ public interface DataConstants {
   /**
    * Returns {@link com.intellij.openapi.vfs.VirtualFile}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#VIRTUAL_FILE} instead
+   * @deprecated use {@link PlatformDataKeys#VIRTUAL_FILE} instead
    */
   String VIRTUAL_FILE = CommonDataKeys.VIRTUAL_FILE.getName();
 
   /**
    * Returns array of {@link com.intellij.openapi.vfs.VirtualFile}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#VIRTUAL_FILE_ARRAY} instead
+   * @deprecated use {@link PlatformDataKeys#VIRTUAL_FILE_ARRAY} instead
    */
   String VIRTUAL_FILE_ARRAY = CommonDataKeys.VIRTUAL_FILE_ARRAY.getName();
 
   /**
    * Returns {@link com.intellij.openapi.editor.Editor}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#EDITOR} instead
+   * @deprecated use {@link PlatformDataKeys#EDITOR} instead
    */
   String EDITOR = CommonDataKeys.EDITOR.getName();
 
   /**
    * Returns {@link com.intellij.openapi.fileEditor.FileEditor}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#FILE_EDITOR} instead
+   * @deprecated use {@link PlatformDataKeys#FILE_EDITOR} instead
    */
   String FILE_EDITOR = PlatformDataKeys.FILE_EDITOR.getName();
 
   /**
    * Returns {@link com.intellij.openapi.fileEditor.OpenFileDescriptor}
    *
-   * @deprecated {@link com.intellij.openapi.actionSystem.PlatformDataKeys#NAVIGATABLE} should be used instead
+   * @deprecated {@link PlatformDataKeys#NAVIGATABLE} should be used instead
    */
   @NonNls String OPEN_FILE_DESCRIPTOR = "openFileDescriptor";
 
   /**
    * Returns the text of currently selected file/file revision
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKey#FILE_TEXT} instead
+   * @deprecated use {@link PlatformDataKeys#FILE_TEXT} instead
    */
   String FILE_TEXT = PlatformDataKeys.FILE_TEXT.getName();
 
@@ -86,35 +86,35 @@ public interface DataConstants {
    * Boolean.FALSE if action is executed not in modal context. If context
    * is unknown then the value of this data constant is <code>null</code>.
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#IS_MODAL_CONTEXT} instead
+   * @deprecated use {@link PlatformDataKeys#IS_MODAL_CONTEXT} instead
    */
   String IS_MODAL_CONTEXT = PlatformDataKeys.IS_MODAL_CONTEXT.getName();
 
   /**
    * Returns {@link com.intellij.openapi.diff.DiffViewer}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#DIFF_VIEWER} instead
+   * @deprecated use {@link PlatformDataKeys#DIFF_VIEWER} instead
    */
   String DIFF_VIEWER = PlatformDataKeys.DIFF_VIEWER.getName();
 
   /**
    * Returns help id (String)
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#HELP_ID} instead
+   * @deprecated use {@link PlatformDataKeys#HELP_ID} instead
    */
   String HELP_ID = PlatformDataKeys.HELP_ID.getName();
 
   /**
    * Returns project if project node is selected (in project view)
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#PROJECT_CONTEXT} instead
+   * @deprecated use {@link PlatformDataKeys#PROJECT_CONTEXT} instead
    */
   String PROJECT_CONTEXT = PlatformDataKeys.PROJECT_CONTEXT.getName();
 
   /**
    * Returns module if module node is selected (in module view)
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys.MODULE_CONTEXT} instead
+   * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys#MODULE_CONTEXT} instead
    */
   @NonNls String MODULE_CONTEXT = "context.Module";
 
@@ -126,49 +126,49 @@ public interface DataConstants {
   /**
    * Returns {@link com.intellij.pom.Navigatable}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#NAVIGATABLE} instead
+   * @deprecated use {@link PlatformDataKeys#NAVIGATABLE} instead
    */
   String NAVIGATABLE = CommonDataKeys.NAVIGATABLE.getName();
 
   /**
    * Returns an array of {@link com.intellij.pom.Navigatable}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#NAVIGATABLE_ARRAY} instead
+   * @deprecated use {@link PlatformDataKeys#NAVIGATABLE_ARRAY} instead
    */
   String NAVIGATABLE_ARRAY = CommonDataKeys.NAVIGATABLE_ARRAY.getName();
 
   /**
    * Returns {@link com.intellij.ide.ExporterToTextFile}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#EXPORTER_TO_TEXT_FILE} instead
+   * @deprecated use {@link PlatformDataKeys#EXPORTER_TO_TEXT_FILE} instead
    */
   String EXPORTER_TO_TEXT_FILE = PlatformDataKeys.EXPORTER_TO_TEXT_FILE.getName();
 
   /**
    * Returns {@link com.intellij.psi.PsiElement}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys#PSI_ELEMENT} instead
+   * @deprecated use {@link CommonDataKeys#PSI_ELEMENT} instead
    */
   @NonNls String PSI_ELEMENT = "psi.Element";
 
   /**
    * Returns {@link com.intellij.psi.PsiFile}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.com.intellij.openapi.actionSystem.CommonDataKeys.PSI_FILE} instead
+   * @deprecated use {@link CommonDataKeys#PSI_FILE} instead
    */
   @NonNls String PSI_FILE = "psi.File";
 
   /**
    * Returns {@link com.intellij.lang.Language}
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys.LANGUAGE} instead
+   * @deprecated use {@link com.intellij.openapi.actionSystem.LangDataKeys#LANGUAGE} instead
    */
   @NonNls String LANGUAGE = "Language";
 
   /**
    * Returns java.awt.Component currently in focus, DataContext should be retrieved for
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#CONTEXT_COMPONENT} instead
+   * @deprecated use {@link PlatformDataKeys#CONTEXT_COMPONENT} instead
    */
   String CONTEXT_COMPONENT = PlatformDataKeys.CONTEXT_COMPONENT.getName();
 
@@ -206,45 +206,45 @@ public interface DataConstants {
   /**
    * Returns com.intellij.ide.CopyProvider
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#COPY_PROVIDER} instead
+   * @deprecated use {@link PlatformDataKeys#COPY_PROVIDER} instead
    */
   String COPY_PROVIDER = PlatformDataKeys.COPY_PROVIDER.getName();
 
   /**
    * Returns com.intellij.ide.CutProvider
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#CUT_PROVIDER} instead
+   * @deprecated use {@link PlatformDataKeys#CUT_PROVIDER} instead
    */
   String CUT_PROVIDER = PlatformDataKeys.CUT_PROVIDER.getName();
 
   /**
    * Returns com.intellij.ide.PasteProvider
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#PASTE_PROVIDER} instead
+   * @deprecated use {@link PlatformDataKeys#PASTE_PROVIDER} instead
    */
   String PASTE_PROVIDER = PlatformDataKeys.PASTE_PROVIDER.getName();
 
   /**
    * Returns com.intellij.ide.DeleteProvider
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#DELETE_ELEMENT_PROVIDER} instead
+   * @deprecated use {@link PlatformDataKeys#DELETE_ELEMENT_PROVIDER} instead
    */
   String DELETE_ELEMENT_PROVIDER = PlatformDataKeys.DELETE_ELEMENT_PROVIDER.getName();
 
   /**
    * Returns com.intellij.openapi.editor.Editor even if focuses currently is in find bar
    *
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#EDITOR} instead
+   * @deprecated use {@link PlatformDataKeys#EDITOR} instead
    */
   String EDITOR_EVEN_IF_INACTIVE = CommonDataKeys.EDITOR_EVEN_IF_INACTIVE.getName();
 
   /**
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#SELECTED_ITEM} instead
+   * @deprecated use {@link PlatformDataKeys#SELECTED_ITEM} instead
    */
   String SELECTED_ITEM = PlatformDataKeys.SELECTED_ITEM.getName();
 
   /**
-   * @deprecated use {@link com.intellij.openapi.actionSystem.PlatformDataKeys#DOMINANT_HINT_AREA_RECTANGLE} instead
+   * @deprecated use {@link PlatformDataKeys#DOMINANT_HINT_AREA_RECTANGLE} instead
    */
   String DOMINANT_HINT_AREA_RECTANGLE = PlatformDataKeys.DOMINANT_HINT_AREA_RECTANGLE.getName();
 }
index c2029184e88ee59c3f2de375a00aa74f48453671..b9c6d959b481c376e133f3931ca9e92287c55fb9 100644 (file)
@@ -88,7 +88,6 @@ public class ActionUtil {
            + " not available while " + ApplicationNamesInfo.getInstance().getProductName() + " is updating indices";
   }
 
-  public static final PausesStat ACTION_UPDATE_PAUSES = new PausesStat("AnAction.update()");
   private static int insidePerformDumbAwareUpdate;
   /**
    * @param action action
@@ -113,7 +112,7 @@ public class ActionUtil {
     final boolean notAllowed = dumbMode && !action.isDumbAware();
 
     if (insidePerformDumbAwareUpdate++ == 0) {
-      ACTION_UPDATE_PAUSES.started();
+      ActionPauses.STAT.started();
     }
     try {
       if (beforeActionPerformed) {
@@ -133,7 +132,7 @@ public class ActionUtil {
     }
     finally {
       if (--insidePerformDumbAwareUpdate == 0) {
-        ACTION_UPDATE_PAUSES.finished(presentation.getText()+" action update ("+action.getClass()+")");
+        ActionPauses.STAT.finished(presentation.getText() + " action update (" + action.getClass() + ")");
       }
       if (notAllowed) {
         if (wasEnabledBefore == null) {
@@ -145,6 +144,9 @@ public class ActionUtil {
     
     return false;
   }
+  public static class ActionPauses {
+    public static final PausesStat STAT = new PausesStat("AnAction.update()");
+  }
 
   /**
    * @return whether a dumb mode is in progress for the passed project or, if the argument is null, for any open project.
index 8c5255d63f3b2ad4a9d2527733874f26608bc2c8..fd5dde976fced15ef7786d8296790d6ffbf43f17 100644 (file)
@@ -488,7 +488,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
     if (gatherStatistics) {
       //noinspection TestOnlyProblems
       LOG.info(writeActionStatistics());
-      LOG.info(ActionUtil.ACTION_UPDATE_PAUSES.statistics());
+      LOG.info(ActionUtil.ActionPauses.STAT.statistics());
       //noinspection TestOnlyProblems
       LOG.info(((AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService()).statistics()
                + "; ProcessIOExecutorService threads: "+((ProcessIOExecutorService)ProcessIOExecutorService.INSTANCE).getThreadCounter()
@@ -1026,18 +1026,16 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
   @Override
   public boolean tryRunReadAction(@NotNull Runnable action) {
     //if we are inside read action, do not try to acquire read lock again since it will deadlock if there is a pending writeAction
-    boolean mustAcquire = !isReadAccessAllowed();
-
-    if (mustAcquire) {
-      assertNoPsiLock();
-      if (!myLock.tryReadLock()) return false;
-    }
-
-    try {
+    if (isReadAccessAllowed()) {
       action.run();
     }
-    finally {
-      if (mustAcquire) {
+    else {
+      assertNoPsiLock();
+      if (!myLock.tryReadLock()) return false;
+      try {
+        action.run();
+      }
+      finally {
         endRead();
       }
     }
index f6abe730fb681430bef738897f6796a953a462b4..363d15bf8fafafbcbea39da66628418ef64121d2 100644 (file)
@@ -293,7 +293,7 @@ public class DumbServiceImpl extends DumbService implements Disposable, Modifica
   private void queueUpdateFinished(boolean modal) {
     if (myUpdateFinishedQueued) return;
     myUpdateFinishedQueued = true;
-    TransactionGuard.submitTransaction(myProject, () -> WriteAction.run(() -> updateFinished(modal)));
+    TransactionGuard.submitTransaction(myProject, () -> ApplicationManager.getApplication().runWriteAction(() -> updateFinished(modal)));
   }
 
   private void updateFinished(boolean modal) {
index 72bcca058e93d903102bcb6ee5639a27cc27c327..5e4173fbb4a276c627c1bbb296ecf7c946beab26 100644 (file)
@@ -198,7 +198,7 @@ public class EditorPaintingTest extends AbstractEditorTest {
     }
   }
 
-  private void fail(String message, File expectedResultsFile, BufferedImage actualImage) throws IOException {
+  private void fail(@NotNull String message, @NotNull File expectedResultsFile, BufferedImage actualImage) throws IOException {
     File savedImage = FileUtil.createTempFile(getName(), ".png", false);
     addTmpFileToKeep(savedImage);
     ImageIO.write(actualImage, "png", savedImage);
index 91c3726d5f8e5d3d422a386fd3e7169faa4f1bf0..989bc325ccd4f9bf525618f32f7d9b12ec937d64 100644 (file)
@@ -54,7 +54,7 @@ public class _LastInSuiteTest extends TestCase {
         PlatformTestUtil.cleanupAllProjects();
         ApplicationImpl application = (ApplicationImpl)ApplicationManager.getApplication();
         System.out.println(application.writeActionStatistics());
-        System.out.println(ActionUtil.ACTION_UPDATE_PAUSES.statistics());
+        System.out.println(ActionUtil.ActionPauses.STAT.statistics());
         System.out.println(((AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService()).statistics());
         System.out.println("ProcessIOExecutorService threads created: "+((ProcessIOExecutorService)ProcessIOExecutorService.INSTANCE).getThreadCounter());
 
index 18a93116e5782f6e0673395c8e7baf94b7b979a5..9e1d45db93dcd343110fc69faf2a60c271e1cd48 100644 (file)
@@ -61,7 +61,7 @@ public class TestAll implements Test {
   private static final int CHECK_MEMORY = 8;
   private static final int FILTER_CLASSES = 16;
 
-  public static int ourMode = SAVE_MEMORY_SNAPSHOT /*| START_GUARD | RUN_GC | CHECK_MEMORY*/ | FILTER_CLASSES;
+  private static final int ourMode = SAVE_MEMORY_SNAPSHOT /*| START_GUARD | RUN_GC | CHECK_MEMORY*/ | FILTER_CLASSES;
 
   private static final boolean PERFORMANCE_TESTS_ONLY = System.getProperty(TestCaseLoader.PERFORMANCE_TESTS_ONLY_FLAG) != null;
   private static final boolean INCLUDE_PERFORMANCE_TESTS = System.getProperty(TestCaseLoader.INCLUDE_PERFORMANCE_TESTS_FLAG) != null;
@@ -106,7 +106,7 @@ public class TestAll implements Test {
   private int myLastTestTestMethodCount;
   private TestRecorder myTestRecorder;
   
-  private static List<Throwable> outClassLoadingProblems = new ArrayList<Throwable>();
+  private static final List<Throwable> outClassLoadingProblems = new ArrayList<>();
 
   public TestAll(String packageRoot) throws Throwable {
     this(packageRoot, getClassRoots());
@@ -176,7 +176,7 @@ public class TestAll implements Test {
   }
 
   private static Set<String> normalizePaths(String[] array) {
-    Set<String> answer = new LinkedHashSet<String>(array.length);
+    Set<String> answer = new LinkedHashSet<>(array.length);
     for (String path : array) {
       answer.add(path.replace('\\', '/'));
     }
@@ -326,7 +326,7 @@ public class TestAll implements Test {
     tryGc(10);
   }
 
-  private TestListener loadDiscoveryListener() {
+  private static TestListener loadDiscoveryListener() {
     final String discoveryListener = System.getProperty("test.discovery.listener");
     if (discoveryListener != null) {
       try {
@@ -434,7 +434,7 @@ public class TestAll implements Test {
   private static boolean possibleOutOfMemory(int neededMemory) {
     Runtime runtime = Runtime.getRuntime();
     long maxMemory = runtime.maxMemory();
-    long realFreeMemory = runtime.freeMemory() + (maxMemory - runtime.totalMemory());
+    long realFreeMemory = runtime.freeMemory() + maxMemory - runtime.totalMemory();
     long meg = 1024 * 1024;
     long needed = neededMemory * meg;
     return realFreeMemory < needed;
@@ -466,7 +466,7 @@ public class TestAll implements Test {
 
       if (TestRunnerUtil.isJUnit4TestClass(testCaseClass)) {
         JUnit4TestAdapter adapter = new JUnit4TestAdapter(testCaseClass);
-        boolean runEverything = isIncludingPerformanceTestsRun() || (isPerformanceTest(testCaseClass) && isPerformanceTestsRun());
+        boolean runEverything = isIncludingPerformanceTestsRun() || isPerformanceTest(testCaseClass) && isPerformanceTestsRun();
         if (!runEverything) {
           try {
             adapter.filter(isPerformanceTestsRun() ? PERFORMANCE_ONLY : NO_PERFORMANCE);
@@ -573,7 +573,7 @@ public class TestAll implements Test {
   private static class ExplodedBomb extends TestCase {
     private final Bombed myBombed;
 
-    public ExplodedBomb(String testName, Bombed bombed) {
+    public ExplodedBomb(@NotNull String testName, @NotNull Bombed bombed) {
       super(testName);
       myBombed = bombed;
     }
index 33dd5fbb1aa5d02e131b9e491b500199b99546eb..5d72a50f04be77e5e748fe60a4739c891d013e7a 100644 (file)
@@ -251,7 +251,8 @@ public class EditorTestUtil {
    *
    * @see #extractCaretAndSelectionMarkers(Document, boolean)
    */
-  public static CaretAndSelectionState extractCaretAndSelectionMarkers(Document document) {
+  @NotNull
+  public static CaretAndSelectionState extractCaretAndSelectionMarkers(@NotNull Document document) {
     return extractCaretAndSelectionMarkers(document, true);
   }
 
@@ -261,7 +262,8 @@ public class EditorTestUtil {
    *
    * @param processBlockSelection if <code>true</code>, &lt;block&gt; and &lt;/block&gt; tags describing a block selection state will also be extracted.
    */
-  public static CaretAndSelectionState extractCaretAndSelectionMarkers(final Document document, final boolean processBlockSelection) {
+  @NotNull
+  public static CaretAndSelectionState extractCaretAndSelectionMarkers(@NotNull Document document, final boolean processBlockSelection) {
     return new WriteCommandAction<CaretAndSelectionState>(null) {
       @Override
       public void run(@NotNull Result<CaretAndSelectionState> actionResult) {
@@ -271,9 +273,8 @@ public class EditorTestUtil {
   }
 
   @NotNull
-  public static CaretAndSelectionState extractCaretAndSelectionMarkersImpl(Document document, boolean processBlockSelection) {
+  public static CaretAndSelectionState extractCaretAndSelectionMarkersImpl(@NotNull Document document, boolean processBlockSelection) {
     List<CaretInfo> carets = ContainerUtil.newArrayList();
-    TextRange blockSelection = null;
     String fileText = document.getText();
 
     RangeMarker blockSelectionStartMarker = null;
@@ -354,6 +355,7 @@ public class EditorTestUtil {
     if (carets.isEmpty()) {
       carets.add(new CaretInfo(null, null));
     }
+    TextRange blockSelection = null;
     if (blockSelectionStartMarker != null) {
       blockSelection = new TextRange(blockSelectionStartMarker.getStartOffset(), blockSelectionEndMarker.getStartOffset());
     }
index 72c0f7a4e44cffdd42d10e8379cc8696b608c591..f336446a5be515f724cf8b734961a8d70db0abdb 100644 (file)
@@ -283,20 +283,20 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
   /**
    * Validates that content of the editor as well as caret and selection matches one specified in data file that
    * should be formed with the same format as one used in configureByFile
-   * @param filePath - relative path from %IDEA_INSTALLATION_HOME%/testData/
+   * @param expectedFilePath - relative path from %IDEA_INSTALLATION_HOME%/testData/
    */
-  protected void checkResultByFile(@TestDataFile @NonNls @NotNull String filePath) {
-    checkResultByFile(null, filePath, false);
+  protected void checkResultByFile(@TestDataFile @NonNls @NotNull String expectedFilePath) {
+    checkResultByFile(null, expectedFilePath, false);
   }
 
   /**
    * Validates that content of the editor as well as caret and selection matches one specified in data file that
    * should be formed with the same format as one used in configureByFile
    * @param message - this check specific message. Added to text, caret position, selection checking. May be null
-   * @param filePath - relative path from %IDEA_INSTALLATION_HOME%/testData/
+   * @param expectedFilePath - relative path from %IDEA_INSTALLATION_HOME%/testData/
    * @param ignoreTrailingSpaces - whether trailing spaces in editor in data file should be stripped prior to comparing.
    */
-  protected void checkResultByFile(@Nullable String message, @TestDataFile @NotNull String filePath, final boolean ignoreTrailingSpaces) {
+  protected void checkResultByFile(@Nullable String message, @TestDataFile @NotNull String expectedFilePath, final boolean ignoreTrailingSpaces) {
     bringRealEditorBack();
 
     getProject().getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
@@ -308,26 +308,27 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
 
     PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
 
-    String fullPath = getTestDataPath() + filePath;
+    String fullPath = getTestDataPath() + expectedFilePath;
 
     File ioFile = new File(fullPath);
 
     assertTrue(getMessage("Cannot find file " + fullPath, message), ioFile.exists());
-    String fileText = null;
+    String fileText;
     try {
       fileText = FileUtil.loadFile(ioFile, CharsetToolkit.UTF8_CHARSET);
     }
     catch (IOException e) {
       LOG.error(e);
+      throw new RuntimeException(e);
     }
-    checkResultByText(message, StringUtil.convertLineSeparators(fileText), ignoreTrailingSpaces, getTestDataPath() + "/" + filePath);
+    checkResultByText(message, StringUtil.convertLineSeparators(fileText), ignoreTrailingSpaces, getTestDataPath() + "/" + expectedFilePath);
   }
 
   /**
    * Same as checkResultByFile but text is provided directly.
    */
-  protected void checkResultByText(@NonNls @NotNull String fileText) {
-    checkResultByText(null, fileText, false, null);
+  protected void checkResultByText(@NonNls @NotNull String expectedFileText) {
+    checkResultByText(null, expectedFileText, false, null);
   }
 
   /**
@@ -335,8 +336,8 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
    * @param message - this check specific message. Added to text, caret position, selection checking. May be null
    * @param ignoreTrailingSpaces - whether trailing spaces in editor in data file should be stripped prior to comparing.
    */
-  protected void checkResultByText(final String message, @NotNull String fileText, final boolean ignoreTrailingSpaces) {
-    checkResultByText(message, fileText, ignoreTrailingSpaces, null);
+  protected void checkResultByText(final String message, @NotNull String expectedFileText, final boolean ignoreTrailingSpaces) {
+    checkResultByText(message, expectedFileText, ignoreTrailingSpaces, null);
   }
 
   /**
@@ -344,11 +345,11 @@ public abstract class LightPlatformCodeInsightTestCase extends LightPlatformTest
    * @param message - this check specific message. Added to text, caret position, selection checking. May be null
    * @param ignoreTrailingSpaces - whether trailing spaces in editor in data file should be stripped prior to comparing.
    */
-  protected void checkResultByText(final String message, @NotNull final String fileText, final boolean ignoreTrailingSpaces, final String filePath) {
+  protected void checkResultByText(final String message, @NotNull String expectedFileText, final boolean ignoreTrailingSpaces, final String filePath) {
     bringRealEditorBack();
     PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
     ApplicationManager.getApplication().runWriteAction(() -> {
-      final Document document = EditorFactory.getInstance().createDocument(fileText);
+      final Document document = EditorFactory.getInstance().createDocument(expectedFileText);
 
       if (ignoreTrailingSpaces) {
         ((DocumentImpl)document).stripTrailingSpaces(getProject());
index acfb53e089eca88705999bd091dfcb825a999018..2ea743b42b627237713d3637fcb623f7d96b9bcd 100644 (file)
@@ -1821,6 +1821,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
 
   private static class SelectionAndCaretMarkupLoader {
     private final String filePath;
+    @NotNull
     private final String newFileText;
     private final EditorTestUtil.CaretAndSelectionState caretState;
 
index e3cfceb31e3565dbb304e7523c06e6f04ffbf667..e051f77ed66faf312c29262bbaa85ce8b1ba7338 100644 (file)
@@ -218,11 +218,8 @@ public class TextRange implements Segment, Serializable {
   }
 
   public static void assertProperRange(int startOffset, int endOffset, @NotNull Object message) {
-    if (startOffset > endOffset) {
+    if (startOffset > endOffset || startOffset < 0) {
       LOG.error("Invalid range specified: (" + startOffset + "," + endOffset + "); " + message);
     }
-    if (startOffset < 0) {
-      LOG.error("Negative start offset: (" + startOffset + "," + endOffset + "); " + message);
-    }
   }
 }
index 319191e523dd645aef0bc86a3691f950f3098aa4..83b31097be7f07ef4827ed763c0b8ff2975f44ac 100644 (file)
@@ -25,6 +25,8 @@ import java.io.*;
 import java.nio.charset.Charset;
 
 public class StreamUtil {
+  private static final Logger LOG = Logger.getInstance(StreamUtil.class);
+
   private StreamUtil() {
   }
 
@@ -34,9 +36,8 @@ public class StreamUtil {
    * @param inputStream source stream
    * @param outputStream destination stream
    * @return bytes copied
-   * @throws IOException
    */
-  public static int copyStreamContent(InputStream inputStream, OutputStream outputStream) throws IOException {
+  public static int copyStreamContent(@NotNull InputStream inputStream, @NotNull OutputStream outputStream) throws IOException {
     final byte[] buffer = new byte[10 * 1024];
     int count;
     int total = 0;
@@ -47,7 +48,8 @@ public class StreamUtil {
     return total;
   }
 
-  public static byte[] loadFromStream(InputStream inputStream) throws IOException {
+  @NotNull
+  public static byte[] loadFromStream(@NotNull InputStream inputStream) throws IOException {
     final UnsyncByteArrayOutputStream outputStream = new UnsyncByteArrayOutputStream();
     try {
       copyStreamContent(inputStream, outputStream);
@@ -61,31 +63,37 @@ public class StreamUtil {
   /**
    * @deprecated depends on the default encoding, use StreamUtil#readText(java.io.InputStream, String) instead
    */
-  public static String readText(InputStream inputStream) throws IOException {
+  @NotNull
+  public static String readText(@NotNull InputStream inputStream) throws IOException {
     final byte[] data = loadFromStream(inputStream);
     return new String(data);
   }
 
-  public static String readText(InputStream inputStream, @NotNull String encoding) throws IOException {
+  @NotNull
+  public static String readText(@NotNull InputStream inputStream, @NotNull String encoding) throws IOException {
     final byte[] data = loadFromStream(inputStream);
     return new String(data, encoding);
   }
-  public static String readText(InputStream inputStream, @NotNull Charset encoding) throws IOException {
+  @NotNull
+  public static String readText(@NotNull InputStream inputStream, @NotNull Charset encoding) throws IOException {
     final byte[] data = loadFromStream(inputStream);
     return new String(data, encoding);
   }
 
-  public static String convertSeparators(String s) {
+  @NotNull
+  public static String convertSeparators(@NotNull String s) {
     return StringFactory.createShared(convertSeparators(s.toCharArray()));
   }
 
-  public static char[] readTextAndConvertSeparators(Reader reader) throws IOException {
+  @NotNull
+  public static char[] readTextAndConvertSeparators(@NotNull Reader reader) throws IOException {
     char[] buffer = readText(reader);
 
     return convertSeparators(buffer);
   }
 
-  private static char[] convertSeparators(char[] buffer) {
+  @NotNull
+  private static char[] convertSeparators(@NotNull char[] buffer) {
     int dst = 0;
     char prev = ' ';
     for (char c : buffer) {
@@ -113,11 +121,13 @@ public class StreamUtil {
     return result;
   }
 
-  public static String readTextFrom(Reader reader) throws IOException {
+  @NotNull
+  public static String readTextFrom(@NotNull Reader reader) throws IOException {
     return StringFactory.createShared(readText(reader));
   }
 
-  private static char[] readText(Reader reader) throws IOException {
+  @NotNull
+  private static char[] readText(@NotNull Reader reader) throws IOException {
     CharArrayWriter writer = new CharArrayWriter();
 
     char[] buffer = new char[2048];
@@ -140,7 +150,4 @@ public class StreamUtil {
       }
     }
   }
-
-  private static final Logger LOG = Logger.getInstance(StreamUtil.class);
-
 }
index 20ab5bfd86dbf148a104ea495f68b970b15fcbd8..06070fa8d4021a7546576045c301dac3f54a34ce 100644 (file)
  */
 package com.intellij.util;
 
-import gnu.trove.TIntArrayList;
+import com.intellij.util.containers.UnsignedShortArrayList;
 import org.jetbrains.annotations.NotNull;
 
+import java.awt.*;
+
 public class PausesStat {
-  private static final int N_MAX = 200000;
-  // stores pairs of (timestamp of the event start), (timestamp of the event end). Timestamps are stored as diffs between System.currentTimeMillis() and epochStart.
-  private final TIntArrayList pauses = new TIntArrayList();
-  private final long epochStart;
+  private static final int N_MAX = 100000;
+  // stores durations of the event: (timestamp of the event end) - (timestamp of the event start) in milliseconds.
+  private final UnsignedShortArrayList durations = new UnsignedShortArrayList();
   @NotNull private final String myName;
-  private volatile boolean started;
+  private final Thread myEdtThread;
+  private boolean started;
+  private long startTimeStamp;
   private int maxDuration;
   private Object maxDurationDescription;
   private int totalNumberRecorded;
@@ -32,50 +35,53 @@ public class PausesStat {
 
   public PausesStat(@NotNull String name) {
     myName = name;
-    epochStart = System.currentTimeMillis();
+    assert EventQueue.isDispatchThread() : Thread.currentThread();
+    myEdtThread = Thread.currentThread();
   }
 
-  private int register() {
-    int stamp = (int)(System.currentTimeMillis() - epochStart);
-    if (pauses.size()/2 == N_MAX) {
-      pauses.set(indexToOverwrite, stamp);
+  private int register(int duration) {
+    if (durations.size() == N_MAX) {
+      durations.set(indexToOverwrite, duration);
       indexToOverwrite = (indexToOverwrite + 1) % N_MAX;
     }
     else {
-      pauses.add(stamp);
+      durations.add(duration);
     }
-    return stamp;
+    return duration;
   }
 
   public void started() {
+    assertEdt();
     assert !started;
-    register();
     started = true;
+    startTimeStamp = System.currentTimeMillis();
+  }
+
+  private void assertEdt() {
+    assert Thread.currentThread() == myEdtThread : Thread.currentThread();
   }
 
   public void finished(@NotNull String description) {
+    assertEdt();
     assert started;
-    int startStamp = pauses.get(pauses.size()/2 == N_MAX ? indexToOverwrite-1 : pauses.size() - 1);
-    int finishStamp = register();
-    int duration = finishStamp - startStamp;
+    long finishStamp = System.currentTimeMillis();
+    int duration = (int)(finishStamp - startTimeStamp);
     started = false;
+    duration = Math.min(duration, (1 << 16) - 1);
     if (duration > maxDuration) {
       maxDuration = duration;
       maxDurationDescription = description;
     }
     totalNumberRecorded++;
+    register(duration);
   }
 
   public String statistics() {
+    int number = durations.size();
+    int[] duration = durations.toArray();
     int total = 0;
-    int number = pauses.size() / 2;
-    int[] duration = new int[number];
-    for (int i = 0; i < number*2; i+=2) {
-      int start = pauses.get(i);
-      int finish = pauses.get(i+1);
-      int thisDuration = finish - start;
-      total += thisDuration;
-      duration[i / 2] = thisDuration;
+    for (int d : duration) {
+      total += d;
     }
 
     return myName + " Statistics" + (totalNumberRecorded == number ? "" : " ("+totalNumberRecorded+" events was recorded in total, but only last "+number+" are reported here)")+":"+
@@ -83,6 +89,6 @@ public class PausesStat {
            "\nTotal time spent: " + total + "ms" +
            "\nAverage duration: " + (number == 0 ? 0 : total / number) + "ms" +
            "\nMedian  duration: " + ArrayUtil.averageAmongMedians(duration, 3) + "ms" +
-           "\nMax  duration:    " + maxDuration + "ms (it was '"+maxDurationDescription+"')";
+           "\nMax  duration:    " + (maxDuration == 65535 ? ">" : "") + maxDuration+ "ms (it was '"+maxDurationDescription+"')";
   }
 }
diff --git a/platform/util/src/com/intellij/util/containers/UnsignedShortArrayList.java b/platform/util/src/com/intellij/util/containers/UnsignedShortArrayList.java
new file mode 100644 (file)
index 0000000..df67fb8
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2000-2016 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.containers;
+
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+
+public class UnsignedShortArrayList implements Cloneable {
+  private char[] myData; // use char as an unsigned short
+  private int mySize;
+
+  public UnsignedShortArrayList(int initialCapacity) {
+    myData = new char[initialCapacity];
+  }
+
+  public UnsignedShortArrayList() {
+    this(10);
+  }
+
+  public void trimToSize() {
+    if (mySize < myData.length){
+      myData = ArrayUtil.realloc(myData, mySize);
+    }
+  }
+
+  public void ensureCapacity(int minCapacity) {
+    int oldCapacity = myData.length;
+    if (minCapacity > oldCapacity){
+      char[] oldData = myData;
+      int newCapacity = oldCapacity * 3 / 2 + 1;
+      if (newCapacity < minCapacity){
+        newCapacity = minCapacity;
+      }
+      myData = new char[newCapacity];
+      System.arraycopy(oldData, 0, myData, 0, mySize);
+    }
+  }
+
+  public void fill(int fromIndex, int toIndex, int value) {
+    assertShort(value);
+    if (toIndex > mySize) {
+      ensureCapacity(toIndex);
+      mySize = toIndex;
+    }
+    Arrays.fill(myData, fromIndex, toIndex, (char)value);
+  }
+
+  public int size() {
+    return mySize;
+  }
+
+  public boolean isEmpty() {
+    return mySize == 0;
+  }
+
+  public boolean contains(int element) {
+    assertShort(element);
+    return indexOf(element) >= 0;
+  }
+
+  public int indexOf(int element) {
+    assertShort(element);
+    return indexOf(element, 0, mySize);
+  }
+
+  public int indexOf(int element, int startIndex, int endIndex) {
+    assertShort(element);
+
+    if (startIndex < 0 || endIndex < startIndex || endIndex > mySize) {
+      throw new IndexOutOfBoundsException("startIndex: "+startIndex+"; endIndex: "+endIndex+"; mySize: "+mySize);
+    }
+    for(int i = startIndex; i < endIndex; i++){
+      if (element == myData[i]) return i;
+    }
+    return -1;
+  }
+
+  public int lastIndexOf(int element) {
+    assertShort(element);
+    for(int i = mySize - 1; i >= 0; i--){
+      if (element == myData[i]) return i;
+    }
+    return -1;
+  }
+
+  @Override
+  public Object clone() {
+    try{
+      UnsignedShortArrayList v = (UnsignedShortArrayList)super.clone();
+      v.myData = myData.clone();
+      return v;
+    }
+    catch(CloneNotSupportedException e){
+      // this shouldn't happen, since we are Cloneable
+      throw new InternalError();
+    }
+  }
+
+  @NotNull
+  public int[] toArray() {
+    return toArray(0,mySize);
+  }
+
+  @NotNull
+  public int[] toArray(@NotNull int[] a) {
+    if (a.length < mySize){
+      a = new int[mySize];
+    }
+    for (int i = 0; i < mySize; i++) {
+      char c = myData[i];
+      a[i] = c;
+    }
+
+    return a;
+  }
+
+  @NotNull
+  public int[] toArray(int startIndex, int length) {
+    int[] result = new int[length];
+    for (int i = startIndex; i < length; i++) {
+      char c = myData[i];
+      result[i-startIndex] = c;
+    }
+    return result;
+  }
+
+  public int get(int index) {
+    checkRange(index);
+    return myData[index];
+  }
+
+  public int getQuick(int index) {
+    return myData[index];
+  }
+
+  public int set(int index, int element) {
+    checkRange(index);
+
+    int oldValue = myData[index];
+    setQuick(index, element);
+    return oldValue;
+  }
+  public void setQuick(int index, int element) {
+    assertShort(element);
+
+    myData[index] = (char)element;
+  }
+
+  private static void assertShort(int element) {
+    assert element >= 0 && element < 1<<16 : element;
+  }
+
+  public void add(int element) {
+    ensureCapacity(mySize + 1);
+    setQuick(mySize++, element);
+  }
+
+  public void add(int index, int element) {
+    if (index > mySize || index < 0){
+      throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + mySize);
+    }
+
+    ensureCapacity(mySize + 1);
+    System.arraycopy(myData, index, myData, index + 1, mySize - index);
+    setQuick(index, element);
+    mySize++;
+  }
+
+  public int remove(int index) {
+    checkRange(index);
+
+    int oldValue = myData[index];
+
+    int numMoved = mySize - index - 1;
+    if (numMoved > 0){
+      System.arraycopy(myData, index + 1, myData, index,numMoved);
+    }
+    mySize--;
+
+    return oldValue;
+  }
+
+  public void clear() {
+    mySize = 0;
+  }
+
+  public void removeRange(int fromIndex, int toIndex) {
+    int numMoved = mySize - toIndex;
+    System.arraycopy(myData, toIndex, myData, fromIndex, numMoved);
+    mySize -= toIndex - fromIndex;
+  }
+
+  public void copyRange(int fromIndex, int length, int toIndex) {
+    if (length < 0 || fromIndex < 0 || fromIndex + length > mySize || toIndex < 0 || toIndex + length > mySize) {
+      throw new IndexOutOfBoundsException("fromIndex: "+fromIndex+"; length: "+length+"; toIndex: "+toIndex+"; mySize: "+mySize);
+    }
+    System.arraycopy(myData, fromIndex, myData, toIndex, length);
+  }
+
+  private void checkRange(int index) {
+    if (index >= mySize || index < 0){
+      //noinspection HardCodedStringLiteral
+      throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + mySize);
+    }
+  }
+
+  @Override
+  public String toString() {
+    return Arrays.toString(toArray());
+  }
+}
index 096de12833a247840bd67114e41167eb3fe50958..c7a3a3f1ce81eaeebfdef670de21ab5d9111a647 100644 (file)
@@ -338,7 +338,7 @@ public class DateFormatUtil {
       }
     }
     catch (Throwable t) {
-      LOG.error(t);
+      LOG.info(t);
     }
 
     if (!loaded) {
index d59a9fc01efe6920dec19df2da5b001abdc4495c..5b3305efda8a85f231f624e0cfe6526d27bbcc31 100644 (file)
@@ -401,19 +401,9 @@ public class LineStatusTracker {
   }
 
   private class MyApplicationListener extends ApplicationAdapter {
-    private int myWriteActionDepth = 0;
-
     @Override
-    public void writeActionStarted(@NotNull Object action) {
-      myWriteActionDepth++;
-    }
-
-    @Override
-    public void writeActionFinished(@NotNull Object action) {
-      myWriteActionDepth = Math.max(myWriteActionDepth - 1, 0);
-      if (myWriteActionDepth == 0) {
-        updateRanges();
-      }
+    public void afterWriteActionFinished(@NotNull Object action) {
+      updateRanges();
     }
   }
 
index 17795670efbaef8ba444b4526d9345b0d21ee38a..70faf4f786170f285bbc22b22f37d71ab8926756 100644 (file)
@@ -88,6 +88,14 @@ public class WatchesRootNode extends XValueContainerNode<XValueContainer> {
     return ContainerUtil.concat(myChildren, children);
   }
 
+  /**
+   * @deprecated use {@link #getWatchChildren()} instead
+   */
+  @NotNull
+  public List<? extends WatchNode> getAllChildren() {
+    return getWatchChildren();
+  }
+
   @NotNull
   public List<? extends WatchNode> getWatchChildren() {
     return myChildren;
index 20853a87e148981b9fafcf094f21f7fdae1e5d47..ea828ce3822f831fe5cbb4bff16707255d99a70c 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.siyeh.ig.threading;
 
+import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.util.Key;
 import com.intellij.psi.*;
 import com.intellij.psi.search.SearchScope;
@@ -33,20 +34,16 @@ import java.util.Stack;
 class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
 
   private final PsiClass aClass;
-  private final Set<PsiField> m_synchronizedAccesses =
-    new HashSet<PsiField>(2);
-  private final Set<PsiField> m_unsynchronizedAccesses =
-    new HashSet<PsiField>(2);
-  private final Set<PsiMethod> methodsAlwaysSynchronized =
-    new HashSet<PsiMethod>();
-  private final Set<PsiMethod> methodsNotAlwaysSynchronized =
-    new HashSet<PsiMethod>();
-  private final Set<PsiMethod> unusedMethods = new HashSet<PsiMethod>();
-  private final Set<PsiMethod> usedMethods = new HashSet<PsiMethod>();
+  private final Set<PsiField> m_synchronizedAccesses = new HashSet<>(2);
+  private final Set<PsiField> m_unsynchronizedAccesses = new HashSet<>(2);
+  private final Set<PsiMethod> methodsAlwaysSynchronized = new HashSet<>();
+  private final Set<PsiMethod> methodsNotAlwaysSynchronized = new HashSet<>();
+  private final Set<PsiMethod> unusedMethods = new HashSet<>();
+  private final Set<PsiMethod> usedMethods = new HashSet<>();
   private boolean m_inInitializer;
   private int m_inSynchronizedContextCount;
-  private final Stack<Integer> contextStack = new Stack<Integer>();
-  private final Stack<Boolean> contextInitializerStack = new Stack<Boolean>();
+  private final Stack<Integer> contextStack = new Stack<>();
+  private final Stack<Boolean> contextInitializerStack = new Stack<>();
   private boolean privateMethodUsagesCalculated;
   private final boolean countGettersAndSetters;
 
@@ -61,7 +58,7 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
     if (!classToVisit.equals(aClass)) {
       contextStack.push(m_inSynchronizedContextCount);
       m_inSynchronizedContextCount = 0;
-      
+
       contextInitializerStack.push(m_inInitializer);
       m_inInitializer = false;
     }
@@ -72,7 +69,7 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
   public void visitLambdaExpression(PsiLambdaExpression expression) {
     contextStack.push(m_inSynchronizedContextCount);
     m_inSynchronizedContextCount = 0;
-    
+
     contextInitializerStack.push(m_inInitializer);
     m_inInitializer = false;
     super.visitLambdaExpression(expression);
@@ -144,6 +141,7 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
   }
 
   private static final Key<Boolean> CODE_BLOCK_CONTAINS_HOLDS_LOCK_CALL = Key.create("CODE_BLOCK_CONTAINS_HOLDS_LOCK_CALL");
+
   @Override
   public void visitAssertStatement(PsiAssertStatement statement) {
     final PsiExpression condition = statement.getAssertCondition();
@@ -198,18 +196,18 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
 
   private void determineUsageMap(HashMap<PsiMethod,
     Collection<PsiReference>> referenceMap) {
-    final Set<PsiMethod> remainingMethods =
-      new HashSet<PsiMethod>(usedMethods);
+    final Set<PsiMethod> remainingMethods = new HashSet<>(usedMethods);
     boolean stabilized = false;
     while (!stabilized) {
+      ProgressManager.checkCanceled();
       stabilized = true;
-      final Set<PsiMethod> methodsDeterminedThisPass =
-        new HashSet<PsiMethod>();
+      final Set<PsiMethod> methodsDeterminedThisPass = new HashSet<>();
       for (PsiMethod method : remainingMethods) {
-        final Collection<PsiReference> references =
-          referenceMap.get(method);
+        ProgressManager.checkCanceled();
+        final Collection<PsiReference> references = referenceMap.get(method);
         boolean areAllReferencesSynchronized = true;
         for (PsiReference reference : references) {
+          ProgressManager.checkCanceled();
           if (isKnownToBeUsed(reference)) {
             if (isInKnownUnsynchronizedContext(reference)) {
               methodsNotAlwaysSynchronized.add(method);
@@ -238,17 +236,18 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
   private void determineUsedMethods(
     Set<PsiMethod> privateMethods,
     HashMap<PsiMethod, Collection<PsiReference>> referenceMap) {
-    final Set<PsiMethod> remainingMethods =
-      new HashSet<PsiMethod>(privateMethods);
+    final Set<PsiMethod> remainingMethods = new HashSet<>(privateMethods);
     boolean stabilized = false;
     while (!stabilized) {
+      ProgressManager.checkCanceled();
       stabilized = true;
-      final Set<PsiMethod> methodsDeterminedThisPass =
-        new HashSet<PsiMethod>();
+      final Set<PsiMethod> methodsDeterminedThisPass = new HashSet<>();
       for (PsiMethod method : remainingMethods) {
+        ProgressManager.checkCanceled();
         final Collection<PsiReference> references =
           referenceMap.get(method);
         for (PsiReference reference : references) {
+          ProgressManager.checkCanceled();
           if (isKnownToBeUsed(reference)) {
             usedMethods.add(method);
             methodsDeterminedThisPass.add(method);
@@ -263,21 +262,21 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
 
   private static HashMap<PsiMethod, Collection<PsiReference>>
   buildReferenceMap(Set<PsiMethod> privateMethods) {
-    final HashMap<PsiMethod, Collection<PsiReference>> referenceMap =
-      new HashMap<PsiMethod, Collection<PsiReference>>();
+    final HashMap<PsiMethod, Collection<PsiReference>> referenceMap = new HashMap<>();
     for (PsiMethod method : privateMethods) {
+      ProgressManager.checkCanceled();
       final SearchScope scope = method.getUseScope();
-      final Collection<PsiReference> references =
-        ReferencesSearch.search(method, scope).findAll();
+      final Collection<PsiReference> references = ReferencesSearch.search(method, scope).findAll();
       referenceMap.put(method, references);
     }
     return referenceMap;
   }
 
   private Set<PsiMethod> findPrivateMethods() {
-    final Set<PsiMethod> privateMethods = new HashSet<PsiMethod>();
+    final Set<PsiMethod> privateMethods = new HashSet<>();
     final PsiMethod[] methods = aClass.getMethods();
     for (PsiMethod method : methods) {
+      ProgressManager.checkCanceled();
       if (method.hasModifierProperty(PsiModifier.PRIVATE)) {
         privateMethods.add(method);
       }
@@ -301,8 +300,7 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
 
   private boolean isInKnownSynchronizedContext(PsiReference reference) {
     final PsiElement element = reference.getElement();
-    if (PsiTreeUtil.getParentOfType(element,
-                                    PsiSynchronizedStatement.class) != null) {
+    if (PsiTreeUtil.getParentOfType(element, PsiSynchronizedStatement.class) != null) {
       return true;
     }
     final PsiMethod method =
@@ -321,8 +319,7 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
 
   private boolean isInKnownUnsynchronizedContext(PsiReference reference) {
     final PsiElement element = reference.getElement();
-    if (PsiTreeUtil.getParentOfType(element,
-                                    PsiSynchronizedStatement.class) != null) {
+    if (PsiTreeUtil.getParentOfType(element, PsiSynchronizedStatement.class) != null) {
       return false;
     }
     final PsiMethod method =
@@ -356,7 +353,9 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
 
   @Override
   protected void elementFinished(@NotNull PsiElement element) {
-    if (element instanceof PsiField || element instanceof PsiClassInitializer || element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
+    if (element instanceof PsiField ||
+        element instanceof PsiClassInitializer ||
+        element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
       m_inInitializer = false;
     }
     if (element instanceof PsiClass && !element.equals(aClass) || element instanceof PsiLambdaExpression) {
@@ -373,14 +372,14 @@ class VariableAccessVisitor extends JavaRecursiveElementWalkingVisitor {
       }
     }
     if (element.getUserData(CODE_BLOCK_CONTAINS_HOLDS_LOCK_CALL) != null) {
-      m_inSynchronizedContextCount --;
+      m_inSynchronizedContextCount--;
       element.putUserData(CODE_BLOCK_CONTAINS_HOLDS_LOCK_CALL, null);
     }
   }
 
   Set<PsiField> getInappropriatelyAccessedFields() {
     final Set<PsiField> out =
-      new HashSet<PsiField>(m_synchronizedAccesses);
+      new HashSet<>(m_synchronizedAccesses);
     out.retainAll(m_unsynchronizedAccesses);
     return out;
   }
index f77525642ffc6f8799229c650e2aa2ea4657d45c..017d47c2889c5cf587a02f3bb1630ec187147567 100644 (file)
@@ -316,9 +316,4 @@ public class GitRepositoryFiles {
   Collection<VirtualFile> getRootDirs() {
     return ContainerUtil.newHashSet(myMainDir, myWorktreeDir);
   }
-
-  @NotNull
-  File getBranchFile(@NotNull String fullBranchName) {
-    return file(myMainDir.getPath() + slash(fullBranchName));
-  }
 }
index 236f71e4857c8c9e383406ea846a95d79fa3ce13..d646eb7609ea06ff311a80bdb48c0fd7c217398f 100644 (file)
@@ -23,7 +23,6 @@ import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.LineTokenizer;
-import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.CharsetToolkit;
 import com.intellij.util.Function;
 import com.intellij.util.Processor;
@@ -321,14 +320,9 @@ class GitRepositoryReader {
 
   @NotNull
   private HeadInfo readHead() {
-    return readHeadInternal(myHeadFile, new ArrayList<>());
-  }
-
-  @NotNull
-  private HeadInfo readHeadInternal(@NotNull File headFile, @NotNull List<String> alreadyVisited) {
     String headContent;
     try {
-      headContent = DvcsUtil.tryLoadFile(headFile, CharsetToolkit.UTF8);
+      headContent = DvcsUtil.tryLoadFile(myHeadFile, CharsetToolkit.UTF8);
     }
     catch (RepoStateException e) {
       LOG.error(e);
@@ -337,22 +331,11 @@ class GitRepositoryReader {
 
     Hash hash = parseHash(headContent);
     if (hash != null) {
-      if (alreadyVisited.isEmpty()) {
-        return new HeadInfo(false, headContent);
-      } else {
-        return new HeadInfo(true, ContainerUtil.getLastItem(alreadyVisited));
-      }
+      return new HeadInfo(false, headContent);
     }
     String target = getTarget(headContent);
     if (target != null) {
-      if (alreadyVisited.contains(target)) {
-        alreadyVisited.add(target);
-        LOG.error(new RepoStateException("Cyclic symbolic ref in HEAD: [" + StringUtil.join(alreadyVisited, " -> ") + "]"));
-        return new HeadInfo(false, null);
-      } else {
-        alreadyVisited.add(target);
-        return readHeadInternal(myGitFiles.getBranchFile(target), alreadyVisited);
-      }
+      return new HeadInfo(true, target);
     }
     LOG.error(new RepoStateException("Invalid format of the .git/HEAD file: [" + headContent + "]")); // including "refs/tags/v1"
     return new HeadInfo(false, null);
index c9d9304358192b5fa1c3cecec224fb10a876bf71..30e2c01a2f944f438994d01a91b18fe3fdb43b4a 100644 (file)
@@ -1 +1 @@
-0e1d130689bc52f140c5c374aa9cc2b8916c0ad7 master
+0e1d130689bc52f140c5c374aa9cc2b8916c0ad7 master-link
\ No newline at end of file
index 7889be4f80976f88150a84a1a31baa4d80a72af9..5bd9ad969f7d4131bd90066902467b705c8bdf60 100644 (file)
@@ -15,9 +15,8 @@
  */
 package com.jetbrains.python.magicLiteral;
 
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.openapi.application.ReadAction;
-import com.intellij.openapi.application.Result;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiReference;
@@ -36,18 +35,15 @@ class PyMagicLiteralReferenceSearcher extends QueryExecutorBase<PsiReference, Re
 
   @Override
   public void processQuery(@NotNull final ReferencesSearch.SearchParameters queryParameters, @NotNull final Processor<PsiReference> consumer) {
-    new ReadAction() {
-      @Override
-      protected void run(@NotNull final Result result) throws Throwable {
-        final PsiElement refElement = queryParameters.getElementToSearch();
-        if (PyMagicLiteralTools.isMagicLiteral(refElement)) {
-          final String refText = ((StringLiteralExpression)refElement).getStringValue();
-          if (!StringUtil.isEmpty(refText)) {
-            final SearchScope searchScope = queryParameters.getEffectiveSearchScope();
-            queryParameters.getOptimizer().searchWord(refText, searchScope, true, refElement);
-          }
+    ApplicationManager.getApplication().runReadAction(() -> {
+      final PsiElement refElement = queryParameters.getElementToSearch();
+      if (PyMagicLiteralTools.isMagicLiteral(refElement)) {
+        final String refText = ((StringLiteralExpression)refElement).getStringValue();
+        if (!StringUtil.isEmpty(refText)) {
+          final SearchScope searchScope = queryParameters.getEffectiveSearchScope();
+          queryParameters.getOptimizer().searchWord(refText, searchScope, true, refElement);
         }
       }
-    }.execute();
+    });
   }
 }
index 1813d9d8166a9ede7dcc13d102f5c6d716b19744..22cc4d5c6aa2b391ef41dd4729408e61b0b2740b 100644 (file)
@@ -589,6 +589,8 @@ subexpression
 subexpressions
 sublicense
 sublist
+submodule
+submodules
 subpackage
 subpackages
 subpartition