Merge remote-tracking branch 'origin/master'
authorKonstantin Bulenkov <kb@jetbrains.com>
Thu, 4 Feb 2016 13:30:36 +0000 (14:30 +0100)
committerKonstantin Bulenkov <kb@jetbrains.com>
Thu, 4 Feb 2016 13:30:36 +0000 (14:30 +0100)
153 files changed:
java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java
java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java
java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java
java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java
java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java
java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/TransitiveInferenceVariableDependencies.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/daemon/impl/DaemonRespondToChangesTest.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java
java/java-tests/testSrc/com/intellij/codeInsight/template/MacroParserTest.java
java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java
java/java-tests/testSrc/com/intellij/psi/ClsPsiTest.java
java/java-tests/testSrc/com/intellij/psi/ConstantValuesTest.java
java/testFramework/src/com/intellij/execution/ExecutionTestCase.java
platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java
platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java
platform/core-impl/src/com/intellij/psi/impl/source/tree/LeafElement.java
platform/diff-impl/src/com/intellij/diff/comparison/iterables/ChangeDiffIterableBase.java
platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffChangeDiffIterable.java
platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffFragmentsDiffIterable.java
platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableBase.java
platform/diff-impl/src/com/intellij/diff/comparison/iterables/FairDiffIterableWrapper.java
platform/diff-impl/src/com/intellij/diff/comparison/iterables/InvertedDiffIterableWrapper.java
platform/diff-impl/src/com/intellij/diff/comparison/iterables/RangesDiffIterable.java
platform/diff-impl/src/com/intellij/diff/impl/DiffWindowBase.java
platform/diff-impl/src/com/intellij/diff/util/DiffLineMarkerRenderer.java
platform/diff-impl/src/com/intellij/diff/util/DiffLineSeparatorRenderer.java
platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java
platform/editor-ui-ex/src/com/intellij/injected/editor/MarkupModelWindow.java
platform/editor-ui-ex/src/com/intellij/openapi/editor/ex/MarkupModelEx.java
platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java
platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java
platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/RangeHighlighterImpl.java
platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/event/MarkupModelListener.java
platform/lang-api/src/com/intellij/codeInsight/template/ExpressionContext.java
platform/lang-impl/src/com/intellij/application/options/editor/GutterIconsConfigurable.java
platform/lang-impl/src/com/intellij/codeInsight/TargetElementUtil.java
platform/lang-impl/src/com/intellij/codeInsight/navigation/CtrlMouseHandler.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/MacroCallNode.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/MacroParser.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java
platform/lang-impl/src/com/intellij/psi/impl/source/tree/injected/MultiHostRegistrarImpl.java
platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java
platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java
platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/FragmentBoundRenderer.java
platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorGutterComponentEx.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFactoryImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorFilteringMarkupModelEx.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/view/IterationState.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/view/LineLayout.java
platform/platform-impl/src/com/intellij/openapi/editor/markup/LineMarkerRendererEx.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/text/TextEditorComponent.java
platform/platform-impl/src/com/intellij/openapi/ui/FrameWrapper.java
platform/platform-impl/src/com/intellij/openapi/ui/WindowWrapperBuilder.java
platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java
platform/platform-resources/src/checkedPlugins.txt
platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java
platform/projectModel-impl/src/com/intellij/openapi/roots/impl/TestModulePropertiesImpl.java
platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/RemoteServersViewContribution.java
platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java
platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeNodeSelector.java [new file with mode: 0644]
platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java
platform/util/src/com/intellij/openapi/util/TraceableDisposable.java
platform/util/src/com/intellij/ui/CaptionPanel.java
platform/vcs-api/src/com/intellij/openapi/vcs/changes/EnsureUpToDateFromNonAWTThread.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsConfirmationDialog.java
platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDataPack.java
platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogHighlighter.java
platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUi.java
platform/vcs-log/impl/src/META-INF/vcs-log.xml
platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUiProperties.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePack.java
platform/vcs-log/impl/src/com/intellij/vcs/log/data/VisiblePackBuilder.java
platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CurrentBranchHighlighter.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/MergeCommitsHighlighter.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/MyCommitsHighlighter.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogHighlighterFactory.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseGraphAction.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseOrExpandGraphAction.java [new file with mode: 0644]
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/ExpandGraphAction.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/GraphAction.java [deleted file]
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/HighlightersActionGroup.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/ShowLongEdgesAction.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/MainFrame.java
platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OptionalUsedAsFieldOrParameterTypeInspection.java [new file with mode: 0644]
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/assignment/AssignmentToNullInspection.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ReturnNullInspectionBase.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/TypeUtils.java
plugins/InspectionGadgets/src/inspectionDescriptions/OptionalUsedAsFieldOrParameterType.html [new file with mode: 0644]
plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/assignment_to_null/AssignmentToNull.java [moved from plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/AssignmentToNullInspection.java with 55% similarity]
plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/return_null/WarnOptional.java
plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OptionalUsedAsFieldOrParameterTypeInspectionTest.java [new file with mode: 0644]
plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToNullInspectionTest.java [new file with mode: 0644]
plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ReturnNullInspectionTest.java
plugins/git4idea/src/META-INF/plugin.xml
plugins/git4idea/src/git4idea/branch/DeepComparator.java
plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcActionGroup.java
plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcFramework.java
plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/util/MvcTargetDialogCompletionUtils.java
plugins/properties/src/com/intellij/lang/properties/editor/ResourceBundlePropertiesUpdateManager.java
python/educational-core/student/resources/META-INF/plugin.xml
python/educational-core/student/resources/code-mirror/clike.js [new file with mode: 0644]
python/educational-core/student/resources/code-mirror/codemirror-old.css [new file with mode: 0644]
python/educational-core/student/resources/code-mirror/codemirror.css [new file with mode: 0644]
python/educational-core/student/resources/code-mirror/codemirror.js [new file with mode: 0644]
python/educational-core/student/resources/code-mirror/colorize.js [new file with mode: 0644]
python/educational-core/student/resources/code-mirror/javascript.js [new file with mode: 0644]
python/educational-core/student/resources/code-mirror/python.js [new file with mode: 0644]
python/educational-core/student/resources/code-mirror/runmode.js [new file with mode: 0644]
python/educational-core/student/resources/code-mirror/template.html [new file with mode: 0644]
python/educational-core/student/resources/style/javaFXBrowserDarcula.css [new file with mode: 0644]
python/educational-core/student/resources/style/javaFXBrowserDarculaScrollBar.css [new file with mode: 0644]
python/educational-core/student/resources/style/javaFXBrowserScrollBar.css [new file with mode: 0644]
python/educational-core/student/src/com/jetbrains/edu/learning/StudyProjectComponent.java
python/educational-core/student/src/com/jetbrains/edu/learning/StudyToolWindowConfigurator.java [new file with mode: 0644]
python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java
python/educational-core/student/src/com/jetbrains/edu/learning/actions/StudyCheckAction.java
python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java
python/educational-core/student/src/com/jetbrains/edu/learning/projectView/StudyTreeStructureProvider.java
python/educational-core/student/src/com/jetbrains/edu/learning/run/StudyExecutor.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyBrowserWindow.java [new file with mode: 0644]
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyNewProjectPanel.java
python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudyToolWindow.java
python/educational-core/student/student.iml
python/educational-python/student-python/resources/META-INF/plugin.xml
python/educational-python/student-python/src/com/jetbrains/edu/learning/PyStudyExecutor.java
python/educational-python/student-python/src/com/jetbrains/edu/learning/PyStudyToolWindowConfigurator.java [new file with mode: 0644]
python/educational-python/student-python/student-python.iml
python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java
python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java
python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java
python/testData/inspections/PyUnresolvedReferencesInspection/slots.py [deleted file]
python/testData/inspections/PyUnresolvedReferencesInspection/slotsAndListedAttrAccess.py [new file with mode: 0644]
python/testData/inspections/PyUnresolvedReferencesInspection/slotsAndUnlistedAttrAssign.py [new file with mode: 0644]
python/testData/inspections/PyUnresolvedReferencesInspection/slotsSuperclass.py [new file with mode: 0644]
python/testData/inspections/PyUnresolvedReferencesInspection/slotsWithDict.py [new file with mode: 0644]
python/testSrc/com/jetbrains/python/PythonKeywordCompletionTest.java
python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java

index 05ad77baf475e5af37e0af9851c4633ac4f37866..9d120d9825777a91725513962c431d4d5b9b1732 100644 (file)
@@ -237,7 +237,7 @@ public class BuildManager implements Disposable {
             final Pair<Date, File> usageData = readUsageFile(usageFile);
             if (usageData != null) {
               final File projectFile = usageData.second;
-              if ((projectFile != null && !projectFile.exists()) || DateFormatUtil.getDifferenceInDays(usageData.first, now) > unusedThresholdDays) {
+              if (projectFile != null && !projectFile.exists() || DateFormatUtil.getDifferenceInDays(usageData.first, now) > unusedThresholdDays) {
                 LOG.info("Clearing project build data because the project does not exist or was not opened for more than " + unusedThresholdDays + " days: " + buildDataProjectDir.getPath());
                 FileUtil.delete(buildDataProjectDir);
               }
@@ -324,6 +324,7 @@ public class BuildManager implements Disposable {
     });
 
     conn.subscribe(BatchFileChangeListener.TOPIC, new BatchFileChangeListener.Adapter() {
+      @Override
       public void batchChangeStarted(Project project) {
         cancelAutoMakeTasks(project);
       }
@@ -343,12 +344,8 @@ public class BuildManager implements Disposable {
       }
     });
 
-    JobScheduler.getScheduler().scheduleWithFixedDelay(new Runnable() {
-      @Override
-      public void run() {
-        runCommand(myGCTask);
-      }
-    }, 3, 180, TimeUnit.MINUTES);
+    ScheduledFuture<?> future = JobScheduler.getScheduler().scheduleWithFixedDelay((Runnable)() -> runCommand(myGCTask), 3, 180, TimeUnit.MINUTES);
+    Disposer.register(this, () -> future.cancel(false));
   }
 
   private List<Project> getOpenProjects() {
@@ -775,6 +772,7 @@ public class BuildManager implements Disposable {
                     // For ordinary make all project, app settings and unsaved docs are always saved before build starts.
                     try {
                       SwingUtilities.invokeAndWait(new Runnable() {
+                        @Override
                         public void run() {
                           project.save();
                         }
@@ -828,6 +826,7 @@ public class BuildManager implements Disposable {
 
                 if (isProcessPreloadingEnabled(project)) {
                   runCommand(new Runnable() {
+                    @Override
                     public void run() {
                       if (!myPreloadedBuilds.containsKey(projectPath)) {
                         try {
@@ -922,10 +921,6 @@ public class BuildManager implements Disposable {
 
   @NotNull
   public static Pair<Sdk, JavaSdkVersion> getBuildProcessRuntimeSdk(Project project) {
-    Sdk projectJdk = null;
-    int sdkMinorVersion = 0;
-    JavaSdkVersion sdkVersion = null;
-
     final Set<Sdk> candidates = new LinkedHashSet<Sdk>();
     final Sdk defaultSdk = ProjectRootManager.getInstance(project).getProjectSdk();
     if (defaultSdk != null && defaultSdk.getSdkType() instanceof JavaSdkType) {
@@ -941,6 +936,9 @@ public class BuildManager implements Disposable {
 
     // now select the latest version from the sdks that are used in the project, but not older than the internal sdk version
     final JavaSdk javaSdkType = JavaSdk.getInstance();
+    Sdk projectJdk = null;
+    int sdkMinorVersion = 0;
+    JavaSdkVersion sdkVersion = null;
     for (Sdk candidate : candidates) {
       final String vs = candidate.getVersionString();
       if (vs != null) {
@@ -954,7 +952,7 @@ public class BuildManager implements Disposable {
           }
           else {
             final int result = candidateVersion.compareTo(sdkVersion);
-            if (result > 0 || (result == 0 && candidateMinorVersion > sdkMinorVersion)) {
+            if (result > 0 || result == 0 && candidateMinorVersion > sdkMinorVersion) {
               sdkVersion = candidateVersion;
               sdkMinorVersion = candidateMinorVersion;
               projectJdk = candidate;
@@ -977,6 +975,7 @@ public class BuildManager implements Disposable {
 
     // launching build process from projectTaskQueue ensures that no other build process for this project is currently running
     return projectTaskQueue.submit(new Callable<Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler>>() {
+      @Override
       public Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> call() throws Exception {
         if (project.isDisposed()) {
           return null;
@@ -1324,7 +1323,7 @@ public class BuildManager implements Disposable {
     final ServerBootstrap bootstrap = NettyKt.serverBootstrap(new NioEventLoopGroup(1, ConcurrencyUtil.newNamedThreadFactory("External compiler")));
     bootstrap.childHandler(new ChannelInitializer() {
       @Override
-      protected void initChannel(Channel channel) throws Exception {
+      protected void initChannel(@NotNull Channel channel) throws Exception {
         channel.pipeline().addLast(myChannelRegistrar,
                                    new ProtobufVarint32FrameDecoder(),
                                    new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
@@ -1360,7 +1359,7 @@ public class BuildManager implements Disposable {
     }
   }
 
-  private static abstract class BuildManagerPeriodicTask implements Runnable {
+  private abstract static class BuildManagerPeriodicTask implements Runnable {
     private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
     private final AtomicBoolean myInProgress = new AtomicBoolean(false);
     private final Runnable myTaskRunnable = new Runnable() {
@@ -1409,7 +1408,7 @@ public class BuildManager implements Disposable {
   private static class NotifyingMessageHandler extends DelegatingMessageHandler {
     private final Project myProject;
     private final BuilderMessageHandler myDelegateHandler;
-    private boolean myIsAutomake;
+    private final boolean myIsAutomake;
 
     public NotifyingMessageHandler(@NotNull Project project, @NotNull BuilderMessageHandler delegateHandler, final boolean isAutomake) {
       myProject = project;
@@ -1452,7 +1451,7 @@ public class BuildManager implements Disposable {
 
   private static final class StdOutputCollector extends ProcessAdapter {
     private final Appendable myOutput;
-    private int myStoredLength = 0;
+    private int myStoredLength;
     public StdOutputCollector(Appendable outputSink) {
       myOutput = outputSink;
     }
@@ -1557,6 +1556,7 @@ public class BuildManager implements Disposable {
                 final LocalFileSystem lfs = LocalFileSystem.getInstance();
                 final Set<VirtualFile> filesToRefresh = new HashSet<VirtualFile>();
                 ApplicationManager.getApplication().runReadAction(new Runnable() {
+                  @Override
                   public void run() {
                     if (project.isDisposed()) {
                       return;
@@ -1639,7 +1639,7 @@ public class BuildManager implements Disposable {
     final SequentialTaskExecutor taskQueue;
     private final Set<InternedPath> myChanged = new THashSet<InternedPath>();
     private final Set<InternedPath> myDeleted = new THashSet<InternedPath>();
-    private long myNextEventOrdinal = 0L;
+    private long myNextEventOrdinal;
     private boolean myNeedRescan = true;
 
     private ProjectData(@NotNull SequentialTaskExecutor taskQueue) {
@@ -1698,7 +1698,7 @@ public class BuildManager implements Disposable {
     }
   }
 
-  private static abstract class InternedPath {
+  private abstract static class InternedPath {
     protected final int[] myPath;
 
     /**
@@ -1783,7 +1783,7 @@ public class BuildManager implements Disposable {
   private static final class DelegateFuture<T> implements TaskFuture<T> {
     @Nullable
     private TaskFuture<? extends T> myDelegate;
-    private Boolean myRequestedCancelState = null;
+    private Boolean myRequestedCancelState;
 
     @NotNull
     public synchronized TaskFuture<? extends T> getDelegate() {
@@ -1815,6 +1815,7 @@ public class BuildManager implements Disposable {
       return false;
     }
 
+    @Override
     public synchronized boolean cancel(boolean mayInterruptIfRunning) {
       final TaskFuture<? extends T> delegate = myDelegate;
       if (delegate == null) {
@@ -1824,14 +1825,17 @@ public class BuildManager implements Disposable {
       return delegate.cancel(mayInterruptIfRunning);
     }
 
+    @Override
     public void waitFor() {
       getDelegate().waitFor();
     }
 
+    @Override
     public boolean waitFor(long timeout, TimeUnit unit) {
       return getDelegate().waitFor(timeout, unit);
     }
 
+    @Override
     public boolean isCancelled() {
       final TaskFuture<? extends T> delegate;
       synchronized (this) {
@@ -1843,6 +1847,7 @@ public class BuildManager implements Disposable {
       return delegate.isCancelled();
     }
 
+    @Override
     public boolean isDone() {
       final TaskFuture<? extends T> delegate;
       synchronized (this) {
@@ -1854,11 +1859,13 @@ public class BuildManager implements Disposable {
       return delegate.isDone();
     }
 
+    @Override
     public T get() throws InterruptedException, java.util.concurrent.ExecutionException {
       return getDelegate().get();
     }
 
-    public T get(long timeout, TimeUnit unit) throws InterruptedException, java.util.concurrent.ExecutionException, TimeoutException {
+    @Override
+    public T get(long timeout, @NotNull TimeUnit unit) throws InterruptedException, java.util.concurrent.ExecutionException, TimeoutException {
       return getDelegate().get(timeout, unit);
     }
   }
index 4dc1e315913f8202226f2d1b260948c41ccbe999..46cd638666c510704ec929e8a1d4080b6d7c7517 100644 (file)
@@ -256,7 +256,7 @@ public abstract class DebuggerEditorImpl extends CompletionEditor {
     myCurrentDocument = PsiDocumentManager.getInstance(getProject()).getDocument(codeFragment);
 
     if (myCurrentDocument != null) {
-      PsiDocumentManagerBase.cachePsi(myCurrentDocument, codeFragment);
+      ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(getProject())).cachePsi(myCurrentDocument, codeFragment);
       for (DocumentListener documentListener : myDocumentListeners) {
         myCurrentDocument.addDocumentListener(documentListener);
       }
index 1275cf8d5af81d610fdfc2ad80a67755ba8246c7..96b38a73ed650cde50bc79f3b233696246d80b98 100644 (file)
@@ -26,6 +26,8 @@ import com.intellij.execution.junit2.info.MethodLocation;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.editor.Caret;
+import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Comparing;
@@ -35,6 +37,7 @@ import com.intellij.psi.*;
 import com.intellij.psi.search.PsiElementProcessor;
 import com.intellij.psi.util.ClassUtil;
 import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.containers.ContainerUtil;
 
 import java.util.ArrayList;
 import java.util.LinkedHashSet;
@@ -157,13 +160,25 @@ public abstract class AbstractPatternBasedConfigurationProducer<T extends Module
                                          PsiElementProcessor.CollectElements<PsiElement> processor) {
     PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
     if (elements != null) {
-      collectTestMembers(elements, checkAbstract, checkIsTest, processor);
-      for (PsiElement psiClass : processor.getCollection()) {
-        classes.add(getQName(psiClass));
-      }
-      return true;
+      return collectTestMembers(elements, checkAbstract, checkIsTest, processor, classes);
     }
     else {
+      final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
+      if (editor != null) {
+        final List<Caret> allCarets = editor.getCaretModel().getAllCarets();
+        if (allCarets.size() > 1) {
+          final PsiFile editorFile = CommonDataKeys.PSI_FILE.getData(dataContext);
+          if (editorFile != null) {
+            final Set<PsiMethod> methods = new LinkedHashSet<PsiMethod>();
+            for (Caret caret : allCarets) {
+              ContainerUtil.addIfNotNull(methods, PsiTreeUtil.getParentOfType(editorFile.findElementAt(caret.getOffset()), PsiMethod.class));
+            }
+            if (!methods.isEmpty()) {
+              return collectTestMembers(methods.toArray(new PsiElement[0]), checkAbstract, checkIsTest, processor, classes);
+            }
+          }
+        }
+      }
       final PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
       final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
       if (files != null) {
@@ -195,6 +210,17 @@ public abstract class AbstractPatternBasedConfigurationProducer<T extends Module
     return false;
   }
 
+  private boolean collectTestMembers(PsiElement[] elements,
+                                     boolean checkAbstract,
+                                     boolean checkIsTest,
+                                     PsiElementProcessor.CollectElements<PsiElement> processor, LinkedHashSet<String> classes) {
+    collectTestMembers(elements, checkAbstract, checkIsTest, processor);
+    for (PsiElement psiClass : processor.getCollection()) {
+      classes.add(getQName(psiClass));
+    }
+    return true;
+  }
+
   private static PsiElement[] collectLocationElements(LinkedHashSet<String> classes, DataContext dataContext) {
     final Location<?>[] locations = Location.DATA_KEYS.getData(dataContext);
     if (locations != null) {
index d47bff7ffcb77ccf6d8cca1f0b7a549c2f6a410e..c9b6dd4b01851e18e7eebe9174c4cf4adf822e9d 100644 (file)
@@ -271,13 +271,12 @@ public class JavaCompletionUtil {
             final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)declarationScope;
             final int parameterIndex = lambdaExpression.getParameterList().getParameterIndex((PsiParameter)resolve);
             final Set<LookupElement> set = new LinkedHashSet<LookupElement>();
-            final boolean overloadsFound = LambdaUtil.processParentOverloads(lambdaExpression, new Consumer<PsiType>() {
-              @Override
-              public void consume(PsiType functionalInterfaceType) {
-                PsiType qualifierType = LambdaUtil.getLambdaParameterFromType(functionalInterfaceType, parameterIndex);
-                PsiReferenceExpression fakeRef = createReference("xxx.xxx", createContextWithXxxVariable(element, qualifierType));
-                set.addAll(processJavaQualifiedReference(fakeRef.getReferenceNameElement(), fakeRef, elementFilter, options, matcher, parameters));
-              }
+            final boolean overloadsFound = LambdaUtil.processParentOverloads(lambdaExpression, functionalInterfaceType -> {
+              PsiType qualifierType = LambdaUtil.getLambdaParameterFromType(functionalInterfaceType, parameterIndex);
+              if (qualifierType == null) return;
+
+              PsiReferenceExpression fakeRef = createReference("xxx.xxx", createContextWithXxxVariable(element, qualifierType));
+              set.addAll(processJavaQualifiedReference(fakeRef.getReferenceNameElement(), fakeRef, elementFilter, options, matcher, parameters));
             });
             if (overloadsFound) return set;
           }
@@ -890,7 +889,7 @@ public class JavaCompletionUtil {
     return true;
   }
 
-  public static FakePsiElement createContextWithXxxVariable(final PsiElement place, final PsiType varType) {
+  public static FakePsiElement createContextWithXxxVariable(@NotNull PsiElement place, @NotNull PsiType varType) {
     return new FakePsiElement() {
       @Override
       public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
index 58614635bac2c6343284b20385df33db64139b40..1380a5641d247d708f6867f0357e4e325eb1705f 100644 (file)
@@ -22,9 +22,8 @@ import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.EditorModificationUtil;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Key;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NotNull;
 
@@ -32,7 +31,6 @@ import java.util.Set;
 
 
 public class JavaPostfixTemplateProvider implements PostfixTemplateProvider {
-  public static final Key<SmartPsiElementPointer<PsiElement>> ADDED_SEMICOLON = Key.create("postfix_added_semicolon");
   private final Set<PostfixTemplate> templates;
 
 
@@ -84,67 +82,34 @@ public class JavaPostfixTemplateProvider implements PostfixTemplateProvider {
   public void preExpand(@NotNull final PsiFile file, @NotNull final Editor editor) {
     ApplicationManager.getApplication().assertIsDispatchThread();
 
-    file.putUserData(ADDED_SEMICOLON, null);
     if (isSemicolonNeeded(file, editor)) {
-      ApplicationManager.getApplication().runWriteAction(new Runnable() {
-        @Override
-        public void run() {
-          CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
-            public void run() {
-              Document document = file.getViewProvider().getDocument();
-              assert document != null;
-              EditorModificationUtil.insertStringAtCaret(editor, ";", false, false);
-              PsiDocumentManager.getInstance(file.getProject()).commitDocument(document);
-              PsiElement at = file.findElementAt(editor.getCaretModel().getOffset());
-              if (at != null && at.getNode().getElementType() == JavaTokenType.SEMICOLON) {
-                file.putUserData(ADDED_SEMICOLON, SmartPointerManager.getInstance(file.getProject()).createSmartPsiElementPointer(at));
-              }
-            }
+      ApplicationManager.getApplication().runWriteAction(() -> {
+        CommandProcessor.getInstance().runUndoTransparentAction(
+          () -> {
+            EditorModificationUtil.insertStringAtCaret(editor, ";", false, false);
+            PsiDocumentManager.getInstance(file.getProject()).commitDocument(editor.getDocument());
           });
-        }
       });
     }
   }
 
   @Override
   public void afterExpand(@NotNull final PsiFile file, @NotNull final Editor editor) {
-    final SmartPsiElementPointer<PsiElement> pointer = file.getUserData(ADDED_SEMICOLON);
-    if (pointer != null) {
-      final PsiElement addedSemicolon = pointer.getElement();
-      file.putUserData(ADDED_SEMICOLON, null);
-      if (addedSemicolon != null && addedSemicolon.isValid() && addedSemicolon.getNode().getElementType() == JavaTokenType.SEMICOLON) {
-        CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
-          @Override
-          public void run() {
-            ApplicationManager.getApplication().runWriteAction(new Runnable() {
-              public void run() {
-                  addedSemicolon.delete();
-              }
-            });
-          }
-        });
-      }
-    }
   }
 
   @NotNull
   @Override
   public PsiFile preCheck(final @NotNull PsiFile copyFile, final @NotNull Editor realEditor, final int currentOffset) {
-    return ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
-      @Override
-      public PsiFile compute() {
-        Document document = copyFile.getViewProvider().getDocument();
-        assert document != null;
-        CharSequence sequence = document.getCharsSequence();
-        StringBuilder fileContentWithSemicolon = new StringBuilder(sequence);
-        if (isSemicolonNeeded(copyFile, realEditor)) {
-          fileContentWithSemicolon.insert(currentOffset, ';');
-          return PostfixLiveTemplate.copyFile(copyFile, fileContentWithSemicolon);
-        }
+    Document document = copyFile.getViewProvider().getDocument();
+    assert document != null;
+    CharSequence sequence = document.getCharsSequence();
+    StringBuilder fileContentWithSemicolon = new StringBuilder(sequence);
+    if (isSemicolonNeeded(copyFile, realEditor)) {
+      fileContentWithSemicolon.insert(currentOffset, ';');
+      return PostfixLiveTemplate.copyFile(copyFile, fileContentWithSemicolon);
+    }
 
-        return copyFile;
-      }
-    });
+    return copyFile;
   }
 
   private static boolean isSemicolonNeeded(@NotNull PsiFile file, @NotNull Editor editor) {
index 08fef26ae05d69a10b16155d7cc4eb927589c423..92d0a65f5c18ace70834eff388c429e5ed8d0dcb 100644 (file)
@@ -1032,6 +1032,9 @@ public class PsiClassImplUtil {
       return new PsiClassType[]{getAnnotationSuperType(psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory())};
     }
     PsiType upperBound = psiClass.getUserData(InferenceSession.UPPER_BOUND);
+    if (upperBound == null && psiClass instanceof PsiTypeParameter) {
+      upperBound = LambdaUtil.getFunctionalTypeMap().get(psiClass);
+    }
     if (upperBound instanceof PsiIntersectionType) {
       final PsiType[] conjuncts = ((PsiIntersectionType)upperBound).getConjuncts();
       final List<PsiClassType> result = new ArrayList<PsiClassType>();
index fa8ce5f676f91a2c3703388ee2ced53eacc0c930..1ea78fd71ea3e75a8645c8543f98b79473e1e807 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * 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.
@@ -32,7 +32,6 @@ import com.intellij.ui.RowIcon;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.PlatformIcons;
 import gnu.trove.THashSet;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -123,16 +122,16 @@ public class ClsFieldImpl extends ClsMemberImpl<PsiFieldStub> implements PsiFiel
     final PsiClass containingClass = getContainingClass();
     final String qName = containingClass != null ? containingClass.getQualifiedName() : null;
     if ("java.lang.Float".equals(qName)) {
-      @NonNls final String name = getName();
-      if ("POSITIVE_INFINITY".equals(name)) return new Float(Float.POSITIVE_INFINITY);
-      if ("NEGATIVE_INFINITY".equals(name)) return new Float(Float.NEGATIVE_INFINITY);
-      if ("NaN".equals(name)) return new Float(Float.NaN);
+      String name = getName();
+      if ("POSITIVE_INFINITY".equals(name)) return Float.POSITIVE_INFINITY;
+      if ("NEGATIVE_INFINITY".equals(name)) return Float.NEGATIVE_INFINITY;
+      if ("NaN".equals(name)) return Float.NaN;
     }
     else if ("java.lang.Double".equals(qName)) {
-      @NonNls final String name = getName();
-      if ("POSITIVE_INFINITY".equals(name)) return new Double(Double.POSITIVE_INFINITY);
-      if ("NEGATIVE_INFINITY".equals(name)) return new Double(Double.NEGATIVE_INFINITY);
-      if ("NaN".equals(name)) return new Double(Double.NaN);
+      String name = getName();
+      if ("POSITIVE_INFINITY".equals(name)) return Double.POSITIVE_INFINITY;
+      if ("NEGATIVE_INFINITY".equals(name)) return Double.NEGATIVE_INFINITY;
+      if ("NaN".equals(name)) return Double.NaN;
     }
 
     return PsiConstantEvaluationHelperImpl.computeCastTo(initializer, getType(), visitedVars);
@@ -243,4 +242,4 @@ public class ClsFieldImpl extends ClsMemberImpl<PsiFieldStub> implements PsiFiel
   public String toString() {
     return "PsiField:" + getName();
   }
-}
+}
\ No newline at end of file
index 8d013b5e187a24d51d20b18be7fd504eac63d1d8..a93c65a61dbbc2557c8eeaaec3842e4e5c80bcd9 100644 (file)
@@ -1501,18 +1501,6 @@ public class InferenceSession {
                                        final PsiElement context,
                                        final boolean varargs) {
     try {
-      //push site substitutor to parameter bounds
-      final String text;
-      if (m1 instanceof ClsMethodImpl) {
-        final StringBuilder builder = new StringBuilder();
-        ((ClsMethodImpl)m1).appendMirrorText(0, builder);
-        text = builder.toString();
-      }
-      else {
-        text = m1.getText();
-      }
-
-      m1 = JavaPsiFacade.getElementFactory(m1.getProject()).createMethodFromText(text, m1);
       for (PsiTypeParameter parameter : m1.getTypeParameters()) {
         final PsiClassType[] types = parameter.getExtendsListTypes();
         if (types.length > 0) {
@@ -1525,14 +1513,14 @@ public class InferenceSession {
           //don't glb to avoid flattening = Object&Interface would be preserved
           //otherwise methods with different signatures could get same erasure
           final PsiType upperBound = PsiIntersectionType.createIntersection(false, conjuncts.toArray(new PsiType[conjuncts.size()]));
-          parameter.putUserData(UPPER_BOUND, upperBound);
+          LambdaUtil.getFunctionalTypeMap().put(parameter, upperBound);
         }
       }
       return isMoreSpecificInternal(m1, m2, siteSubstitutor1, args, context, varargs);
     }
     finally {
-      for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(m1)) {
-        parameter.putUserData(UPPER_BOUND, null);
+      for (PsiTypeParameter parameter : m1.getTypeParameters()) {
+        LambdaUtil.getFunctionalTypeMap().remove(parameter);
       }
     }
   }
index 84279bf978ba484e4cf9cd58aeb929ce7d4f01e3..a490643cf8bfdcecb7ae1eae7c19ac9bf9b2f619 100644 (file)
@@ -103,14 +103,9 @@ public class InferenceVariable extends LightTypeParameter {
 
   public Set<InferenceVariable> getDependencies(InferenceSession session) {
     final Set<InferenceVariable> dependencies = new LinkedHashSet<InferenceVariable>();
-    for (Collection<PsiType> boundTypes : myBounds.values()) {
-      if (boundTypes != null) {
-        for (PsiType bound : boundTypes) {
-          session.collectDependencies(bound, dependencies);
-        }
-      }
-    }
-
+    collectBoundDependencies(session, dependencies);
+    collectTransitiveDependencies(session, dependencies, dependencies);
+    
     if (!session.hasCapture(this) && dependencies.isEmpty()) {
       return dependencies;
     }
@@ -128,6 +123,33 @@ public class InferenceVariable extends LightTypeParameter {
     return dependencies;
   }
 
+  private void collectTransitiveDependencies(InferenceSession session, 
+                                             Set<InferenceVariable> dependencies,
+                                             Set<InferenceVariable> rootDependencies) {
+    final LinkedHashSet<InferenceVariable> newDependencies = new LinkedHashSet<InferenceVariable>();
+
+    for (InferenceVariable dependency : dependencies) {
+      dependency.collectBoundDependencies(session, newDependencies);
+    }
+    newDependencies.removeAll(rootDependencies);
+    newDependencies.remove(this);
+
+    if (!newDependencies.isEmpty()) {
+      rootDependencies.addAll(newDependencies);
+      collectTransitiveDependencies(session, newDependencies, rootDependencies);
+    }
+  }
+
+  private void collectBoundDependencies(InferenceSession session, Set<InferenceVariable> dependencies) {
+    for (Collection<PsiType> boundTypes : myBounds.values()) {
+      if (boundTypes != null) {
+        for (PsiType bound : boundTypes) {
+          session.collectDependencies(bound, dependencies);
+        }
+      }
+    }
+  }
+
   public boolean hasInstantiation(InferenceSession session) {
     List<PsiType> bounds = getBounds(InferenceBound.EQ);
     if (bounds != null) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/TransitiveInferenceVariableDependencies.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/TransitiveInferenceVariableDependencies.java
new file mode 100644 (file)
index 0000000..167ac74
--- /dev/null
@@ -0,0 +1,8 @@
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+class Test {
+  private void foo(final Stream<String> stream) {
+    stream.collect(Collectors.collectingAndThen(Collectors.toList(), list -> list)).get(0).length();
+  }
+}
index df6f45ea8c92bf269030ff4c7fa21490394c1ce5..57088c72c084ae92706f4fe856bdcc2788554ec1 100644 (file)
@@ -671,7 +671,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
 
     final int[] count = {0};
     MarkupModelEx modelEx = (MarkupModelEx)DocumentMarkupModel.forDocument(getDocument(getFile()), getProject(), true);
-    modelEx.addMarkupModelListener(getTestRootDisposable(), new MarkupModelListener() {
+    modelEx.addMarkupModelListener(getTestRootDisposable(), new MarkupModelListener.Adapter() {
       @Override
       public void afterAdded(@NotNull RangeHighlighterEx highlighter) {
         count[0]++;
@@ -681,10 +681,6 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
       public void beforeRemoved(@NotNull RangeHighlighterEx highlighter) {
         count[0]++;
       }
-
-      @Override
-      public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
-      }
     });
 
     type(' ');
@@ -718,7 +714,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
       }
 
       @Override
-      public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
+      public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
         changed(highlighter, ExceptionUtil.getThrowableText(new Throwable("changed")));
       }
 
@@ -769,7 +765,7 @@ public class DaemonRespondToChangesTest extends DaemonAnalyzerTestCase {
       }
 
       @Override
-      public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
+      public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
         changed(highlighter, ExceptionUtil.getThrowableText(new Throwable("changed")));
       }
 
index 8094fc5a14b0960126fa29ebb8a62cd9bf06ed28..1ac990d85b1c1ed51958c15e73ad103cc14ee5b0 100644 (file)
@@ -371,6 +371,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
     doTest();
   }
 
+  public void testTransitiveInferenceVariableDependencies() throws Exception {
+    doTest();
+  }
+
   private void doTest() throws Exception {
     doTest(false);
   }
index d05067b23d0c32c3fe98b1eb7f20e6c9be17ca9b..18655337b98e96815b8003df74259aba39d7c00c 100644 (file)
@@ -19,7 +19,7 @@ public class MacroParserTest extends LightIdeaTestCase {
     Expression e = MacroParser.parse("  variableOfType(  \"java.util.Collection\"  )   ");
     assertTrue(e instanceof MacroCallNode);
     MacroCallNode n = (MacroCallNode) e;
-    assertTrue(n.getMacro(new TemplateContextType[0]) instanceof VariableOfTypeMacro);
+    assertTrue(n.getMacro() instanceof VariableOfTypeMacro);
     Expression[] parameters = n.getParameters();
     assertEquals(1, parameters.length);
     assertTrue(parameters [0] instanceof ConstantNode);
@@ -46,7 +46,7 @@ public class MacroParserTest extends LightIdeaTestCase {
     Expression e = MacroParser.parse("variableOfType(\"A\", \"B\")");
     assertTrue(e instanceof MacroCallNode);
     MacroCallNode n = (MacroCallNode) e;
-    assertTrue(n.getMacro(new TemplateContextType[0]) instanceof VariableOfTypeMacro);
+    assertTrue(n.getMacro() instanceof VariableOfTypeMacro);
     Expression[] parameters = n.getParameters();
     assertEquals(2, parameters.length);
     assertTrue(parameters [0] instanceof ConstantNode);
index 9d152d5be989cce0a8adc53829a14178122e94ab..471f5e0ed6307f0717563670970874674c63b697 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -25,10 +25,8 @@ import com.intellij.psi.impl.compiled.ClsFileImpl;
 import com.intellij.psi.stubs.PsiFileStub;
 import com.intellij.psi.stubs.StubBase;
 import com.intellij.testFramework.LightIdeaTestCase;
-import com.intellij.util.cls.ClsFormatException;
 
 import java.io.File;
-import java.io.IOException;
 
 /**
  * @author max
@@ -83,10 +81,7 @@ public class ClsBuilderTest extends LightIdeaTestCase {
 
       assertEquals(expected, actual);
     }
-    catch (ClsFormatException e) {
-      throw new RuntimeException(e);
-    }
-    catch (IOException e) {
+    catch (Exception e) {
       throw new RuntimeException(e);
     }
   }
@@ -101,4 +96,4 @@ public class ClsBuilderTest extends LightIdeaTestCase {
     fail("Cannot file class file for: " + className);
     return null;
   }
-}
+}
\ No newline at end of file
index cada6035b4789684748caf42d74359786f1685fc..d5c0b71b712d7cc98a60fa88a467803fc6dafb71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -370,6 +370,19 @@ public class ClsPsiTest extends LightIdeaTestCase {
     assertEquals("pack.$Weird$Name.Inner", aClass.getQualifiedName());
   }
 
+  public void testFieldConstantValue() {
+    PsiClass dbl = getJavaFacade().findClass(Double.class.getName(), myScope);
+    assertNotNull(dbl);
+    PsiField dnn = dbl.findFieldByName("NaN", false);
+    assertNotNull(dnn);
+    assertEquals(Double.NaN, dnn.computeConstantValue());
+
+    PsiClass cls = getFile("../../mirror/pkg/Primitives").getClasses()[0];
+    PsiField lng = cls.findFieldByName("LONG", false);
+    assertNotNull(lng);
+    assertEquals(42L, lng.computeConstantValue());
+  }
+
   private PsiJavaFile getFile() {
     return getFile(getTestName(false));
   }
index af68ad625ac89a54fb25cff220422012a261110e..836a97ac5079ce107a99b5bc21fd9e9ff8f13683 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
 package com.intellij.psi;
 
 import com.intellij.JavaTestUtil;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.roots.ModuleRootModificationUtil;
-import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.testFramework.PsiTestCase;
-import com.intellij.testFramework.PsiTestUtil;
-import org.jetbrains.annotations.NotNull;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
 
-import java.io.IOException;
-
-public class ConstantValuesTest extends PsiTestCase{
+public class ConstantValuesTest extends LightCodeInsightFixtureTestCase {
   private PsiClass myClass;
 
   @Override
-  protected void setUp() throws Exception {
-    super.setUp();
-
-    ApplicationManager.getApplication().runWriteAction(
-      new Runnable() {
-        @Override
-        public void run() {
-          try{
-            String rootPath = JavaTestUtil.getJavaTestDataPath() + "/psi/constantValues";
-            VirtualFile root = PsiTestUtil.createTestProjectStructure(myProject, myModule, rootPath, myFilesToDelete, true);
-            ModuleRootModificationUtil.addModuleLibrary(myModule, root.getUrl());
-          }
-          catch(Exception e){
-            LOG.error(e);
-          }
-        }
-      }
-    );
-
-    myClass = myJavaFacade.findClass("ClassWithConstants", GlobalSearchScope.allScope(getProject()));
-    assertNotNull(myClass);
-    assertEquals(StdFileTypes.JAVA, myClass.getContainingFile().getVirtualFile().getFileType());
+  protected String getTestDataPath() {
+    return JavaTestUtil.getJavaTestDataPath() + "/psi/constantValues";
   }
 
   @Override
-  protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
-    super.invokeTestRunnable(runnable);
-    final PsiJavaFile file = (PsiJavaFile)myClass.getContainingFile();
-
-    WriteCommandAction.runWriteCommandAction(
-      null, new Runnable() {
-        @Override
-        public void run() {
-          try {
-            file.getVirtualFile().setBinaryContent(file.getVirtualFile().contentsToByteArray());
-          }
-          catch (IOException e) {
-            LOG.error(e);
-          }
-        }
-      }
-    );
-
-    LOG.assertTrue(file.isValid());
-    myClass = file.getClasses()[0];
-
-    LOG.assertTrue(myClass.isValid());
-    super.invokeTestRunnable(runnable);
+  protected void setUp() throws Exception {
+    super.setUp();
+    myClass = ((PsiJavaFile)myFixture.configureByFile("ClassWithConstants.java")).getClasses()[0];
   }
 
-  public void testInt1(){
+  public void testInt1() {
     PsiField field = myClass.findFieldByName("INT_CONST1", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -95,20 +45,21 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(Integer.valueOf(1), field.computeConstantValue());
   }
 
-  public void testInt2(){
+  public void testInt2() {
     PsiField field = myClass.findFieldByName("INT_CONST2", false);
     assertNotNull(field);
     PsiPrefixExpression initializer = (PsiPrefixExpression)field.getInitializer();
     assertNotNull(initializer);
     assertEquals(PsiType.INT, initializer.getType());
     PsiLiteralExpression operand = (PsiLiteralExpression)initializer.getOperand();
+    assertNotNull(operand);
     assertEquals(Integer.valueOf(1), operand.getValue());
     assertEquals("-1", initializer.getText());
 
     assertEquals(Integer.valueOf(-1), field.computeConstantValue());
   }
 
-  public void testInt3(){
+  public void testInt3() {
     PsiField field = myClass.findFieldByName("INT_CONST3", false);
     assertNotNull(field);
     PsiPrefixExpression initializer = (PsiPrefixExpression)field.getInitializer();
@@ -120,7 +71,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(Integer.valueOf(value), field.computeConstantValue());
   }
 
-  public void testLong1(){
+  public void testLong1() {
     PsiField field = myClass.findFieldByName("LONG_CONST1", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -132,7 +83,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(Long.valueOf(2), field.computeConstantValue());
   }
 
-  public void testLong2(){
+  public void testLong2() {
     PsiField field = myClass.findFieldByName("LONG_CONST2", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -144,7 +95,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(Long.valueOf(1000000000000L), field.computeConstantValue());
   }
 
-  public void testLong3(){
+  public void testLong3() {
     PsiField field = myClass.findFieldByName("LONG_CONST3", false);
     assertNotNull(field);
     PsiPrefixExpression initializer = (PsiPrefixExpression)field.getInitializer();
@@ -156,7 +107,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(Long.valueOf(value), field.computeConstantValue());
   }
 
-  public void testShort(){
+  public void testShort() {
     PsiField field = myClass.findFieldByName("SHORT_CONST", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -168,7 +119,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(Short.valueOf((short)3), field.computeConstantValue());
   }
 
-  public void testByte(){
+  public void testByte() {
     PsiField field = myClass.findFieldByName("BYTE_CONST", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -180,7 +131,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(Byte.valueOf((byte)4), field.computeConstantValue());
   }
 
-  public void testChar(){
+  public void testChar() {
     PsiField field = myClass.findFieldByName("CHAR_CONST", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -192,7 +143,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(new Character('5'), field.computeConstantValue());
   }
 
-  public void testBoolean(){
+  public void testBoolean() {
     PsiField field = myClass.findFieldByName("BOOL_CONST", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -204,7 +155,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(Boolean.TRUE, field.computeConstantValue());
   }
 
-  public void testFloat(){
+  public void testFloat() {
     PsiField field = myClass.findFieldByName("FLOAT_CONST", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -216,7 +167,7 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(new Float(1.234f), field.computeConstantValue());
   }
 
-  public void testDouble(){
+  public void testDouble() {
     PsiField field = myClass.findFieldByName("DOUBLE_CONST", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
@@ -228,19 +179,21 @@ public class ConstantValuesTest extends PsiTestCase{
     assertEquals(new Double(3.456), field.computeConstantValue());
   }
 
-  public void testString(){
+  public void testString() {
     PsiField field = myClass.findFieldByName("STRING_CONST", false);
     assertNotNull(field);
     PsiLiteralExpression initializer = (PsiLiteralExpression)field.getInitializer();
     assertNotNull(initializer);
-    assertTrue(initializer.getType().equalsToText("java.lang.String"));
+    PsiType type = initializer.getType();
+    assertNotNull(type);
+    assertTrue(type.equalsToText("java.lang.String"));
     assertEquals("a\r\n\"bcd", initializer.getValue());
     assertEquals("\"a\\r\\n\\\"bcd\"", initializer.getText());
 
     assertEquals("a\r\n\"bcd", field.computeConstantValue());
   }
 
-  public void testInfinity(){
+  public void testInfinity() {
     PsiField field1 = myClass.findFieldByName("d1", false);
     assertNotNull(field1);
     PsiReferenceExpression initializer1 = (PsiReferenceExpression)field1.getInitializer();
@@ -267,17 +220,13 @@ public class ConstantValuesTest extends PsiTestCase{
   }
 
   public void testConstantEvaluatorStackOverflowResistance() {
-    String text ="class X { String s = \"\" ";
-    for (int i=0;i<10000;i++) {
-      text += "+ \"\"";
-    }
-    text += "; }";
-    PsiJavaFile file = (PsiJavaFile)createDummyFile("a.java", text);
-
-    PsiExpression expression = file.getClasses()[0].findFieldByName("s", false).getInitializer();
+    StringBuilder text = new StringBuilder(65536).append("class X { String s = \"\"");
+    for (int i = 0; i < 10000; i++) text.append(" + \"\"");
+    text.append("; }");
 
-    Object o = JavaConstantExpressionEvaluator.computeConstantExpression(expression, false);
-
-    assertEquals("", o);
+    PsiJavaFile file = (PsiJavaFile)myFixture.configureByText("a.java", text.toString());
+    PsiField field = file.getClasses()[0].findFieldByName("s", false);
+    assertNotNull(field);
+    assertEquals("", JavaConstantExpressionEvaluator.computeConstantExpression(field.getInitializer(), false));
   }
-}
+}
\ No newline at end of file
index 757d32bef431c50853927097a57032c7455dff27..5bd2eec4c37910f907f3e1706a1457a4256b5aca 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -75,6 +75,10 @@ public abstract class ExecutionTestCase extends IdeaTestCase {
       }
     });
     if (!myModuleOutputDir.exists()) {
+      VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ourOutputRoot);
+      assertNotNull(ourOutputRoot.getAbsolutePath(), vDir);
+      vDir.getChildren();//we need this to load children to VFS to fire VFileCreatedEvent for the output directory
+
       myCompilerTester = new CompilerTester(myProject, Arrays.asList(ModuleManager.getInstance(myProject).getModules()));
       List<CompilerMessage> messages = myCompilerTester.rebuild();
       for (CompilerMessage message : messages) {
index 040c935c2a9a0f74eebffc116aaf1250257e1187..54597828294db1241b6c20147cc389ead1369842 100644 (file)
@@ -63,7 +63,7 @@ import java.util.concurrent.ConcurrentMap;
 public abstract class PsiDocumentManagerBase extends PsiDocumentManager implements DocumentListener, ProjectComponent {
   static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiDocumentManagerImpl");
   private static final Key<Document> HARD_REF_TO_DOCUMENT = Key.create("HARD_REFERENCE_TO_DOCUMENT");
-  private static final Key<PsiFile> HARD_REF_TO_PSI = Key.create("HARD_REFERENCE_TO_PSI");
+  private final Key<PsiFile> HARD_REF_TO_PSI = Key.create("HARD_REFERENCE_TO_PSI"); // has to be different for each project to avoid mixups
   private static final Key<List<Runnable>> ACTION_AFTER_COMMIT = Key.create("ACTION_AFTER_COMMIT");
 
   protected final Project myProject;
@@ -120,7 +120,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
     return psiFile;
   }
 
-  public static void cachePsi(@NotNull Document document, @Nullable PsiFile file) {
+  public void cachePsi(@NotNull Document document, @Nullable PsiFile file) {
     document.putUserData(HARD_REF_TO_PSI, file);
   }
 
@@ -287,9 +287,9 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
 
   // public for Upsource
   public boolean finishCommit(@NotNull final Document document,
-                       @NotNull final List<Processor<Document>> finishProcessors,
-                       final boolean synchronously,
-                       @NotNull final Object reason) {
+                              @NotNull final List<Processor<Document>> finishProcessors,
+                              final boolean synchronously,
+                              @NotNull final Object reason) {
     assert !myProject.isDisposed() : "Already disposed";
     final boolean[] ok = {true};
     ApplicationManager.getApplication().runWriteAction(new CommitToPsiFileAction(document, myProject) {
@@ -539,7 +539,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
             action.run();
           }
           catch (Throwable e) {
-            LOG.error("During running "+action, e);
+            LOG.error("During running " + action, e);
           }
         }
       }
index f8ba97181d2df8df6df90e888372fd29adf63cfd..aa5fd88fdaedd40e26584b00ea5e48ecd62278b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -256,7 +256,7 @@ public class FileManagerImpl implements FileManager {
 
         Document document = FileDocumentManager.getInstance().getCachedDocument(virtualFile);
         if (document != null) {
-          PsiDocumentManagerBase.cachePsi(document, null);
+          ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(myManager.getProject())).cachePsi(document, null);
         }
         virtualFile.putUserData(myPsiHardRefKey, null);
       }
index b8c3addcc8de8c017dbcf28a4eceab9434c0166b..73d53ea2219899d8b67500dc5198ed6091e43ddf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -125,7 +125,7 @@ public abstract class LeafElement extends TreeElement {
     return leafTextMatches(text, buffer, start);
   }
 
-  public static int leafTextMatches(@NotNull CharSequence text, @NotNull CharSequence buffer, int start) {
+  static int leafTextMatches(@NotNull CharSequence text, @NotNull CharSequence buffer, int start) {
     assert start >= 0 : start;
     final int length = text.length();
     if(buffer.length() - start < length) {
index 0a062defa43a07c073698b0d60e53adb63b313c8..c21bbea0c56302056a2013a9e0610ee1ccf1f558 100644 (file)
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
 
 import java.util.Iterator;
 
-@SuppressWarnings("ConstantConditions")
 abstract class ChangeDiffIterableBase extends DiffIterableBase {
   private final int myLength1;
   private final int myLength2;
index 58c1a1d754d0a236ff8d63878fb48965d0f19e39..e873893a948b9b96f030b3b8ec59dd13593b976e 100644 (file)
@@ -19,7 +19,6 @@ import com.intellij.util.diff.Diff;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-@SuppressWarnings("ConstantConditions")
 class DiffChangeDiffIterable extends ChangeDiffIterableBase {
   @Nullable private final Diff.Change myChange;
 
@@ -34,6 +33,7 @@ class DiffChangeDiffIterable extends ChangeDiffIterableBase {
     return new DiffChangeChangeIterable(myChange);
   }
 
+  @SuppressWarnings("ConstantConditions")
   private static class DiffChangeChangeIterable implements ChangeIterable {
     @Nullable private Diff.Change myChange;
 
index a977b5c86dabb502d05c5002683b315c3c29118c..75baafa1860d37c2a44bdd7fabdd546501524c5d 100644 (file)
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
-@SuppressWarnings("ConstantConditions")
 class DiffFragmentsDiffIterable extends ChangeDiffIterableBase {
   @NotNull private final List<? extends DiffFragment> myFragments;
 
index 64c74bf016ce0923f70fadd7c7f97f7fee45093d..df65b239e024876497a4f50e6b6cf4ba53e2973c 100644 (file)
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
 
 import java.util.Iterator;
 
-@SuppressWarnings("ConstantConditions")
 abstract class DiffIterableBase implements DiffIterable {
   @NotNull
   @Override
index 3ffa7265693c250daff07a56776ed29ae1901581..541dd258a680e7e58052e40a808109c337e1a831 100644 (file)
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
 
 import java.util.Iterator;
 
-@SuppressWarnings("ConstantConditions")
 class FairDiffIterableWrapper extends DiffIterableBase implements FairDiffIterable {
   @NotNull private final DiffIterable myIterable;
 
index 87d7b8faa92dd89b711e584f44d2f83e94eb2fe5..eb90d653ddb7a8dc631e0822547f299eeb207790 100644 (file)
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
 
 import java.util.Iterator;
 
-@SuppressWarnings("ConstantConditions")
 class InvertedDiffIterableWrapper extends DiffIterableBase {
   @NotNull private final DiffIterable myIterable;
 
index 23a11ef49674080dbd72e14d0eab20d564b61b5b..efdee4898558eda8ceb13319566f0ba01230dd12 100644 (file)
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
-@SuppressWarnings("ConstantConditions")
 class RangesDiffIterable extends ChangeDiffIterableBase {
   @NotNull private final List<? extends Range> myRanges;
 
index 226f699ffa02ac1730a8ed9ed9401c9d971bc1f9..e9970e8f09f0a3fa546f0d99fec3aa04f9657f6d 100644 (file)
@@ -21,6 +21,7 @@ import com.intellij.diff.util.DiffUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.WindowWrapper;
 import com.intellij.openapi.ui.WindowWrapperBuilder;
+import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.util.ImageLoader;
 import org.jetbrains.annotations.NotNull;
@@ -53,11 +54,16 @@ public abstract class DiffWindowBase {
       .setProject(myProject)
       .setParent(myHints.getParent())
       .setDimensionServiceKey(dialogGroupKey)
+      .setPreferredFocusedComponent(new Computable<JComponent>() {
+        @Override
+        public JComponent compute() {
+          return myProcessor.getPreferredFocusedComponent();
+        }
+      })
       .setOnShowCallback(new Runnable() {
         @Override
         public void run() {
           myProcessor.updateRequest();
-          myProcessor.requestFocus(); // TODO: not needed for modal dialogs. Make a flag in WindowWrapperBuilder ?
         }
       })
       .build();
index 82a043d7d08b86c1a0d26d82f05fbbd322d3a5ba..f8fa1983210203c57d1c09a12f0a09ea616532d2 100644 (file)
@@ -18,13 +18,13 @@ package com.intellij.diff.util;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
-import com.intellij.openapi.editor.markup.LineMarkerRenderer;
+import com.intellij.openapi.editor.markup.LineMarkerRendererEx;
 import com.intellij.openapi.editor.markup.RangeHighlighter;
 import org.jetbrains.annotations.NotNull;
 
 import java.awt.*;
 
-public class DiffLineMarkerRenderer implements LineMarkerRenderer {
+public class DiffLineMarkerRenderer implements LineMarkerRendererEx {
   @NotNull private final RangeHighlighter myHighlighter;
   @NotNull private final TextDiffType myDiffType;
   private final boolean myIgnoredFoldingOutline;
@@ -104,4 +104,9 @@ public class DiffLineMarkerRenderer implements LineMarkerRenderer {
       DiffDrawUtil.drawChunkBorderLine(g2, x1, x2, y - 1, color, true, myResolved);
     }
   }
+
+  @Override
+  public Position getPosition() {
+    return Position.CUSTOM;
+  }
 }
index 7570cbb9c33f3f33e1e51c98cdd988fdf2d96a0a..e6d677df7588cd8a6bf741a6667c6997e0c6fb94 100644 (file)
@@ -22,7 +22,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
 import com.intellij.openapi.editor.colors.EditorColorsScheme;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
-import com.intellij.openapi.editor.markup.LineMarkerRenderer;
+import com.intellij.openapi.editor.markup.LineMarkerRendererEx;
 import com.intellij.openapi.editor.markup.LineSeparatorRenderer;
 import com.intellij.openapi.ui.GraphicsConfig;
 import com.intellij.openapi.util.BooleanGetter;
@@ -36,7 +36,7 @@ import java.awt.*;
 import java.awt.geom.AffineTransform;
 import java.util.Arrays;
 
-public class DiffLineSeparatorRenderer implements LineMarkerRenderer, LineSeparatorRenderer {
+public class DiffLineSeparatorRenderer implements LineMarkerRendererEx, LineSeparatorRenderer {
   @NotNull private final Editor myEditor;
   @NotNull private final BooleanGetter myCondition;
 
@@ -142,6 +142,11 @@ public class DiffLineSeparatorRenderer implements LineMarkerRenderer, LineSepara
     draw(g, shiftX, y, lineHeight, myEditor.getColorsScheme());
   }
 
+  @Override
+  public LineMarkerRendererEx.Position getPosition() {
+    return LineMarkerRendererEx.Position.CUSTOM;
+  }
+
   private static void draw(@NotNull Graphics g,
                            int shiftX,
                            int shiftY,
index 062e8ce0800bbcc63af2f490b031158772b3cc93..c9fe80344e9f51adf62355ff3bf29e9479df19b9 100644 (file)
@@ -187,7 +187,6 @@ public class DiffUtil {
     editor.getSettings().setShowIntentionBulb(false);
     ((EditorMarkupModel)editor.getMarkupModel()).setErrorStripeVisible(true);
     editor.getGutterComponentEx().setShowDefaultGutterPopup(false);
-    editor.getGutterComponentEx().setShowRightFreePaintersArea(false);
 
     if (enableFolding) {
       setFoldingModelSupport(editor);
index f95c47e6b99862bd52024511cc3d0789d1529eec..2addb6cd039675ca16120c5b01d6b3ac86fdcf2b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -151,7 +151,7 @@ public class MarkupModelWindow extends UserDataHolderBase implements MarkupModel
   }
 
   @Override
-  public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged) {
+  public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged) {
 
   }
 
index 6b848f40e0b22e5fc89c14b68211444fc929d29b..5416607e12f262ddc36a8416ed343ba6ebc6097b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -35,7 +35,7 @@ public interface MarkupModelEx extends MarkupModel {
   @Nullable
   RangeHighlighterEx addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes);
 
-  void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged);
+  void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged);
 
   void fireAfterAdded(@NotNull RangeHighlighterEx segmentHighlighter);
 
index 17a19df56ca98f7f9c99a4fa798035fd057b5953..d6177dbdf13e1273979336119f6324bf5bb59593 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -144,7 +144,7 @@ public class EmptyMarkupModel implements MarkupModelEx {
   }
 
   @Override
-  public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged) {
+  public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged) {
 
   }
 
index d5a0d8795fa262a4505b7086d321396935cce54c..c999f5618936fe9ef4fef823cf3c51069ac46888 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -144,9 +144,11 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx
   public void changeAttributesInBatch(@NotNull RangeHighlighterEx highlighter,
                                       @NotNull Consumer<RangeHighlighterEx> changeAttributesAction) {
     ApplicationManager.getApplication().assertIsDispatchThread();
-    RangeHighlighterImpl.ChangeResult changed = ((RangeHighlighterImpl)highlighter).changeAttributesNoEvents(changeAttributesAction);
-    if (changed != RangeHighlighterImpl.ChangeResult.NOT_CHANGED) {
-      fireAttributesChanged(highlighter, changed == RangeHighlighterImpl.ChangeResult.RENDERERS_CHANGED);
+    byte changeStatus = ((RangeHighlighterImpl)highlighter).changeAttributesNoEvents(changeAttributesAction);
+    if ((changeStatus & RangeHighlighterImpl.CHANGED_MASK) != 0) {
+      fireAttributesChanged(highlighter, 
+                            (changeStatus & RangeHighlighterImpl.RENDERERS_CHANGED_MASK) != 0, 
+                            (changeStatus & RangeHighlighterImpl.FONT_STYLE_CHANGED_MASK) != 0);
     }
   }
 
@@ -225,9 +227,9 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx
   }
 
   @Override
-  public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged) {
+  public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged) {
     for (MarkupModelListener listener : myListeners) {
-      listener.attributesChanged(segmentHighlighter, renderersChanged);
+      listener.attributesChanged(segmentHighlighter, renderersChanged, fontStyleChanged);
     }
   }
 
index f1d86d7fa3945847b502668fa706cf1be26c6742..c54c9e36756c1ba87d0c20ceb2bc4da6f83dbc5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -57,12 +57,17 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
   private static final byte ERROR_STRIPE_IS_THIN_MASK = 2;
   private static final byte TARGET_AREA_IS_EXACT_MASK = 4;
   private static final byte IN_BATCH_CHANGE_MASK = 8;
-  private static final byte CHANGED_MASK = 16;
-  private static final byte RENDERERS_CHANGED_MASK = 32;
+  static final byte CHANGED_MASK = 16;
+  static final byte RENDERERS_CHANGED_MASK = 32;
+  static final byte FONT_STYLE_CHANGED_MASK = 64;
 
-  @MagicConstant(intValues = {AFTER_END_OF_LINE_MASK, ERROR_STRIPE_IS_THIN_MASK, TARGET_AREA_IS_EXACT_MASK, IN_BATCH_CHANGE_MASK, CHANGED_MASK, RENDERERS_CHANGED_MASK})
+  @MagicConstant(intValues = {AFTER_END_OF_LINE_MASK, ERROR_STRIPE_IS_THIN_MASK, TARGET_AREA_IS_EXACT_MASK, IN_BATCH_CHANGE_MASK, 
+    CHANGED_MASK, RENDERERS_CHANGED_MASK, FONT_STYLE_CHANGED_MASK})
   private @interface FlagConstant {}
 
+  @MagicConstant(flags = {CHANGED_MASK, RENDERERS_CHANGED_MASK, FONT_STYLE_CHANGED_MASK})
+  private @interface ChangeStatus {}
+
   RangeHighlighterImpl(@NotNull MarkupModel model,
                        int start,
                        int end,
@@ -98,9 +103,13 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     TextAttributes old = myTextAttributes;
     myTextAttributes = textAttributes;
     if (!Comparing.equal(old, textAttributes)) {
-      fireChanged(false);
+      fireChanged(false, getFontStyle(old) != getFontStyle(textAttributes));
     }
   }
+  
+  private static int getFontStyle(TextAttributes textAttributes) {
+    return textAttributes == null ? Font.PLAIN : textAttributes.getFontType();
+  }
 
   @Override
   @NotNull
@@ -118,7 +127,7 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     LineMarkerRenderer old = myLineMarkerRenderer;
     myLineMarkerRenderer = renderer;
     if (!Comparing.equal(old, renderer)) {
-      fireChanged(true);
+      fireChanged(true, false);
     }
   }
 
@@ -132,7 +141,7 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     CustomHighlighterRenderer old = myCustomRenderer;
     myCustomRenderer = renderer;
     if (!Comparing.equal(old, renderer)) {
-      fireChanged(true);
+      fireChanged(true, false);
     }
   }
 
@@ -146,7 +155,7 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     GutterMark old = myGutterIconRenderer;
     myGutterIconRenderer = renderer;
     if (!Comparing.equal(old, renderer)) {
-      fireChanged(true);
+      fireChanged(true, false);
     }
   }
 
@@ -164,7 +173,7 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     Color old = myErrorStripeColor;
     myErrorStripeColor = color;
     if (!Comparing.equal(old, color)) {
-      fireChanged(false);
+      fireChanged(false, false);
     }
   }
 
@@ -179,7 +188,7 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     Object old = myErrorStripeTooltip;
     myErrorStripeTooltip = tooltipObject;
     if (!Comparing.equal(old, tooltipObject)) {
-      fireChanged(false);
+      fireChanged(false, false);
     }
   }
 
@@ -194,7 +203,7 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     boolean old = isThinErrorStripeMark();
     setFlag(ERROR_STRIPE_IS_THIN_MASK, value);
     if (old != value) {
-      fireChanged(false);
+      fireChanged(false, false);
     }
   }
 
@@ -208,7 +217,7 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     Color old = myLineSeparatorColor;
     myLineSeparatorColor = color;
     if (!Comparing.equal(old, color)) {
-      fireChanged(false);
+      fireChanged(false, false);
     }
   }
 
@@ -222,14 +231,14 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     SeparatorPlacement old = mySeparatorPlacement;
     mySeparatorPlacement = placement;
     if (!Comparing.equal(old, placement)) {
-      fireChanged(false);
+      fireChanged(false, false);
     }
   }
 
   @Override
   public void setEditorFilter(@NotNull MarkupEditorFilter filter) {
     myFilter = filter;
-    fireChanged(false);
+    fireChanged(false, false);
   }
 
   @Override
@@ -248,20 +257,19 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     boolean old = isAfterEndOfLine();
     setFlag(AFTER_END_OF_LINE_MASK, afterEndOfLine);
     if (old != afterEndOfLine) {
-      fireChanged(false);
+      fireChanged(false, false);
     }
   }
 
-  private void fireChanged(boolean renderersChanged) {
+  private void fireChanged(boolean renderersChanged, boolean fontStyleChanged) {
     if (myModel instanceof MarkupModelEx) {
       if (isFlagSet(IN_BATCH_CHANGE_MASK)) {
         setFlag(CHANGED_MASK, true);
-        if (renderersChanged) {
-          setFlag(RENDERERS_CHANGED_MASK, true);
-        }
+        if (renderersChanged) setFlag(RENDERERS_CHANGED_MASK, true);
+        if (fontStyleChanged) setFlag(FONT_STYLE_CHANGED_MASK, true);
       }
       else {
-        ((MarkupModelEx)myModel).fireAttributesChanged(this, renderersChanged);
+        ((MarkupModelEx)myModel).fireAttributesChanged(this, renderersChanged, fontStyleChanged);
       }
     }
   }
@@ -299,24 +307,27 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
 
   }
 
-  enum ChangeResult { NOT_CHANGED, MINOR_CHANGE, RENDERERS_CHANGED }
-  @NotNull
-  ChangeResult changeAttributesNoEvents(@NotNull Consumer<RangeHighlighterEx> change) {
+  @ChangeStatus
+  byte changeAttributesNoEvents(@NotNull Consumer<RangeHighlighterEx> change) {
     assert !isFlagSet(IN_BATCH_CHANGE_MASK);
     assert !isFlagSet(CHANGED_MASK);
     setFlag(IN_BATCH_CHANGE_MASK, true);
     setFlag(RENDERERS_CHANGED_MASK, false);
-    ChangeResult result;
+    setFlag(FONT_STYLE_CHANGED_MASK, false);
+    byte result = 0;
     try {
       change.consume(this);
     }
     finally {
       setFlag(IN_BATCH_CHANGE_MASK, false);
-      boolean changed = isFlagSet(CHANGED_MASK);
-      boolean renderersChanged = isFlagSet(RENDERERS_CHANGED_MASK);
-      result = changed ? renderersChanged ? ChangeResult.RENDERERS_CHANGED : ChangeResult.MINOR_CHANGE : ChangeResult.NOT_CHANGED;
+      if (isFlagSet(CHANGED_MASK)) {
+        result |= CHANGED_MASK;
+        if (isFlagSet(RENDERERS_CHANGED_MASK)) result |= RENDERERS_CHANGED_MASK;
+        if (isFlagSet(FONT_STYLE_CHANGED_MASK)) result |= FONT_STYLE_CHANGED_MASK;
+      }
       setFlag(CHANGED_MASK, false);
       setFlag(RENDERERS_CHANGED_MASK, false);
+      setFlag(FONT_STYLE_CHANGED_MASK, false);
     }
     return result;
   }
@@ -330,7 +341,7 @@ class RangeHighlighterImpl extends RangeMarkerImpl implements RangeHighlighterEx
     LineSeparatorRenderer old = myLineSeparatorRenderer;
     myLineSeparatorRenderer = renderer;
     if (!Comparing.equal(old, renderer)) {
-      fireChanged(true);
+      fireChanged(true, false);
     }
   }
 
index 83368bfd228ad953618c56b6c5de09e051bed7a7..f938717a65e43d3989aa3165e2dfc5ccc33c7397 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -27,7 +27,7 @@ public interface MarkupModelListener extends EventListener {
 
   void beforeRemoved(@NotNull RangeHighlighterEx highlighter);
 
-  void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged);
+  void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged);
 
   abstract class Adapter implements MarkupModelListener {
     @Override
@@ -39,7 +39,7 @@ public interface MarkupModelListener extends EventListener {
     }
 
     @Override
-    public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
+    public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
     }
   }
 }
index ced75119175d55646db4856a7ac929d5d96ace25..b86edbedbe1fdf5ef572fa919ed4acabe9401bf1 100644 (file)
@@ -21,7 +21,6 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Key;
 import com.intellij.psi.PsiElement;
 import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public interface ExpressionContext {
@@ -37,11 +36,5 @@ public interface ExpressionContext {
   <T> T getProperty(Key<T> key);
   @Nullable
   PsiElement getPsiElementAtStartOffset();
-
-  /**
-   * @return all template context types matching the template invocation place
-   */
-  @NotNull
-  TemplateContextType[] getCompatibleContexts();
 }
 
index 11e7957f3da1638ae659fa426e2faa6f475e15b1..c9309c443859c2ffa16bb99a476fff3c0f4f7ada 100644 (file)
@@ -25,6 +25,7 @@ import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.ui.CheckBoxList;
 import com.intellij.ui.SeparatorWithText;
 import com.intellij.util.Function;
@@ -40,7 +41,6 @@ import javax.swing.*;
 import java.awt.*;
 import java.util.*;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * @author Dmitry Avdeev
@@ -79,25 +79,21 @@ public class GutterIconsConfigurable implements Configurable, Configurable.NoScr
         }
       };
     MultiMap<PluginDescriptor, LanguageExtensionPoint<LineMarkerProvider>> map = ContainerUtil.groupBy(Arrays.asList(extensions), function);
+    Map<GutterIconDescriptor, PluginDescriptor> pluginDescriptorMap = ContainerUtil.newHashMap();
     myDescriptors = new ArrayList<GutterIconDescriptor>();
     for (final PluginDescriptor descriptor : map.keySet()) {
       Collection<LanguageExtensionPoint<LineMarkerProvider>> points = map.get(descriptor);
-      final AtomicBoolean first = new AtomicBoolean(true);
       for (LanguageExtensionPoint<LineMarkerProvider> extensionPoint : points) {
         GutterIconDescriptor instance = (GutterIconDescriptor)extensionPoint.getInstance();
         if (instance.getOptions().length > 0) {
           for (GutterIconDescriptor option : instance.getOptions()) {
-            if (first.getAndSet(false)) {
-              myFirstDescriptors.put(instance, descriptor);
-            }
             myDescriptors.add(option);
+            pluginDescriptorMap.put(option, descriptor);
           }
         }
         else {
-          if (first.getAndSet(false)) {
-            myFirstDescriptors.put(instance, descriptor);
-          }
           myDescriptors.add(instance);
+          pluginDescriptorMap.put(instance, descriptor);
         }
       }
     }
@@ -110,6 +106,22 @@ public class GutterIconsConfigurable implements Configurable, Configurable.NoScr
       }
     }
     myDescriptors.addAll(options);
+    myDescriptors.sort(new Comparator<GutterIconDescriptor>() {
+      @Override
+      public int compare(GutterIconDescriptor o1, GutterIconDescriptor o2) {
+        if (pluginDescriptorMap.get(o1) != pluginDescriptorMap.get(o2)) return 0;
+        return Comparing.compare(o1.getName(), o2.getName());
+      }
+    });
+    PluginDescriptor current = null;
+    for (GutterIconDescriptor descriptor : myDescriptors) {
+      PluginDescriptor pluginDescriptor = pluginDescriptorMap.get(descriptor);
+      if (pluginDescriptor != current) {
+        myFirstDescriptors.put(descriptor, pluginDescriptor);
+        current = pluginDescriptor;
+      }
+    }
+
     myList.setItems(myDescriptors, new Function<GutterIconDescriptor, String>() {
       @Override
       public String fun(GutterIconDescriptor descriptor) {
index 8825e7de0501bae5a337c12021112ca066c23090..01f07c96297c9f6f8c980c565875ac211a84e535 100644 (file)
@@ -59,9 +59,24 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
+@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
 public class TargetElementUtil extends TargetElementUtilBase {
+  /**
+   * A flag used in {@link #findTargetElement(Editor, int, int)} indicating that if a reference is found at the specified offset,
+   * it should be resolved and the result returned.
+   */
   public static final int REFERENCED_ELEMENT_ACCEPTED = 0x01;
+
+  /**
+   * A flag used in {@link #findTargetElement(Editor, int, int)} indicating that if a element declaration name (e.g. class name identifier)
+   * is found at the specified offset, the declared element should be returned.
+   */
   public static final int ELEMENT_NAME_ACCEPTED = 0x02;
+
+  /**
+   * A flag used in {@link #findTargetElement(Editor, int, int)} indicating that if a lookup (e.g. completion) is shown in the editor,
+   * the PSI element corresponding to the selected lookup item should be returned.
+   */
   public static final int LOOKUP_ITEM_ACCEPTED = 0x08;
 
   public static TargetElementUtil getInstance() {
@@ -163,6 +178,14 @@ public class TargetElementUtil extends TargetElementUtilBase {
            && EditorUtil.inVirtualSpace(editor, editor.getCaretModel().getLogicalPosition());
   }
 
+  /**
+   * Note: this method can perform slow PSI activity (e.g. {@link PsiReference#resolve()}, so please avoid calling it from Swing thread.
+   * @param editor editor
+   * @param flags a combination of {@link #REFERENCED_ELEMENT_ACCEPTED}, {@link #ELEMENT_NAME_ACCEPTED}, {@link #LOOKUP_ITEM_ACCEPTED}
+   * @return a PSI element declared or referenced at the editor caret position, or selected in the {@link Lookup} if shown in the editor,
+   * depending on the flags passed.
+   * @see #findTargetElement(Editor, int, int)
+   */
   @Nullable
   public static PsiElement findTargetElement(Editor editor, int flags) {
     ApplicationManager.getApplication().assertIsDispatchThread();
@@ -178,6 +201,15 @@ public class TargetElementUtil extends TargetElementUtilBase {
     return null;
   }
 
+  /**
+   * Note: this method can perform slow PSI activity (e.g. {@link PsiReference#resolve()}, so please avoid calling it from Swing thread.
+   * @param editor editor
+   * @param flags a combination of {@link #REFERENCED_ELEMENT_ACCEPTED}, {@link #ELEMENT_NAME_ACCEPTED}, {@link #LOOKUP_ITEM_ACCEPTED}
+   * @param offset offset in the editor's document           f? yt jlby dfh
+   * @return a PSI element declared or referenced at the specified offset in the editor, or selected in the {@link Lookup} if shown in the editor,
+   * depending on the flags passed.
+   * @see #findTargetElement(Editor, int)
+   */
   @Override
   @Nullable
   public PsiElement findTargetElement(@NotNull Editor editor, int flags, int offset) {
index d4da9aca64b4c20ef5c84f67765cc58aea2ed9e4..91555d8e48f85c0d47d91c730f8c242746db8362 100644 (file)
@@ -392,6 +392,9 @@ public class CtrlMouseHandler extends AbstractProjectComponent {
     private static TextRange getReferenceRange(@NotNull PsiElement elementAtPointer) {
       int textOffset = elementAtPointer.getTextOffset();
       final TextRange range = elementAtPointer.getTextRange();
+      if (range == null) {
+        throw new AssertionError("Null range for " + elementAtPointer + " of " + elementAtPointer.getClass());
+      }
       if (textOffset < range.getStartOffset() || textOffset < 0) {
         LOG.error("Invalid text offset " + textOffset + " of element " + elementAtPointer + " of " + elementAtPointer.getClass());
         textOffset = range.getStartOffset();
index b11356ad04268d0e7428fcc024b5528837f9c810..945830bb103152cb77711ea15fc362841bd3cef9 100644 (file)
@@ -21,49 +21,39 @@ import com.intellij.codeInsight.template.*;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Predicate;
 
 public class MacroCallNode extends Expression {
-  private final List<Macro> myMacros;
+  private final Macro myMacro;
   private final ArrayList<Expression> myParameters = new ArrayList<>();
 
   public MacroCallNode(@NotNull Macro macro) {
-    this(Collections.singletonList(macro));
-  }
-
-  public MacroCallNode(List<Macro> macros) {
-    myMacros = macros;
-    assert macros.size() > 0;
+    myMacro = macro;
   }
 
   public void addParameter(Expression node) {
     myParameters.add(node);
   }
 
-  public Macro getMacro(TemplateContextType[] context) {
-    Predicate<Macro> isAcceptableInContext = macro -> Arrays.stream(context).anyMatch(macro::isAcceptableInContext);
-    return myMacros.stream().filter(isAcceptableInContext).findFirst().orElse(myMacros.get(0));
+  public Macro getMacro() {
+    return myMacro;
   }
 
   @Override
   public Result calculateResult(ExpressionContext context) {
     Expression[] parameters = myParameters.toArray(new Expression[myParameters.size()]);
-    return getMacro(context.getCompatibleContexts()).calculateResult(parameters, context);
+    return getMacro().calculateResult(parameters, context);
   }
 
   @Override
   public Result calculateQuickResult(ExpressionContext context) {
     Expression[] parameters = myParameters.toArray(new Expression[myParameters.size()]);
-    return getMacro(context.getCompatibleContexts()).calculateQuickResult(parameters, context);
+    return getMacro().calculateQuickResult(parameters, context);
   }
 
   @Override
   public LookupElement[] calculateLookupItems(ExpressionContext context) {
     Expression[] parameters = myParameters.toArray(new Expression[myParameters.size()]);
-    return getMacro(context.getCompatibleContexts()).calculateLookupItems(parameters, context);
+    return getMacro().calculateLookupItems(parameters, context);
   }
 
   public Expression[] getParameters() {
index d6f0ac72b766e8c1d42dcfb9650d09a66dd06ec3..c7d9e73583c011fecc7639e900127793946d7d5c 100644 (file)
@@ -84,7 +84,7 @@ public class MacroParser {
     }
 
     advance(lexer);
-    MacroCallNode macroCallNode = new MacroCallNode(macros);
+    MacroCallNode macroCallNode = new MacroCallNode(macros.get(0));
     if (lexer.getTokenType() == null) {
       return macroCallNode;
     }
index c64329f0e1c4b72f4694a6bf6c9ab228dfcac503..bf2f53af636055d201a0eb88574dbd278e3aee2d 100644 (file)
@@ -99,19 +99,11 @@ public class TemplateState implements Disposable {
   @Nullable private PairProcessor<String, String> myProcessor;
   private boolean mySelectionCalculated = false;
   private boolean myStarted;
-  private final TemplateContextType[] myCompatibleContexts;
 
   TemplateState(@NotNull Project project, @NotNull final Editor editor) {
     myProject = project;
     myEditor = editor;
     myDocument = myEditor.getDocument();
-
-    PsiFile file = getPsiFile();
-    if (file != null) {
-      myCompatibleContexts = TemplateManagerImpl.getApplicableContextTypes(file, editor.getCaretModel().getOffset()).toArray(new TemplateContextType[0]);
-    } else {
-      myCompatibleContexts = new TemplateContextType[0];
-    }
   }
 
   private void initListeners() {
@@ -935,12 +927,6 @@ public class TemplateState implements Disposable {
         PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
         return file == null ? null : file.findElementAt(offset);
       }
-
-      @NotNull
-      @Override
-      public TemplateContextType[] getCompatibleContexts() {
-        return myCompatibleContexts;
-      }
     };
   }
 
@@ -1085,7 +1071,7 @@ public class TemplateState implements Disposable {
           Expression e = myTemplate.getExpressionAt(j);
           @NonNls String marker = "a";
           if (e instanceof MacroCallNode) {
-            marker = ((MacroCallNode)e).getMacro(myCompatibleContexts).getDefaultValue();
+            marker = ((MacroCallNode)e).getMacro().getDefaultValue();
           }
           replaceString(marker, mySegments.getSegmentStart(i), mySegments.getSegmentEnd(i), i);
           indices.add(i);
index 7369956b960db0d206e29574021424312b252926..16e0280a205f18a5818cf6e56513d117cac4a67e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -43,7 +43,10 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.OrderEntry;
 import com.intellij.openapi.roots.OrderRootType;
 import com.intellij.openapi.roots.ProjectFileIndex;
-import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Conditions;
+import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.*;
@@ -202,13 +205,7 @@ public class FindInProjectUtil {
       pattern = PatternUtil.convertToRegex(filter.trim());
     }
     else {
-      pattern = StringUtil.join(strings, new Function<String, String>() {
-        @NotNull
-        @Override
-        public String fun(@NotNull String s) {
-          return "(" + PatternUtil.convertToRegex(s.trim()) + ")";
-        }
-      }, "|");
+      pattern = StringUtil.join(strings, s -> "(" + PatternUtil.convertToRegex(s.trim()) + ")", "|");
     }
     return Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
   }
@@ -228,7 +225,7 @@ public class FindInProjectUtil {
                                 @NotNull final Project project,
                                 @NotNull final Processor<UsageInfo> consumer,
                                 @NotNull FindUsagesProcessPresentation processPresentation) {
-    findUsages(findModel, project, consumer, processPresentation, Collections.<VirtualFile>emptySet());
+    findUsages(findModel, project, consumer, processPresentation, Collections.emptySet());
   }
 
   public static void findUsages(@NotNull FindModel findModel,
@@ -244,12 +241,7 @@ public class FindInProjectUtil {
                                  @NotNull final FindModel findModel,
                                  @NotNull final Processor<UsageInfo> consumer) {
     if (findModel.getStringToFind().isEmpty()) {
-      if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
-              @Override
-              public Boolean compute() {
-                return consumer.process(new UsageInfo(psiFile));
-              }
-            })) {
+      if (!ApplicationManager.getApplication().runReadAction((Computable<Boolean>)() -> consumer.process(new UsageInfo(psiFile)))) {
         throw new ProcessCanceledException();
       }
       return 1;
@@ -257,12 +249,8 @@ public class FindInProjectUtil {
     final VirtualFile virtualFile = psiFile.getVirtualFile();
     if (virtualFile == null) return 0;
     if (virtualFile.getFileType().isBinary()) return 0; // do not decompile .class files
-    final Document document = ApplicationManager.getApplication().runReadAction(new Computable<Document>() {
-      @Override
-      public Document compute() {
-        return virtualFile.isValid() ? FileDocumentManager.getInstance().getDocument(virtualFile) : null;
-      }
-    });
+    final Document document = ApplicationManager.getApplication().runReadAction(
+      (Computable<Document>)() -> virtualFile.isValid() ? FileDocumentManager.getInstance().getDocument(virtualFile) : null);
     if (document == null) return 0;
     final int[] offset = {0};
     int count = 0;
@@ -271,13 +259,9 @@ public class FindInProjectUtil {
     TooManyUsagesStatus tooManyUsagesStatus = TooManyUsagesStatus.getFrom(indicator);
     do {
       tooManyUsagesStatus.pauseProcessingIfTooManyUsages(); // wait for user out of read action
-      found = ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
-        @Override
-        @NotNull
-        public Integer compute() {
-          if (!psiFile.isValid()) return 0;
-          return addToUsages(document, consumer, findModel, psiFile, offset, USAGES_PER_READ_ACTION);
-        }
+      found = ApplicationManager.getApplication().runReadAction((Computable<Integer>)() -> {
+        if (!psiFile.isValid()) return 0;
+        return addToUsages(document, consumer, findModel, psiFile, offset, USAGES_PER_READ_ACTION);
       });
       count += found;
     }
@@ -389,13 +373,7 @@ public class FindInProjectUtil {
     processPresentation.setShowNotFoundMessage(true);
     processPresentation.setShowPanelIfOnlyOneUsage(showPanelIfOnlyOneUsage);
     processPresentation.setProgressIndicatorFactory(
-      new Factory<ProgressIndicator>() {
-        @NotNull
-        @Override
-        public ProgressIndicator create() {
-          return new FindProgressIndicator(project, presentation.getScopeText());
-        }
-      }
+      () -> new FindProgressIndicator(project, presentation.getScopeText())
     );
     return processPresentation;
   }
@@ -410,14 +388,15 @@ public class FindInProjectUtil {
       if (grandChildren.length != 1) return Collections.emptyList(); // a | b, more than one branch, can not predict in current way
 
       for(PsiElement grandGrandChild:grandChildren[0].getChildren()) {
-        if (result == null) result = new ArrayList<PsiElement>();
+        if (result == null) result = new ArrayList<>();
         result.add(grandGrandChild);
       }
     }
     return result != null ? result : Collections.<PsiElement>emptyList();
   }
 
-  public static @NotNull String buildStringToFindForIndicesFromRegExp(@NotNull String stringToFind, @NotNull Project project) {
+  @NotNull
+  public static String buildStringToFindForIndicesFromRegExp(@NotNull String stringToFind, @NotNull Project project) {
     if (!Registry.is("idea.regexp.search.uses.indices")) return "";
 
     final AccessToken accessToken = ReadAction.start();
@@ -549,16 +528,14 @@ public class FindInProjectUtil {
   }
 
   private static void addSourceDirectoriesFromLibraries(@NotNull Project project,
-                                                        @NotNull VirtualFile file,
+                                                        @NotNull VirtualFile directory,
                                                         @NotNull Collection<VirtualFile> outSourceRoots) {
     ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
-    // if we already are in the sources, search just in this directory only
-    if (index.isInLibrarySource(file)) return;
-    VirtualFile classRoot = index.getClassRootForFile(file);
+    VirtualFile classRoot = index.getClassRootForFile(directory);
     if (classRoot == null) return;
-    String relativePath = VfsUtilCore.getRelativePath(file, classRoot);
+    String relativePath = VfsUtilCore.getRelativePath(directory, classRoot);
     if (relativePath == null) return;
-    for (OrderEntry orderEntry : index.getOrderEntriesForFile(file)) {
+    for (OrderEntry orderEntry : index.getOrderEntriesForFile(directory)) {
       for (VirtualFile sourceRoot : orderEntry.getFiles(OrderRootType.SOURCES)) {
         VirtualFile sourceFile = sourceRoot.findFileByRelativePath(relativePath);
         if (sourceFile != null) {
@@ -586,7 +563,7 @@ public class FindInProjectUtil {
   private static GlobalSearchScope forDirectory(@NotNull Project project,
                                                 boolean withSubdirectories,
                                                 @NotNull VirtualFile directory) {
-    Set<VirtualFile> result = new LinkedHashSet<VirtualFile>();
+    Set<VirtualFile> result = new LinkedHashSet<>();
     result.add(directory);
     addSourceDirectoriesFromLibraries(project, directory, result);
     VirtualFile[] array = result.toArray(new VirtualFile[result.size()]);
index 8543d6aaca65ba6231a26e0d861f1c3df6da958b..82f6926922c87f80f02200c64087dfddfef150bc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -331,7 +331,7 @@ public class MultiHostRegistrarImpl implements MultiHostRegistrar, ModificationT
     }
 
     psiFile.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, pointer);
-    PsiDocumentManagerBase.cachePsi(documentWindow, psiFile);
+    ((PsiDocumentManagerBase)PsiDocumentManager.getInstance(psiFile.getProject())).cachePsi(documentWindow, psiFile);
 
     keepTreeFromChameleoningBack(psiFile);
 
index dbeff3213c4a8513467cdde007165ed357058a07..d842e274cf7d1ddca07aa55f38a16794cc0358de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
  */
 package com.intellij.internal.focus;
 
+import com.intellij.execution.filters.TextConsoleBuilderFactory;
+import com.intellij.execution.ui.ConsoleView;
+import com.intellij.execution.ui.ConsoleViewContentType;
 import com.intellij.openapi.ide.CopyPasteManager;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.wm.impl.FocusRequestInfo;
 import com.intellij.ui.JBColor;
@@ -41,10 +45,10 @@ import java.util.List;
  * @author Konstantin Bulenkov
  */
 public class FocusTracesDialog extends DialogWrapper {
-  private final JTextPane myStacktrace = new JTextPane();
   private final JBTable myRequestsTable;
   private final List<FocusRequestInfo> myRequests;
   private static final String[] COLUMNS = {"Time", "Forced", "Component"};
+  private final ConsoleView consoleView;
 
   public FocusTracesDialog(Project project, ArrayList<FocusRequestInfo> requests) {
     super(project);
@@ -65,13 +69,11 @@ public class FocusTracesDialog extends DialogWrapper {
     final ListSelectionListener selectionListener = new ListSelectionListener() {
       @Override
       public void valueChanged(ListSelectionEvent e) {
+        if (consoleView == null) return;
         final int index = myRequestsTable.getSelectedRow();
+        consoleView.clear();
         if (-1 < index && index < myRequests.size()) {
-          myStacktrace.setText(myRequests.get(index).getStackTrace());
-          myStacktrace.setCaretPosition(0);
-        }
-        else {
-          myStacktrace.setText("");
+          consoleView.print(myRequests.get(index).getStackTrace(), ConsoleViewContentType.NORMAL_OUTPUT);
         }
       }
     };
@@ -85,6 +87,9 @@ public class FocusTracesDialog extends DialogWrapper {
     columnModel.getColumn(1).setPreferredWidth(60);
     myRequestsTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     myRequestsTable.changeSelection(0, 0, false, true);
+
+    consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(ProjectManager.getInstance().getDefaultProject()).getConsole();
+
     init();
   }
 
@@ -98,8 +103,13 @@ public class FocusTracesDialog extends DialogWrapper {
     JPanel panel = new JPanel(new BorderLayout());
     JBSplitter splitter = new JBSplitter(true, .5F, .2F, .8F);
     splitter.setFirstComponent(new JBScrollPane(myRequestsTable, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
+
+    final JComponent consoleComponent = new JPanel(new BorderLayout());
+    consoleComponent.add(consoleView.getComponent(), BorderLayout.CENTER);
+    consoleView.print(myRequests.get(myRequestsTable.getSelectedRow()).getStackTrace(), ConsoleViewContentType.NORMAL_OUTPUT);
+
     splitter.setSecondComponent(
-      new JBScrollPane(myStacktrace, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
+      new JBScrollPane(consoleComponent, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
     panel.add(splitter, BorderLayout.CENTER);
     return panel;
   }
@@ -119,7 +129,7 @@ public class FocusTracesDialog extends DialogWrapper {
     return new AbstractAction("&Copy stacktrace") {
       @Override
       public void actionPerformed(ActionEvent e) {
-        CopyPasteManager.getInstance().setContents(new StringSelection(myStacktrace.getText()));
+        CopyPasteManager.getInstance().setContents(new StringSelection(myRequests.get(myRequestsTable.getSelectedRow()).getStackTrace()));
       }
     };
   }
index f0eff59a45cc7507a46dbb081000269786d26dbc..d2b062a9257603ce9ea9fe1b7185f69726b23f71 100644 (file)
@@ -874,7 +874,7 @@ public class NotificationsManagerImpl extends NotificationsManager {
     private final JEditorPane myText;
     private final BalloonLayoutData myLayoutData;
     private Component myTitleComponent;
-    private Component myCenteredComponent;
+    private JScrollPane myCenteredComponent;
     private JPanel myActionPanel;
     private Component myExpandAction;
 
@@ -888,8 +888,8 @@ public class NotificationsManagerImpl extends NotificationsManager {
       if (myTitleComponent != null) {
         return myTitleComponent;
       }
-      if (myCenteredComponent instanceof JScrollPane) {
-        return ((JScrollPane)myCenteredComponent).getViewport().getView();
+      if (myCenteredComponent != null) {
+        return myCenteredComponent.getViewport().getView();
       }
       return null;
     }
@@ -900,7 +900,7 @@ public class NotificationsManagerImpl extends NotificationsManager {
         myTitleComponent = comp;
       }
       else if (BorderLayout.CENTER.equals(constraints)) {
-        myCenteredComponent = comp;
+        myCenteredComponent = (JScrollPane)comp;
       }
       else if (BorderLayout.SOUTH.equals(constraints)) {
         myActionPanel = (JPanel)comp;
@@ -989,6 +989,7 @@ public class NotificationsManagerImpl extends NotificationsManager {
 
       if (myCenteredComponent != null) {
         myCenteredComponent.setBounds(0, top, width, centeredSize.height);
+        myCenteredComponent.revalidate();
       }
 
       if (myExpandAction != null) {
@@ -996,10 +997,6 @@ public class NotificationsManagerImpl extends NotificationsManager {
         int x = width - size.width - myLayoutData.configuration.rightActionsOffset.width;
 
         if (myLayoutData.showMinSize) {
-          if (myText.getWidth() < 0 || myText.getHeight() < 0) {
-            myCenteredComponent.doLayout();
-            ((JScrollPane)myCenteredComponent).getViewport().doLayout();
-          }
           Point location = getCollapsedTextEndLocation(myText, myLayoutData);
           if (location != null) {
             int y = SwingUtilities.convertPoint(myText, location.x, location.y, parent).y;
index 1b6f1491c3589c4828812cc3eae1aeb6a894d6df..a0943b13cda6587d71755d05a51dc03ab93cad73 100644 (file)
@@ -19,7 +19,7 @@ import com.intellij.openapi.diff.impl.util.TextDiffType;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
-import com.intellij.openapi.editor.markup.LineMarkerRenderer;
+import com.intellij.openapi.editor.markup.LineMarkerRendererEx;
 import org.jetbrains.annotations.NotNull;
 
 import java.awt.*;
@@ -28,7 +28,7 @@ import java.awt.*;
  * <p>Draws the diff change highlighters on the editor's gutter.</p>
  * <p>Has ability to draw applied changes (used in the merge tool).</p>
  */
-public class DiffLineMarkerRenderer implements LineMarkerRenderer {
+public class DiffLineMarkerRenderer implements LineMarkerRendererEx {
 
   @NotNull private final TextDiffType myDiffType;
 
@@ -72,4 +72,8 @@ public class DiffLineMarkerRenderer implements LineMarkerRenderer {
     }
   }
 
+  @Override
+  public LineMarkerRendererEx.Position getPosition() {
+    return LineMarkerRendererEx.Position.CUSTOM;
+  }
 }
index f2ac5b7545cc36eea3d310b7a7830a568a8ee081..1839f3563b6304014a0b734239891716689055e4 100644 (file)
@@ -18,11 +18,10 @@ package com.intellij.openapi.diff.impl.highlighting;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.impl.EditorImpl;
-import com.intellij.openapi.editor.markup.LineMarkerRenderer;
+import com.intellij.openapi.editor.markup.LineMarkerRendererEx;
 import com.intellij.openapi.editor.markup.LineSeparatorRenderer;
 import com.intellij.openapi.util.Couple;
 import com.intellij.util.Consumer;
-import com.intellij.util.containers.Convertor;
 import com.intellij.util.ui.UIUtil;
 
 import java.awt.*;
@@ -36,7 +35,7 @@ import java.util.Random;
  *         Date: 7/6/11
  *         Time: 7:44 PM
  */
-public class FragmentBoundRenderer implements LineMarkerRenderer, LineSeparatorRenderer {
+public class FragmentBoundRenderer implements LineMarkerRendererEx, LineSeparatorRenderer {
   private final int myLineHeight;
   private final Editor myEditor;
   private final Consumer<Integer> myOffsetsConsumer;
@@ -64,7 +63,6 @@ public class FragmentBoundRenderer implements LineMarkerRenderer, LineSeparatorR
       ((Graphics2D) gr).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
       gr.setColor(getColor());
-      int y = r.y;
       final int width = ((EditorEx)editor).getGutterComponentEx().getWidth();
       final int editorWidth = editor.getScrollingModel().getVisibleArea().width;
       myShoeneLine.ensureLastX(editorWidth + width + width);
@@ -107,6 +105,11 @@ public class FragmentBoundRenderer implements LineMarkerRenderer, LineSeparatorR
     }
   }
 
+  @Override
+  public Position getPosition() {
+    return Position.CUSTOM;
+  }
+
   public Color getColor() {
     return myMainColor;
   }
index 393e4761d879c7eb1db323f91437bc07296e0d4a..f3d0a516e91c339b421ea38545b884308621f92e 100644 (file)
@@ -73,5 +73,7 @@ public abstract class EditorGutterComponentEx extends JComponent implements Edit
   
   public abstract void setPaintBackground(boolean value);
 
-  public abstract void setShowRightFreePaintersArea(boolean value);
+  public abstract void setForceShowLeftFreePaintersArea(boolean value);
+
+  public abstract void setForceShowRightFreePaintersArea(boolean value);
 }
index 03e687bd39c6dfe0cd14df75cd4a91d4bcb06edb..4ad7e498ccae68b96e44833388f629c5d168ef50 100644 (file)
@@ -106,7 +106,7 @@ public class EditorFactoryImpl extends EditorFactory implements ApplicationCompo
   @NonNls
   public static void throwNotReleasedError(@NotNull Editor editor) {
     if (editor instanceof EditorImpl) {
-      ((EditorImpl)editor).throwDisposalError("Editor of " + editor.getClass() + " hasn't been released:");
+      ((EditorImpl)editor).throwEditorNotDisposedError("Editor of " + editor.getClass() + " hasn't been released:");
     }
     else {
       throw new RuntimeException("Editor of " + editor.getClass() +
index a575fdfa786fe7c6357a19e9cd4a67380efe431d..eb89620cc9fbf588160cd2c50b3975dabb73489a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -128,8 +128,8 @@ public class EditorFilteringMarkupModelEx implements MarkupModelEx {
   }
 
   @Override
-  public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged) {
-    myDelegate.fireAttributesChanged(segmentHighlighter, renderersChanged);
+  public void fireAttributesChanged(@NotNull RangeHighlighterEx segmentHighlighter, boolean renderersChanged, boolean fontStyleChanged) {
+    myDelegate.fireAttributesChanged(segmentHighlighter, renderersChanged, fontStyleChanged);
   }
 
   @Override
index 0715e9f77a79d7247d5f6c533dc8a39ccaad32bc..50fa99244b900b0a2138163555b76621f5c99e1c 100644 (file)
@@ -58,10 +58,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;
@@ -146,7 +143,9 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
   private TIntObjectHashMap<Color> myTextFgColors = new TIntObjectHashMap<Color>();
   private boolean myPaintBackground = true;
   private boolean myLeftFreePaintersAreaShown;
-  private boolean myRightFreePaintersAreaShown = true;
+  private boolean myRightFreePaintersAreaShown;
+  private boolean myForceLeftFreePaintersAreaShown = false;
+  private boolean myForceRightFreePaintersAreaShown = false;
   private int myLastNonDumbModeIconAreaWidth = 0;
 
   @SuppressWarnings("unchecked")
@@ -308,7 +307,8 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
     int startX = myEditor.isInDistractionFreeMode() ? 0 : getWhitespaceSeparatorOffset() + (isFoldingOutlineShown() ? 1 : 0);
     if (myEditor.myUseNewRendering) {
       com.intellij.openapi.editor.impl.view.IterationState state =
-        new com.intellij.openapi.editor.impl.view.IterationState(myEditor, firstVisibleOffset, lastVisibleOffset, false, true, true, false);
+        new com.intellij.openapi.editor.impl.view.IterationState(myEditor, firstVisibleOffset, lastVisibleOffset, 
+                                                                 false, true, false, true, false);
       while (!state.atEnd()) {
         drawEditorBackgroundForRange(g, state.getStartOffset(), state.getEndOffset(), state.getMergedAttributes(),
                                      defaultBackgroundColor, defaultForegroundColor, startX);
@@ -716,18 +716,19 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
 
   private void calcLineMarkerAreaWidth() {
     myLineToGutterRenderers = new TIntObjectHashMap<List<GutterMark>>();
-    myLeftFreePaintersAreaShown = false;
+    myLeftFreePaintersAreaShown = myForceLeftFreePaintersAreaShown;
+    myRightFreePaintersAreaShown = myForceRightFreePaintersAreaShown;
 
     processRangeHighlighters(0, myEditor.getDocument().getTextLength(), new RangeHighlighterProcessor() {
       @Override
       public void process(@NotNull RangeHighlighter highlighter) {
         LineMarkerRenderer lineMarkerRenderer = highlighter.getLineMarkerRenderer();
-        if (lineMarkerRenderer instanceof LineMarkerRendererEx && 
-            ((LineMarkerRendererEx)lineMarkerRenderer).getPosition() == LineMarkerRendererEx.Position.LEFT && 
-            isLineMarkerVisible(highlighter)) {
-          myLeftFreePaintersAreaShown = true;
+        if (lineMarkerRenderer != null) {
+          LineMarkerRendererEx.Position position = getLineMarkerPosition(lineMarkerRenderer);
+          if (position == LineMarkerRendererEx.Position.LEFT && isLineMarkerVisible(highlighter)) myLeftFreePaintersAreaShown = true;
+          if (position == LineMarkerRendererEx.Position.RIGHT && isLineMarkerVisible(highlighter)) myRightFreePaintersAreaShown = true;
         }
-        
+
         GutterMark renderer = highlighter.getGutterIconRenderer();
         if (renderer == null) {
           return;
@@ -870,13 +871,29 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
       endY += myEditor.getLineHeight();
     }
 
-    LineMarkerRenderer renderer = highlighter.getLineMarkerRenderer();
-    boolean leftPosition = renderer instanceof LineMarkerRendererEx && 
-                           ((LineMarkerRendererEx)renderer).getPosition() == LineMarkerRendererEx.Position.LEFT;
+    LineMarkerRenderer renderer = ObjectUtils.assertNotNull(highlighter.getLineMarkerRenderer());
+    LineMarkerRendererEx.Position position = getLineMarkerPosition(renderer);
+
+    int w;
+    int x;
+    switch (position) {
+      case LEFT:
+        w = getLeftFreePaintersAreaWidth();
+        x = getLeftFreePaintersAreaOffset();
+        break;
+      case RIGHT:
+        w = getRightFreePaintersAreaWidth();
+        x = getLineMarkerFreePaintersAreaOffset() - 1;
+        break;
+      case CUSTOM:
+        w = getWidth();
+        x = 0;
+        break;
+      default:
+        throw new IllegalArgumentException(position.name());
+    }
 
     int height = endY - startY;
-    int w = leftPosition ? getLeftFreePaintersAreaWidth() : getRightFreePaintersAreaWidth();
-    int x = leftPosition ? getLeftFreePaintersAreaOffset() : getLineMarkerFreePaintersAreaOffset() - 1;
     return new Rectangle(x, startY, w, height);
   }
 
@@ -1684,8 +1701,13 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
   }
 
   @Override
-  public void setShowRightFreePaintersArea(boolean value) {
-    myRightFreePaintersAreaShown = value;
+  public void setForceShowLeftFreePaintersArea(boolean value) {
+    myForceLeftFreePaintersAreaShown = value;
+  }
+
+  @Override
+  public void setForceShowRightFreePaintersArea(boolean value) {
+    myForceRightFreePaintersAreaShown = value;
   }
 
   private void invokePopup(MouseEvent e) {
@@ -1807,6 +1829,14 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
     return (GutterIconRenderer)getGutterRenderer(e.getPoint());
   }
 
+  @NotNull
+  private static LineMarkerRendererEx.Position getLineMarkerPosition(@NotNull LineMarkerRenderer renderer) {
+    if (renderer instanceof LineMarkerRendererEx) {
+      return ((LineMarkerRendererEx)renderer).getPosition();
+    }
+    return LineMarkerRendererEx.Position.RIGHT;
+  }
+
   public int convertX(int x) {
     if (!isMirrored()) return x;
     return getWidth() - x;
index edc2c9414e604418ed6f0600a605aa0fb00094a4..cdc2d8b84778539e509092b7850ad52bb101eb66 100644 (file)
@@ -374,16 +374,16 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
       }
       @Override
       public void afterAdded(@NotNull RangeHighlighterEx highlighter) {
-        attributesChanged(highlighter, areRenderersInvolved(highlighter));
+        attributesChanged(highlighter, areRenderersInvolved(highlighter), false);
       }
 
       @Override
       public void beforeRemoved(@NotNull RangeHighlighterEx highlighter) {
-        attributesChanged(highlighter, areRenderersInvolved(highlighter));
+        attributesChanged(highlighter, areRenderersInvolved(highlighter), false);
       }
 
       @Override
-      public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged) {
+      public void attributesChanged(@NotNull RangeHighlighterEx highlighter, boolean renderersChanged, boolean fontStyleChanged) {
         if (myDocument.isInBulkUpdate()) return; // bulkUpdateFinished() will repaint anything
         
         if (myUseNewRendering && renderersChanged) {
@@ -408,7 +408,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
         int startLine = start == -1 ? 0 : myDocument.getLineNumber(start);
         int endLine = end == -1 ? myDocument.getLineCount() : myDocument.getLineNumber(end);
         TextAttributes attributes = highlighter.getTextAttributes();
-        if (myUseNewRendering && start != end && attributes != null && attributes.getFontType() != Font.PLAIN) {
+        if (myUseNewRendering && start != end && (fontStyleChanged || attributes != null && attributes.getFontType() != Font.PLAIN)) {
           myView.invalidateRange(start, end);
         }
         repaintLines(Math.max(0, startLine - 1), Math.min(endLine + 1, getDocument().getLineCount()));
@@ -857,6 +857,16 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     );
   }
 
+  /**
+   * To be called when editor was not disposed while it should
+   */
+  public void throwEditorNotDisposedError(@NonNls @NotNull final String msg) {
+    myTraceableDisposable.throwObjectNotDisposedError(msg);
+  }
+
+  /**
+   * In case of "editor not disposed error" use {@link #throwEditorNotDisposedError(String)}
+   */
   public void throwDisposalError(@NonNls @NotNull String msg) {
     myTraceableDisposable.throwDisposalError(msg);
   }
@@ -4675,13 +4685,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     private long mySleepTime = 500;
     private boolean myIsBlinkCaret = true;
     @Nullable private EditorImpl myEditor;
-    @NotNull private final MyRepaintRunnable myRepaintRunnable;
+    @NotNull private final MyRepaintRunnable myRepaintRunnable = new MyRepaintRunnable();
     private ScheduledFuture<?> mySchedulerHandle;
 
-    private RepaintCursorCommand() {
-      myRepaintRunnable = new MyRepaintRunnable();
-    }
-
     private class MyRepaintRunnable implements Runnable {
       @Override
       public void run() {
@@ -5497,7 +5503,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     for (RangeHighlighter highlighter : myDocumentMarkupModel.getDelegate().getAllHighlighters()) {
       boolean oldAvailable = oldFilter == null || oldFilter.value(highlighter);
       boolean newAvailable = filter == null || filter.value(highlighter);
-      if (oldAvailable != newAvailable) myMarkupModelListener.attributesChanged((RangeHighlighterEx)highlighter, true);
+      if (oldAvailable != newAvailable) myMarkupModelListener.attributesChanged((RangeHighlighterEx)highlighter, true, false);
     }
   }
 
index 6216f88f9fb28511658d2d20a7bdf9d9d5e44ae8..41e37df2f24e4bf81c703960f19679e95eda271a 100644 (file)
@@ -882,7 +882,7 @@ class EditorPainter implements TextDrawingCallback {
         SoftWrap softWrap = myEditor.getSoftWrapModel().getSoftWrap(offset);
         if (softWrap != null) {
           prevEndOffset = offset;
-          it = new IterationState(myEditor, offset == 0 ? 0 : offset - 1, visualLineEndOffset, true, false, false, false);
+          it = new IterationState(myEditor, offset == 0 ? 0 : offset - 1, visualLineEndOffset, true, false, false, false, false);
           if (it.getEndOffset() <= offset) {
             it.advance();
           }
@@ -895,7 +895,8 @@ class EditorPainter implements TextDrawingCallback {
       FoldRegion foldRegion = fragment.getCurrentFoldRegion();
       if (foldRegion == null) {
         if (start != prevEndOffset) {
-          it = new IterationState(myEditor, start, fragment.isRtl() ? offset : visualLineEndOffset, true, false, false, fragment.isRtl());
+          it = new IterationState(myEditor, start, fragment.isRtl() ? offset : visualLineEndOffset, 
+                                  true, false, false, false, fragment.isRtl());
         }
         prevEndOffset = end;
         assert it != null;
@@ -920,8 +921,8 @@ class EditorPainter implements TextDrawingCallback {
       else {
         float xNew = fragment.getEndX();
         if (xNew >= clip.getMinX()) {
-          painter.paint(g, fragment, 0, fragment.getEndVisualColumn() - fragment.getStartVisualColumn(), getFoldRegionAttributes(foldRegion), 
-                        x, xNew, y);
+          painter.paint(g, fragment, 0, fragment.getEndVisualColumn() - fragment.getStartVisualColumn(), 
+                        getFoldRegionAttributes(foldRegion), x, xNew, y);
         }
         x = xNew;
         prevEndOffset = -1;
@@ -932,7 +933,7 @@ class EditorPainter implements TextDrawingCallback {
     }
     if (it == null || it.getEndOffset() != visualLineEndOffset) {
       it = new IterationState(myEditor, visualLineEndOffset == offset ? visualLineEndOffset : visualLineEndOffset - 1, visualLineEndOffset, 
-                              true, false, false, false);
+                              true, false, false, false, false);
     }
     if (!it.atEnd()) {
       it.advance();
index 250cd97483ca033106403252b66421038e06a5ca..139fc74e54e93b28de40605a1a0b7abaa437da68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -131,7 +131,7 @@ public class IterationState {
   private final boolean myReverseIteration;
 
   public IterationState(@NotNull EditorEx editor, int start, int end, boolean useCaretAndSelection, boolean useOnlyFullLineHighlighters,
-                        boolean useFoldRegions, boolean iterateBackwards) {
+                        boolean useOnlyFontAffectingHighlighters, boolean useFoldRegions, boolean iterateBackwards) {
     ApplicationManager.getApplication().assertReadAccessAllowed();
     myDocument = editor.getDocument();
     myStartOffset = start;
@@ -184,10 +184,10 @@ public class IterationState {
     myCaretRowEndsWithSoftWrap = editor.getSoftWrapModel().getSoftWrap(myCaretRowEnd) != null;
 
     MarkupModelEx editorMarkup = editor.getMarkupModel();
-    myView = new HighlighterSweep(editorMarkup, start, myEnd, useOnlyFullLineHighlighters);
+    myView = new HighlighterSweep(editorMarkup, start, myEnd, useOnlyFullLineHighlighters, useOnlyFontAffectingHighlighters);
 
     MarkupModelEx docMarkup = editor.getFilteredDocumentMarkupModel();
-    myDoc = new HighlighterSweep(docMarkup, start, myEnd, useOnlyFullLineHighlighters);
+    myDoc = new HighlighterSweep(docMarkup, start, myEnd, useOnlyFullLineHighlighters, useOnlyFontAffectingHighlighters);
 
     myEndOffset = myStartOffset;
 
@@ -199,16 +199,20 @@ public class IterationState {
     int i;
     private final RangeHighlighterEx[] highlighters;
 
-    private HighlighterSweep(@NotNull MarkupModelEx markupModel, int start, int end, final boolean onlyFullLine) {
+    private HighlighterSweep(@NotNull MarkupModelEx markupModel, int start, int end, 
+                             final boolean onlyFullLine, final boolean onlyFontAffecting) {
       // we have to get all highlighters in advance and sort them by affected offsets
       // since these can be different from the real offsets the highlighters are sorted by in the tree.  (See LINES_IN_RANGE perverts)
       final List<RangeHighlighterEx> list = new ArrayList<RangeHighlighterEx>();
-      markupModel.processRangeHighlightersOverlappingWith(myReverseIteration ? end : start, 
-                                                          myReverseIteration ? start : end,
+      markupModel.processRangeHighlightersOverlappingWith(myReverseIteration ? end : start, myReverseIteration ? start : end,
                                                           new CommonProcessors.CollectProcessor<RangeHighlighterEx>(list) {
                                                             @Override
                                                             protected boolean accept(RangeHighlighterEx ex) {
-                                                              return !onlyFullLine || ex.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE;
+                                                              return (!onlyFullLine || 
+                                                                      ex.getTargetArea() == HighlighterTargetArea.LINES_IN_RANGE) && 
+                                                                     (!onlyFontAffecting ||
+                                                                      ex.getTextAttributes() != null && 
+                                                                      ex.getTextAttributes().getFontType() != Font.PLAIN);
                                                             }
                                                           });
       highlighters = list.isEmpty() ? RangeHighlighterEx.EMPTY_ARRAY : list.toArray(new RangeHighlighterEx[list.size()]);
index 6316c0fa14f910926a9c8470a3a52ca71761f58c..277992723bf57bfd1508ea853016dbb00360ae6b 100644 (file)
@@ -523,7 +523,7 @@ abstract class LineLayout {
       int lineStartOffset = view.getEditor().getDocument().getLineStartOffset(line);
       int start = lineStartOffset + startOffset;
       int end = lineStartOffset + endOffset;
-      IterationState it = new IterationState(view.getEditor(), start, end, false, false, false, false);
+      IterationState it = new IterationState(view.getEditor(), start, end, false, false, true, false, false);
       FontPreferences fontPreferences = view.getEditor().getColorsScheme().getFontPreferences();
       char[] chars = CharArrayUtil.fromSequence(view.getEditor().getDocument().getImmutableCharSequence(), start, end);
       while (!it.atEnd()) {
index 51f830b56c439d7d45c23f4627a3eaf933de70f1..6d41e7904da27a7b4cedbebdb1aff4a91a39172a 100644 (file)
 package com.intellij.openapi.editor.markup;
 
 import com.intellij.openapi.editor.Editor;
+import org.jetbrains.annotations.NotNull;
 
 import java.awt.*;
 
 public interface LineMarkerRendererEx extends LineMarkerRenderer {
-  enum Position {LEFT, RIGHT}
+  enum Position {LEFT, RIGHT, CUSTOM}
   
   /**
-   * Determines whether line marker should be rendered to the left or to the right of icon area in gutter.
+   * Determines where in gutter the line marker should be rendered.
+   *
+   * LEFT - to the left of icon area
+   * RIGHT - to the right of icon area
+   * CUSTOM - over whole gutter area
+   * If renderer does not implement LineMarkerRendererEx the RIGHT position will be used.
+   *
    * Corresponding rectangle will be passed to renderer in {@link #paint(Editor, Graphics, Rectangle)} method.
    */
+  @NotNull
   Position getPosition();
 }
index 02423006fdc6281d667eed6b6182602116792293..7ca3f77835757418a73a493b06a832d1b15e31c1 100644 (file)
@@ -164,6 +164,8 @@ class TextEditorComponent extends JBLoadingPanel implements DataProvider {
   private Editor createEditor(){
     Editor editor = EditorFactory.getInstance().createEditor(myDocument, myProject);
     ((EditorMarkupModel) editor.getMarkupModel()).setErrorStripeVisible(true);
+    ((EditorEx) editor).getGutterComponentEx().setForceShowRightFreePaintersArea(true);
+
     EditorHighlighter highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(myFile, EditorColorsManager.getInstance().getGlobalScheme(), myProject);
     ((EditorEx) editor).setHighlighter(highlighter);
     ((EditorEx) editor).setFile(myFile);
index dd0a769eb0e8e35804c25a66df6d09aa0e33ec4b..6b13d79c10975bda2c1f0530e5d90248854c885d 100644 (file)
@@ -142,7 +142,7 @@ public class FrameWrapper implements Disposable, DataProvider {
     final WindowAdapter focusListener = new WindowAdapter() {
       public void windowOpened(WindowEvent e) {
         IdeFocusManager fm = IdeFocusManager.getInstance(myProject);
-        JComponent toFocus = myPreferedFocus;
+        JComponent toFocus = getPreferredFocusedComponent();
         if (toFocus == null) {
           toFocus = fm.getFocusTargetFor(myComponent);
         }
@@ -290,6 +290,10 @@ public class FrameWrapper implements Disposable, DataProvider {
     myPreferedFocus = preferedFocus;
   }
 
+  public JComponent getPreferredFocusedComponent() {
+    return myPreferedFocus;
+  }
+
   public void closeOnEsc() {
     myCloseOnEsc = true;
   }
index 3f30e572d6a01ef5f08e013e919d0276e5eed478..9dfb620ff3ea427f9737b4884256dc092313face 100644 (file)
@@ -2,8 +2,10 @@ package com.intellij.openapi.ui;
 
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.WindowWrapper.Mode;
+import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -19,7 +21,7 @@ public class WindowWrapperBuilder {
   @Nullable private Project myProject;
   @Nullable private Component myParent;
   @Nullable private String myTitle;
-  @Nullable private JComponent myPreferredFocusedComponent;
+  @Nullable private Computable<JComponent> myPreferredFocusedComponent;
   @Nullable private String myDimensionServiceKey;
   @Nullable private Runnable myOnShowCallback;
 
@@ -48,7 +50,13 @@ public class WindowWrapperBuilder {
 
   @NotNull
   public WindowWrapperBuilder setPreferredFocusedComponent(@Nullable JComponent preferredFocusedComponent) {
-    myPreferredFocusedComponent = preferredFocusedComponent;
+    myPreferredFocusedComponent = new Computable.PredefinedValueComputable<JComponent>(preferredFocusedComponent);
+    return this;
+  }
+
+  @NotNull
+  public WindowWrapperBuilder setPreferredFocusedComponent(@Nullable Computable<JComponent> computable) {
+    myPreferredFocusedComponent = computable;
     return this;
   }
 
@@ -77,6 +85,16 @@ public class WindowWrapperBuilder {
     }
   }
 
+  private static void installOnShowCallback(@Nullable Window window, @Nullable final Runnable onShowCallback) {
+    if (window == null || onShowCallback == null) return;
+    window.addWindowListener(new WindowAdapter() {
+      @Override
+      public void windowOpened(WindowEvent e) {
+        onShowCallback.run();
+      }
+    });
+  }
+
   private static class DialogWindowWrapper implements WindowWrapper {
     @Nullable private final Project myProject;
     @NotNull private final JComponent myComponent;
@@ -94,15 +112,7 @@ public class WindowWrapperBuilder {
                  : new MyDialogWrapper(builder.myProject, builder.myComponent);
       myDialog.setParameters(builder.myDimensionServiceKey, builder.myPreferredFocusedComponent);
 
-      final Runnable onShowCallback = builder.myOnShowCallback;
-      if (onShowCallback != null) {
-        myDialog.getWindow().addWindowListener(new WindowAdapter() {
-          @Override
-          public void windowOpened(WindowEvent e) {
-            onShowCallback.run();
-          }
-        });
-      }
+      installOnShowCallback(myDialog.getWindow(), builder.myOnShowCallback);
 
       setTitle(builder.myTitle);
       switch (builder.myMode) {
@@ -170,7 +180,7 @@ public class WindowWrapperBuilder {
     private static class MyDialogWrapper extends DialogWrapper {
       @NotNull private JComponent myComponent;
       @Nullable private String myDimensionServiceKey;
-      @Nullable private JComponent myPreferredFocusedComponent;
+      @Nullable private Computable<JComponent> myPreferredFocusedComponent;
 
       public MyDialogWrapper(@Nullable Project project, @NotNull JComponent component) {
         super(project, true);
@@ -183,7 +193,7 @@ public class WindowWrapperBuilder {
       }
 
       public void setParameters(@Nullable String dimensionServiceKey,
-                                @Nullable JComponent preferredFocusedComponent) {
+                                @Nullable Computable<JComponent> preferredFocusedComponent) {
         myDimensionServiceKey = dimensionServiceKey;
         myPreferredFocusedComponent = preferredFocusedComponent;
       }
@@ -221,7 +231,8 @@ public class WindowWrapperBuilder {
       @Nullable
       @Override
       public JComponent getPreferredFocusedComponent() {
-        return myPreferredFocusedComponent;
+        if (myPreferredFocusedComponent != null) return myPreferredFocusedComponent.compute();
+        return super.getPreferredFocusedComponent();
       }
     }
   }
@@ -232,7 +243,7 @@ public class WindowWrapperBuilder {
     @NotNull private final Mode myMode;
     @Nullable private final Runnable myOnShowCallback;
 
-    @NotNull private final FrameWrapper myFrame;
+    @NotNull private final MyFrameWrapper myFrame;
 
     public FrameWindowWrapper(@NotNull WindowWrapperBuilder builder) {
       assert builder.myMode == Mode.FRAME;
@@ -240,12 +251,13 @@ public class WindowWrapperBuilder {
       myProject = builder.myProject;
       myComponent = builder.myComponent;
       myMode = builder.myMode;
-      myOnShowCallback = builder.myOnShowCallback;
 
-      myFrame = new FrameWrapper(builder.myProject, builder.myDimensionServiceKey);
+      myFrame = new MyFrameWrapper(builder.myProject, builder.myDimensionServiceKey);
+      myFrame.setParameters(builder.myPreferredFocusedComponent);
+
+      myOnShowCallback = builder.myOnShowCallback;
 
       myFrame.setComponent(builder.myComponent);
-      myFrame.setPreferredFocusedComponent(builder.myPreferredFocusedComponent);
       myFrame.setTitle(builder.myTitle);
       myFrame.closeOnEsc();
       Disposer.register(myFrame, this);
@@ -305,5 +317,23 @@ public class WindowWrapperBuilder {
     public void dispose() {
       Disposer.dispose(myFrame);
     }
+
+    private static class MyFrameWrapper extends FrameWrapper {
+      private Computable<JComponent> myPreferredFocusedComponent;
+
+      public MyFrameWrapper(Project project, @Nullable @NonNls String dimensionServiceKey) {
+        super(project, dimensionServiceKey);
+      }
+
+      public void setParameters(@Nullable Computable<JComponent> preferredFocusedComponent) {
+        myPreferredFocusedComponent = preferredFocusedComponent;
+      }
+
+      @Override
+      public JComponent getPreferredFocusedComponent() {
+        if (myPreferredFocusedComponent != null) return myPreferredFocusedComponent.compute();
+        return super.getPreferredFocusedComponent();
+      }
+    }
   }
 }
index 3c0d740bf5a39e7da963cbc0099d6b6b9d7cf881..5f537dd09287439d13a870f41228327b2c8c366b 100644 (file)
@@ -43,7 +43,6 @@ import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import javax.swing.border.Border;
-import javax.swing.border.EmptyBorder;
 import java.awt.*;
 import java.awt.event.*;
 import java.util.Map;
@@ -276,7 +275,6 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr
     innerPanel.add(toolWindowComponent, BorderLayout.CENTER);
 
     final NonOpaquePanel inner = new NonOpaquePanel(innerPanel);
-    inner.setBorder(new EmptyBorder(-1, 0, 0, 0));
 
     contentPane.add(inner, BorderLayout.CENTER);
     add(contentPane, BorderLayout.CENTER);
index e47f44e76154b746280edf96ee681921b570ba15..75782dfeeb04bc73268067d31bc3cbc7e7fadef8 100644 (file)
@@ -22,8 +22,8 @@ AWSCloudFormation
 Dart
 IdeaVIM
 IDETalk
-Commander
+com.intellij.commander
 SourceSafe
 TFS
 ro.redeul.google.go
-LiveEdit
\ No newline at end of file
+com.intellij.plugins.html.instantEditing
\ No newline at end of file
index 24baa21f2ab37459d3d7c76f15072c9f5399e5cf..b53b17233e435f6f564cbccfc7e31f4ff346383b 100644 (file)
@@ -616,7 +616,7 @@ public class FileTypesTest extends PlatformTestCase {
     }
   }
 
-  public void testStressPlainTextFileWithEverIncreasingLength() throws IOException, InterruptedException {
+  public void _testStressPlainTextFileWithEverIncreasingLength() throws IOException, InterruptedException {
     FrequentEventDetector.disableUntil(myTestRootDisposable);
 
     String stillText = StringUtil.repeatSymbol(' ', (int)PersistentFSConstants.FILE_LENGTH_TO_CACHE_THRESHOLD);
@@ -682,7 +682,7 @@ public class FileTypesTest extends PlatformTestCase {
     if (exception.get() != null) throw new RuntimeException(exception.get());
   }
 
-  public void testStressPlainTextFileWithEverIncreasingLength2() throws IOException, InterruptedException {
+  public void _testStressPlainTextFileWithEverIncreasingLength2() throws IOException, InterruptedException {
     FrequentEventDetector.disableUntil(myTestRootDisposable);
 
     File f = createTempFile("xx.asdkjfhlkasjdhf", StringUtil.repeatSymbol(' ', (int)PersistentFSConstants.FILE_LENGTH_TO_CACHE_THRESHOLD - 100));
index 221806b98cedbd410cd5f2f2a4113fcd30e09232..d4047c346cf7f74d4ec146185975b0a5e7a51543 100644 (file)
@@ -69,7 +69,7 @@ public class TestModulePropertiesImpl extends TestModuleProperties implements Pe
 
   @Override
   public void loadState(TestModulePropertiesState state) {
-
+    setProductionModuleName(state.moduleName);
   }
 
   public static class TestModulePropertiesState {
index 47271ff63152cdd9198cc24fb5fdc0caede71fe2..72f6768cba322a48c29049de2002b99f70d49902 100644 (file)
@@ -18,6 +18,7 @@ package com.intellij.remoteServer.impl.runtime.ui;
 import com.intellij.ide.util.treeView.AbstractTreeNode;
 import com.intellij.openapi.project.Project;
 import com.intellij.remoteServer.configuration.RemoteServer;
+import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNodeSelector;
 import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
 import com.intellij.remoteServer.runtime.ServerConnection;
 import org.jetbrains.annotations.NotNull;
@@ -33,8 +34,8 @@ public abstract class RemoteServersViewContribution extends RemoteServersViewCon
     return !getRemoteServers().isEmpty();
   }
 
-  public ServersTreeStructure createTreeStructure(@NotNull final Project project) {
-    return new ServersTreeStructure(project, this);
+  public ServersTreeStructure createTreeStructure(@NotNull Project project, @NotNull ServersTreeNodeSelector nodeSelector) {
+    return new ServersTreeStructure(project, this, nodeSelector);
   }
 
   public TreeNodeSelector createLogNodeSelector(final ServerConnection<?> connection,
index 02925d01adf4df1fb95d4aa4a312532f2a3a42d8..f0a0ad2fea2e475fa84a88b495b36eeeba7fdeea 100644 (file)
@@ -13,6 +13,7 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Splitter;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Disposer;
+import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNodeSelector;
 import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure;
 import com.intellij.remoteServer.impl.runtime.ui.tree.TreeBuilderBase;
 import com.intellij.remoteServer.runtime.ConnectionStatus;
@@ -45,7 +46,7 @@ import java.util.Set;
 /**
  * @author michael.golubev
  */
-public class ServersToolWindowContent extends JPanel implements Disposable {
+public class ServersToolWindowContent extends JPanel implements Disposable, ServersTreeNodeSelector {
   public static final DataKey<ServersToolWindowContent> KEY = DataKey.create("serversToolWindowContent");
   @NonNls private static final String PLACE_TOOLBAR = "ServersToolWindowContent#Toolbar";
   @NonNls private static final String SERVERS_TOOL_WINDOW_TOOLBAR = "RemoteServersViewToolbar";
@@ -210,7 +211,7 @@ public class ServersToolWindowContent extends JPanel implements Disposable {
   }
 
   private void setupBuilder(final @NotNull Project project) {
-    ServersTreeStructure structure = myContribution.createTreeStructure(project);
+    ServersTreeStructure structure = myContribution.createTreeStructure(project, this);
     myBuilder = new TreeBuilderBase(myTree, structure, myTreeModel) {
       @Override
       protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) {
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeNodeSelector.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeNodeSelector.java
new file mode 100644 (file)
index 0000000..b270743
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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.remoteServer.impl.runtime.ui.tree;
+
+import com.intellij.remoteServer.runtime.ServerConnection;
+import org.jetbrains.annotations.NotNull;
+
+public interface ServersTreeNodeSelector {
+
+  void select(@NotNull ServerConnection<?> connection);
+
+  void select(@NotNull ServerConnection<?> connection, @NotNull String deploymentName);
+
+  void select(@NotNull ServerConnection<?> connection, @NotNull String deploymentName, @NotNull String logName);
+}
index 8a78c702171ebbffb4c28dabdfa7d751b34bec0c..f286fc96969d2f1a74c83190e4b063733cde609b 100644 (file)
@@ -61,14 +61,18 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
   private final ServersTreeRootNode myRootElement;
   private final Project myProject;
   private final RemoteServersViewContribution myContribution;
+  private final ServersTreeNodeSelector myNodeSelector;
 
   private final Map<RemoteServer, Map<String, DeploymentGroup>> myServer2DeploymentGroups
     = new HashMap<RemoteServer, Map<String, DeploymentGroup>>();
 
-  public ServersTreeStructure(@NotNull Project project, @NotNull RemoteServersViewContribution contribution) {
+  public ServersTreeStructure(@NotNull Project project,
+                              @NotNull RemoteServersViewContribution contribution,
+                              @NotNull ServersTreeNodeSelector nodeSelector) {
     super(project);
     myProject = project;
     myContribution = contribution;
+    myNodeSelector = nodeSelector;
     myRootElement = new ServersTreeRootNode();
   }
 
@@ -98,6 +102,10 @@ public class ServersTreeStructure extends AbstractTreeStructureBase {
     return myRootElement;
   }
 
+  protected ServersTreeNodeSelector getNodeSelector() {
+    return myNodeSelector;
+  }
+
   @Override
   public void commit() {
   }
index 39c6d1559d638db65f86c08a7eecd66be8a05230..2dc838c1a7d7483522c11637cccc1893c2fb3d97 100644 (file)
@@ -16,6 +16,7 @@
 package com.intellij.openapi.util;
 
 import com.intellij.openapi.util.objectTree.ThrowableInterner;
+import com.intellij.openapi.util.text.StringUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -23,6 +24,9 @@ import org.jetbrains.annotations.Nullable;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Traces creation and disposal by storing corresponding stacktraces.
@@ -49,12 +53,38 @@ public class TraceableDisposable {
     }
   }
 
+  /**
+   * Call when object is not disposed while it should
+   */
+  public void throwObjectNotDisposedError(@NonNls @NotNull final String msg) {
+    throw new ObjectNotDisposedException(msg);
+  }
+
+  private class ObjectNotDisposedException extends AbstractDisposalException {
+
+    ObjectNotDisposedException(@Nullable @NonNls final String msg) {
+      super(msg);
+    }
+
+
+    @SuppressWarnings("HardCodedStringLiteral")
+    @Override
+    public void printStackTrace(PrintWriter s) {
+      final List<StackTraceElement> stack = new ArrayList<StackTraceElement>(Arrays.asList(CREATE_TRACE.getStackTrace()));
+      stack.remove(0); // this line is useless it stack
+     s.write(ObjectNotDisposedException.class.getCanonicalName() + ": See stack trace responsible for creation of unreleased object below \n\tat " + StringUtil.join(stack, "\n\tat "));
+    }
+  }
+
+  /**
+   * in case of "object not disposed" use {@link #throwObjectNotDisposedError(String)} instead
+   */
   public void throwDisposalError(@NonNls String msg) throws RuntimeException {
     throw new DisposalException(msg);
   }
 
-  private class DisposalException extends RuntimeException {
-    private DisposalException(String message) {
+  private abstract class AbstractDisposalException extends RuntimeException {
+    protected AbstractDisposalException(String message) {
       super(message);
     }
 
@@ -65,6 +95,12 @@ public class TraceableDisposable {
       printStackTrace(writer);
       writer.flush();
     }
+  }
+
+  private class DisposalException extends AbstractDisposalException {
+    private DisposalException(String message) {
+      super(message);
+    }
 
     @SuppressWarnings("HardCodedStringLiteral")
     @Override
index c486697c7f627c765231157d1d204f8ae94dacc4..632cd22c7b806d49205d947e0731554c47a66637 100644 (file)
@@ -16,8 +16,6 @@
 
 package com.intellij.ui;
 
-import com.intellij.openapi.util.SystemInfo;
-import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NotNull;
 
@@ -123,13 +121,10 @@ public class CaptionPanel extends JPanel {
 
   public void addSettingsComponent(Component component) {
     if (mySettingComponent == null) {
-      mySettingComponent = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
-      mySettingComponent.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
-      add(mySettingComponent, BorderLayout.WEST);
+      mySettingComponent = new JPanel();
       mySettingComponent.setOpaque(false);
-      if (!SystemInfo.isMacOSLion || UIUtil.isUnderDarcula()) {
-        mySettingComponent.setBorder(JBUI.Borders.emptyBottom(4));
-      }
+      mySettingComponent.setLayout(new BoxLayout(mySettingComponent, BoxLayout.X_AXIS));
+      add(mySettingComponent, BorderLayout.WEST);
     }
     mySettingComponent.add(component);
   }
index 0d8d343789d684330b86687d87af34c3118344b3..96240b0e9584ed82aa28c34d83c9840e85ec9007 100644 (file)
  */
 package com.intellij.openapi.vcs.changes;
 
+import com.intellij.diagnostic.ThreadDumper;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.Project;
+import com.intellij.util.concurrency.Semaphore;
+import org.jetbrains.annotations.TestOnly;
 
 /**
  * for non-AWT threads, synchronously waits for completion of ChanegListManager update
  */
+@TestOnly
 public class EnsureUpToDateFromNonAWTThread {
   private final Project myProject;
   private volatile boolean myDone;
 
   public EnsureUpToDateFromNonAWTThread(final Project project) {
-    //assert ApplicationManager.getApplication().isUnitTestMode();
-    assert ! ApplicationManager.getApplication().isDispatchThread();
     myProject = project;
-    myDone = false;
   }
 
   public void execute() {
-    assert ! ApplicationManager.getApplication().isDispatchThread();
-    final Object lock = new Object();
-
-    synchronized (lock) {
-      ChangeListManager.getInstance(myProject).invokeAfterUpdate(new Runnable() {
-        public void run() {
-          synchronized (lock) {
-            myDone = true;
-            lock.notifyAll();
-          }
-        }
-      }, InvokeAfterUpdateMode.SILENT, null, null);
-
-      while ((! myDone) && (! myProject.isDisposed())) {
-        try {
-          lock.wait();
-        }
-        catch (InterruptedException e) {
-          //
-        }
+    assert !ApplicationManager.getApplication().isDispatchThread();
+    final Semaphore lock = new Semaphore();
+
+    lock.down();
+
+    ChangeListManager.getInstance(myProject).invokeAfterUpdate(new Runnable() {
+      public void run() {
+        myDone = true;
+        lock.up();
       }
+    }, InvokeAfterUpdateMode.SILENT, null, null);
+
+    if (myProject.isDisposed()) return;
+
+    if (!lock.waitFor(100 * 1000) && !myProject.isDisposed()) {
+      //noinspection UseOfSystemOutOrSystemErr
+      System.out.println(ThreadDumper.dumpThreadsToString());
+      throw new AssertionError("Couldn't wait for changes update");
     }
   }
 
index 7fd4cac7317df5350a3521f2ee942ac92a33690d..5fbe58158f7285ee976091f05cfffd64cb2413b5 100644 (file)
@@ -231,7 +231,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
                                }, "<br/>"));
     }
 
-    VcsConfirmationDialog dialog = new VcsConfirmationDialog(myProject, new VcsShowConfirmationOption() {
+    VcsConfirmationDialog dialog = new VcsConfirmationDialog(myProject, "Remove Empty Changelist", "Remove", "Cancel", new VcsShowConfirmationOption() {
       @Override
       public Value getValue() {
         return config.REMOVE_EMPTY_INACTIVE_CHANGELISTS;
index 00c9c6c1a0c56438e65823abe8e1a96f7591935f..707458229a9a75f1819ea0cf9a41714aa2e80f48 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -15,7 +15,6 @@
  */
 package com.intellij.openapi.vcs.changes;
 
-import com.intellij.CommonBundle;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.SystemInfo;
@@ -30,18 +29,27 @@ import java.awt.event.ActionEvent;
 /**
  * @author Dmitry Avdeev
  */
-public class VcsConfirmationDialog extends OptionsDialog {
-
+class VcsConfirmationDialog extends OptionsDialog {
+  @NotNull private final String myOkText;
+  @NotNull private final String myCancelText;
   private final VcsShowConfirmationOption myOption;
   private final String myMessage;
   private final String myDoNotShowMessage;
 
-  protected VcsConfirmationDialog(Project project, VcsShowConfirmationOption option, String message, @NotNull String doNotShowMessage) {
+  VcsConfirmationDialog(@NotNull Project project,
+                        @NotNull String title,
+                        @NotNull String okText,
+                        @NotNull String cancelText,
+                        @NotNull VcsShowConfirmationOption option,
+                        @NotNull String message,
+                        @NotNull String doNotShowMessage) {
     super(project);
+    myOkText = okText;
+    myCancelText = cancelText;
     myOption = option;
     myMessage = message;
     myDoNotShowMessage = doNotShowMessage;
-    setTitle("Confirmation");
+    setTitle(title);
     init();
   }
 
@@ -77,16 +85,18 @@ public class VcsConfirmationDialog extends OptionsDialog {
   @NotNull
   @Override
   protected Action[] createActions() {
-    final AbstractAction okAction = new AbstractAction(CommonBundle.getYesButtonText()) {
+    final AbstractAction okAction = new AbstractAction(myOkText) {
       {
         putValue(DEFAULT_ACTION, Boolean.TRUE);
       }
 
+      @Override
       public void actionPerformed(ActionEvent e) {
         doOKAction();
       }
     };
-    final AbstractAction cancelAction = new AbstractAction(CommonBundle.getNoButtonText()) {
+    final AbstractAction cancelAction = new AbstractAction(myCancelText) {
+      @Override
       public void actionPerformed(ActionEvent e) {
         doCancelAction();
       }
index 60978dd3a5642a757f6fa1b1c03fa23c084a33d9..e32188ed680a2b27273219413e5e65ed8e553983 100644 (file)
@@ -32,4 +32,6 @@ public interface VcsLogDataPack {
   @NotNull
   PermanentGraph<Integer> getPermanentGraph();
 
+  @NotNull
+  VcsLogFilterCollection getFilters();
 }
index eab1d8375309d4ec1b57851047817fae369a7a21..fbb2c270a62404195dea6d8c09afc6e54dbd3fdf 100644 (file)
@@ -27,12 +27,18 @@ public interface VcsLogHighlighter {
 
   /**
    * Return the style which should be used for the log table commit entry, or VcsCommitStyle.DEFAULT if this highlighter does not specify any style for this commit.
-   *
-   * @param commitIndex index of commit (can be transferred to the Hash and vice versa).
+   * @param commitDetails details of selected commit.
    * @param isSelected  if true, the row currently has selection on it.
    */
   @NotNull
-  VcsCommitStyle getStyle(int commitIndex, boolean isSelected);
+  VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails commitDetails, boolean isSelected);
+
+  /**
+   * This method is called when new data arrives to the ui.
+   * @param dataPack new visible pack.
+   * @param refreshHappened true if permanent graph has changed.
+   */
+  void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened);
 
   /**
    * Describes how to display commit entry in the log table (for example, text or background color).
index a9a4106a269ece6ec770a1b9c7e60a703d8ac8b9..91bfe2c63b2fc8b4c3bf8d5462dbd5bca4511e8a 100644 (file)
@@ -26,10 +26,6 @@ public interface VcsLogUi {
   @NotNull
   VcsLogDataPack getDataPack();
 
-  void addHighlighter(@NotNull VcsLogHighlighter highlighter);
-
-  void removeHighlighter(@NotNull VcsLogHighlighter highlighter);
-
   void addLogListener(@NotNull VcsLogListener listener);
 
   void removeLogListener(@NotNull VcsLogListener listener);
index 3bd3d740b38e8c60e8e3900fb7c2112a39f3d506..bfa97d075a75466d437390fe4b759d17c7013a64 100644 (file)
     <group id="Vcs.Log.Settings">
       <reference id="Vcs.Log.ShowBranchesPanelAction"/>
       <reference id="Vcs.Log.ShowRootsColumnAction"/>
+      <separator/>
+      <reference id="Vcs.Log.CollapseAll"/>
+      <reference id="Vcs.Log.ExpandAll"/>
       <reference id="Vcs.Log.HighlightersActionGroup"/>
     </group>
     <group id="Vcs.Log.Toolbar">
-      <reference id="Vcs.Log.CollapseAll"/>
-      <reference id="Vcs.Log.ExpandAll"/>
       <reference id="Vcs.Log.ShowLongEdges"/>
       <reference id="Vcs.Log.ShowDetailsAction"/>
     </group>
index 0dedc193c684acd861b77d0694054b76b3188055..8fb6a3af119e6bd881d0e31b4cc8a66466d2f697 100644 (file)
@@ -44,7 +44,6 @@ public class VcsLogUiProperties implements PersistentStateComponent<VcsLogUiProp
     public boolean LONG_EDGES_VISIBLE = false;
     public int BEK_SORT_TYPE = 0;
     public boolean SHOW_ROOT_NAMES = false;
-    public boolean HIGHLIGHT_MY_COMMITS = true;
     public Deque<UserGroup> RECENTLY_FILTERED_USER_GROUPS = new ArrayDeque<UserGroup>();
     public Deque<UserGroup> RECENTLY_FILTERED_BRANCH_GROUPS = new ArrayDeque<UserGroup>();
     public Map<String, Boolean> HIGHLIGHTERS = ContainerUtil.newTreeMap();
@@ -146,14 +145,6 @@ public class VcsLogUiProperties implements PersistentStateComponent<VcsLogUiProp
     myState.HIGHLIGHTERS.put(id, value);
   }
 
-  public boolean isHighlightMyCommits() {
-    return myState.HIGHLIGHT_MY_COMMITS;
-  }
-
-  public void setHighlightMyCommits(boolean isHighlightMyCommits) {
-    myState.HIGHLIGHT_MY_COMMITS = isHighlightMyCommits;
-  }
-
   public static class UserGroup {
     public List<String> users = new ArrayList<String>();
 
index f0405a284d0cee5a0a16907c0f708e5a83f5bc34..f12646e551ec62bbf46f074b7fca8490fb4a5024 100644 (file)
@@ -17,26 +17,30 @@ package com.intellij.vcs.log.data;
 
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.vcs.log.VcsLogDataPack;
+import com.intellij.vcs.log.VcsLogFilterCollection;
 import com.intellij.vcs.log.VcsLogProvider;
 import com.intellij.vcs.log.VcsLogRefs;
 import com.intellij.vcs.log.graph.PermanentGraph;
 import com.intellij.vcs.log.graph.VisibleGraph;
+import com.intellij.vcs.log.impl.VcsLogFilterCollectionImpl;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Map;
 
 public class VisiblePack implements VcsLogDataPack {
 
-  public static final VisiblePack EMPTY = new VisiblePack(DataPack.EMPTY, EmptyVisibleGraph.getInstance(), false);
+  public static final VisiblePack EMPTY = new VisiblePack(DataPack.EMPTY, EmptyVisibleGraph.getInstance(), false, VcsLogFilterCollectionImpl.EMPTY);
 
   @NotNull private final DataPack myDataPack;
   @NotNull private final VisibleGraph<Integer> myVisibleGraph;
   private final boolean myCanRequestMore;
+  @NotNull private final VcsLogFilterCollection myFilters;
 
-  VisiblePack(@NotNull DataPack dataPack, @NotNull VisibleGraph<Integer> graph, boolean canRequestMore) {
+  VisiblePack(@NotNull DataPack dataPack, @NotNull VisibleGraph<Integer> graph, boolean canRequestMore, @NotNull VcsLogFilterCollection filters) {
     myDataPack = dataPack;
     myVisibleGraph = graph;
     myCanRequestMore = canRequestMore;
+    myFilters = filters;
   }
 
   @NotNull
@@ -73,4 +77,10 @@ public class VisiblePack implements VcsLogDataPack {
   public boolean isFull() {
     return myDataPack.isFull();
   }
+
+  @Override
+  @NotNull
+  public VcsLogFilterCollection getFilters() {
+    return myFilters;
+  }
 }
index 3c3f714150d70f2d75bc799718b8ac1a51232ff4..41f7cb6ed3620b05fe32d25422a7da4f0fb8eac2 100644 (file)
@@ -31,6 +31,7 @@ import com.intellij.vcs.log.graph.GraphCommit;
 import com.intellij.vcs.log.graph.PermanentGraph;
 import com.intellij.vcs.log.graph.VisibleGraph;
 import com.intellij.vcs.log.impl.VcsLogFilterCollectionImpl;
+import com.intellij.vcs.log.impl.VcsLogHashFilterImpl;
 import com.intellij.vcs.log.impl.VcsLogUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -100,7 +101,7 @@ class VisiblePackBuilder {
     else {
       visibleGraph = dataPack.getPermanentGraph().createVisibleGraph(sortType, matchingHeads, getMatchedCommitIndex(matchingCommits));
     }
-    return Pair.create(new VisiblePack(dataPack, visibleGraph, canRequestMore), commitCount);
+    return Pair.create(new VisiblePack(dataPack, visibleGraph, canRequestMore, filters), commitCount);
   }
 
   private static <T> boolean matchesNothing(@Nullable Collection<T> matchingSet) {
@@ -118,7 +119,7 @@ class VisiblePackBuilder {
       }
     });
     VisibleGraph<Integer> visibleGraph = dataPack.getPermanentGraph().createVisibleGraph(sortType, null, indices);
-    return new VisiblePack(dataPack, visibleGraph, false);
+    return new VisiblePack(dataPack, visibleGraph, false, new VcsLogFilterCollectionImpl(null, null, new VcsLogHashFilterImpl(hashes), null, null, null, null));
   }
 
   @Nullable
index d973face890d973041fe2bb8e7d4db73513f53a8..4d6fe2cfe8b2c7f841572de15138fd7cb86ab51e 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.List;
 
 public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection {
+  @NotNull public static final VcsLogFilterCollection EMPTY = new VcsLogFilterCollectionImpl(null, null, null, null, null, null, null);
 
   @Nullable private final VcsLogBranchFilter myBranchFilter;
   @Nullable private final VcsLogUserFilter myUserFilter;
index a656298c8923b616b5195c840bb1d0b1f4bc38d3..75ca5fb1a8f8725650cdc15024cd5b5a500e1a14 100644 (file)
@@ -18,11 +18,8 @@ package com.intellij.vcs.log.ui;
 import com.intellij.openapi.util.Condition;
 import com.intellij.ui.JBColor;
 import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.LoadingDetails;
 import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
 import com.intellij.vcs.log.impl.VcsLogUtil;
-import com.intellij.vcs.log.ui.filter.VcsLogClassicFilterUi;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -30,61 +27,44 @@ import java.awt.*;
 
 public class CurrentBranchHighlighter implements VcsLogHighlighter {
   private static final JBColor CURRENT_BRANCH_BG = new JBColor(new Color(228, 250, 255), new Color(63, 71, 73));
-  @NotNull private final VcsLogUiProperties myUiProperties;
   @NotNull private final VcsLogDataHolder myDataHolder;
-  @NotNull private final VcsLogFilterUi myFilterUi;
+  @NotNull private final VcsLogUi myLogUi;
   @Nullable private String mySingleFilteredBranch;
 
-  public CurrentBranchHighlighter(@NotNull VcsLogDataHolder logDataHolder,
-                                  @NotNull VcsLogUiProperties uiProperties,
-                                  @NotNull VcsLogFilterUi filterUi) {
+  public CurrentBranchHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
     myDataHolder = logDataHolder;
-    myUiProperties = uiProperties;
-    myFilterUi = filterUi;
-
-
-    // this code will look much simpler when history* branch is merged
-    ((VcsLogClassicFilterUi)filterUi).getLogUi().addLogListener(new VcsLogListener() {
-      @Override
-      public void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
-        VcsLogBranchFilter branchFilter = myFilterUi.getFilters().getBranchFilter();
-        mySingleFilteredBranch = branchFilter == null
-                                 ? null
-                                 : VcsLogUtil
-                                   .getSingleFilteredBranch(branchFilter, dataPack.getRefs());
-      }
-    });
+    myLogUi = logUi;
   }
 
   @NotNull
   @Override
-  public VcsCommitStyle getStyle(int commitIndex, boolean isSelected) {
-    if (isSelected || !myUiProperties.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
-    VcsShortCommitDetails details = myDataHolder.getMiniDetailsGetter().getCommitDataIfAvailable(commitIndex);
-    if (details != null && !(details instanceof LoadingDetails)) {
-      VcsLogProvider provider = myDataHolder.getLogProvider(details.getRoot());
-      String currentBranch = provider.getCurrentBranch(details.getRoot());
-      VcsLogBranchFilter branchFilter = myFilterUi.getFilters().getBranchFilter();
-      if (currentBranch != null && (branchFilter == null || !(currentBranch.equals(mySingleFilteredBranch)))) {
-        Condition<CommitId> condition =
-          myDataHolder.getContainingBranchesGetter().getContainedInBranchCondition(currentBranch, details.getRoot());
-        if (condition.value(new CommitId(details.getId(), details.getRoot()))) {
-          return VcsCommitStyleFactory.background(CURRENT_BRANCH_BG);
-        }
+  public VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails details, boolean isSelected) {
+    if (isSelected || !myLogUi.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
+    VcsLogProvider provider = myDataHolder.getLogProvider(details.getRoot());
+    String currentBranch = provider.getCurrentBranch(details.getRoot());
+    if (currentBranch != null && !(currentBranch.equals(mySingleFilteredBranch))) {
+      Condition<CommitId> condition =
+        myDataHolder.getContainingBranchesGetter().getContainedInBranchCondition(currentBranch, details.getRoot());
+      if (condition.value(new CommitId(details.getId(), details.getRoot()))) {
+        return VcsCommitStyleFactory.background(CURRENT_BRANCH_BG);
       }
     }
     return VcsCommitStyle.DEFAULT;
   }
 
+  @Override
+  public void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
+    VcsLogBranchFilter branchFilter = dataPack.getFilters().getBranchFilter();
+    mySingleFilteredBranch = branchFilter == null ? null : VcsLogUtil.getSingleFilteredBranch(branchFilter, dataPack.getRefs());
+  }
+
   public static class Factory implements VcsLogHighlighterFactory {
     @NotNull private static final String ID = "CURRENT_BRANCH";
 
     @NotNull
     @Override
-    public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder,
-                                               @NotNull VcsLogUiProperties uiProperties,
-                                               @NotNull VcsLogFilterUi filterUi) {
-      return new CurrentBranchHighlighter(logDataHolder, uiProperties, filterUi);
+    public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
+      return new CurrentBranchHighlighter(logDataHolder, logUi);
     }
 
     @NotNull
@@ -98,5 +78,10 @@ public class CurrentBranchHighlighter implements VcsLogHighlighter {
     public String getTitle() {
       return "Current Branch";
     }
+
+    @Override
+    public boolean showMenuItem() {
+      return true;
+    }
   }
 }
index 16d820e9f331a60028fa98bb236a1a99791869e0..0b5bd5b610cfe94efaba678e5eae69a5aaf59f67 100644 (file)
@@ -17,45 +17,37 @@ package com.intellij.vcs.log.ui;
 
 import com.intellij.ui.Gray;
 import com.intellij.ui.JBColor;
-import com.intellij.vcs.log.VcsCommitStyleFactory;
-import com.intellij.vcs.log.VcsLogFilterUi;
-import com.intellij.vcs.log.VcsLogHighlighter;
-import com.intellij.vcs.log.VcsShortCommitDetails;
-import com.intellij.vcs.log.data.LoadingDetails;
+import com.intellij.vcs.log.*;
 import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
 import org.jetbrains.annotations.NotNull;
 
 public class MergeCommitsHighlighter implements VcsLogHighlighter {
   public static final JBColor MERGE_COMMIT_FOREGROUND = new JBColor(Gray._128, Gray._96);
-  @NotNull private final VcsLogUiProperties myUiProperties;
-  @NotNull private final VcsLogDataHolder myDataHolder;
+  @NotNull private final VcsLogUi myLogUi;
 
-  public MergeCommitsHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUiProperties uiProperties) {
-    myDataHolder = logDataHolder;
-    myUiProperties = uiProperties;
+  public MergeCommitsHighlighter(@NotNull VcsLogUi logUi) {
+    myLogUi = logUi;
   }
 
   @NotNull
   @Override
-  public VcsCommitStyle getStyle(int commitIndex, boolean isSelected) {
-    if (isSelected || !myUiProperties.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
-    VcsShortCommitDetails details = myDataHolder.getMiniDetailsGetter().getCommitDataIfAvailable(commitIndex);
-    if (details != null && !(details instanceof LoadingDetails)) {
-      if (details.getParents().size() >= 2) return VcsCommitStyleFactory.foreground(MERGE_COMMIT_FOREGROUND);
-    }
+  public VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails details, boolean isSelected) {
+    if (isSelected || !myLogUi.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
+    if (details.getParents().size() >= 2) return VcsCommitStyleFactory.foreground(MERGE_COMMIT_FOREGROUND);
     return VcsCommitStyle.DEFAULT;
   }
 
+  @Override
+  public void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
+  }
+
   public static class Factory implements VcsLogHighlighterFactory {
     @NotNull private static final String ID = "MERGE_COMMITS";
 
     @NotNull
     @Override
-    public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder,
-                                               @NotNull VcsLogUiProperties uiProperties,
-                                               @NotNull VcsLogFilterUi filterUi) {
-      return new MergeCommitsHighlighter(logDataHolder, uiProperties);
+    public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
+      return new MergeCommitsHighlighter(logUi);
     }
 
     @NotNull
@@ -69,5 +61,10 @@ public class MergeCommitsHighlighter implements VcsLogHighlighter {
     public String getTitle() {
       return "Merge Commits";
     }
+
+    @Override
+    public boolean showMenuItem() {
+      return true;
+    }
   }
 }
index d6ce0bba7d1e55cc97268bf8cf8a1f5b696be299..4123abe62734e5ddcc54d30488b9d9f70eb8a63a 100644 (file)
  */
 package com.intellij.vcs.log.ui;
 
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.util.NotNullFunction;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.LoadingDetails;
 import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
-import com.intellij.vcs.log.impl.VcsLogContentProvider;
-import com.intellij.vcs.log.impl.VcsLogManager;
 import com.intellij.vcs.log.impl.VcsUserImpl;
 import com.intellij.vcs.log.ui.filter.VcsLogUserFilterImpl;
 import org.jetbrains.annotations.NotNull;
@@ -33,64 +28,35 @@ import java.util.Collections;
 import java.util.Set;
 
 public class MyCommitsHighlighter implements VcsLogHighlighter {
-  @NotNull private final VcsLogUiProperties myUiProperties;
   @NotNull private final VcsLogDataHolder myDataHolder;
-  @NotNull private final VcsLogFilterUi myFilterUi;
-  private boolean myAreTheOnlyUsers = false;
+  @NotNull private final VcsLogUi myLogUi;
+  private boolean myShouldHighlightUser = false;
 
-  public MyCommitsHighlighter(@NotNull VcsLogDataHolder logDataHolder,
-                              @NotNull VcsLogUiProperties uiProperties,
-                              @NotNull VcsLogFilterUi filterUi) {
+  public MyCommitsHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
     myDataHolder = logDataHolder;
-    myUiProperties = uiProperties;
-    myFilterUi = filterUi;
-    // migration to map storage
-    if (!myUiProperties.isHighlightMyCommits()) {
-      // by default, my commits highlighter was enabled
-      // if it was disabled we need to migrate that
-      myUiProperties.enableHighlighter(Factory.ID, false);
-      myUiProperties.setHighlightMyCommits(true);
-    }
-
-    // this is a tmp solution for performance problems of calculating areTheOnlyUsers every repaint (we simply do not want to do that)
-    // todo remove this when history2 branch is merged into master (history2 will allow a proper way to fix the problem)
-    ApplicationManager.getApplication().invokeLater(new Runnable() {
-      @Override
-      public void run() {
-        if (myDataHolder.getProject().isDisposed()) return;
-        VcsLogManager logManager = VcsLogContentProvider.findLogManager(myDataHolder.getProject());
-        if (logManager != null) {
-          VcsLogUiImpl logUi = logManager.getLogUi();
-          if (logUi != null) {
-            logUi.addLogListener(new VcsLogListener() {
-              @Override
-              public void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
-                myAreTheOnlyUsers = areTheOnlyUsers();
-              }
-            });
-          }
-        }
-      }
-    });
+    myLogUi = logUi;
   }
 
   @NotNull
   @Override
-  public VcsCommitStyle getStyle(int commitIndex, boolean isSelected) {
-    if (!myUiProperties.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
-    if (!myAreTheOnlyUsers && !isFilteredByCurrentUser()) {
-      VcsShortCommitDetails details = myDataHolder.getMiniDetailsGetter().getCommitDataIfAvailable(commitIndex);
-      if (details != null && !(details instanceof LoadingDetails)) {
-        VcsUser currentUser = myDataHolder.getCurrentUser().get(details.getRoot());
-        if (currentUser != null && VcsUserImpl.isSamePerson(currentUser, details.getAuthor())) {
-          return VcsCommitStyleFactory.bold();
-        }
+  public VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails details, boolean isSelected) {
+    if (!myLogUi.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT;
+    if (myShouldHighlightUser) {
+      VcsUser currentUser = myDataHolder.getCurrentUser().get(details.getRoot());
+      if (currentUser != null && VcsUserImpl.isSamePerson(currentUser, details.getAuthor())) {
+        return VcsCommitStyleFactory.bold();
       }
     }
     return VcsCommitStyle.DEFAULT;
   }
 
-  private boolean areTheOnlyUsers() {
+  @Override
+  public void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
+    myShouldHighlightUser = !isSingleUser() && !isFilteredByCurrentUser(dataPack.getFilters());
+  }
+
+  // returns true if only one user commits to this repository
+  private boolean isSingleUser() {
     NotNullFunction<VcsUser, String> nameToString = new NotNullFunction<VcsUser, String>() {
       @NotNull
       @Override
@@ -103,8 +69,9 @@ public class MyCommitsHighlighter implements VcsLogHighlighter {
     return allUserNames.size() == currentUserNames.size() && currentUserNames.containsAll(allUserNames);
   }
 
-  private boolean isFilteredByCurrentUser() {
-    VcsLogUserFilter userFilter = myFilterUi.getFilters().getUserFilter();
+  // returns true if filtered by "me"
+  private static boolean isFilteredByCurrentUser(@NotNull VcsLogFilterCollection filters) {
+    VcsLogUserFilter userFilter = filters.getUserFilter();
     if (userFilter == null) return false;
     Collection<String> filterByName = ((VcsLogUserFilterImpl)userFilter).getUserNamesForPresentation();
     if (Collections.singleton(VcsLogUserFilterImpl.ME).containsAll(filterByName)) return true;
@@ -116,10 +83,8 @@ public class MyCommitsHighlighter implements VcsLogHighlighter {
 
     @NotNull
     @Override
-    public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder,
-                                               @NotNull VcsLogUiProperties uiProperties,
-                                               @NotNull VcsLogFilterUi filterUi) {
-      return new MyCommitsHighlighter(logDataHolder, uiProperties, filterUi);
+    public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
+      return new MyCommitsHighlighter(logDataHolder, logUi);
     }
 
     @NotNull
@@ -133,5 +98,10 @@ public class MyCommitsHighlighter implements VcsLogHighlighter {
     public String getTitle() {
       return "My Commits";
     }
+
+    @Override
+    public boolean showMenuItem() {
+      return true;
+    }
   }
 }
index def532abcebbf556625a317acb7bd7f7b997143f..d1a3bb4f83c5b1d5ba3b259bc000ab16361cf610 100644 (file)
  */
 package com.intellij.vcs.log.ui;
 
-import com.intellij.vcs.log.VcsLogFilterUi;
 import com.intellij.vcs.log.VcsLogHighlighter;
+import com.intellij.vcs.log.VcsLogUi;
 import com.intellij.vcs.log.data.VcsLogDataHolder;
-import com.intellij.vcs.log.data.VcsLogUiProperties;
 import org.jetbrains.annotations.NotNull;
 
 public interface VcsLogHighlighterFactory {
   @NotNull
-  VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder,
-                                      @NotNull VcsLogUiProperties uiProperties,
-                                      @NotNull VcsLogFilterUi filterUi);
+  VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi);
 
   @NotNull
   String getId();
 
   @NotNull
   String getTitle();
+
+  boolean showMenuItem();
 }
index 03d58fcefc46ecab74f19f5e24d353e76772c10a..9f616eb37a7855f8a8039bdfb05fd2f9b52f79c5 100644 (file)
@@ -68,7 +68,7 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
     myMainFrame = new MainFrame(logDataHolder, this, project, settings, uiProperties, myLog, myVisiblePack);
 
     for (VcsLogHighlighterFactory factory : Extensions.getExtensions(LOG_HIGHLIGHTER_FACTORY_EP, myProject)) {
-      addHighlighter(factory.createHighlighter(logDataHolder, myUiProperties, myMainFrame.getFilterUi()));
+      getTable().addHighlighter(factory.createHighlighter(logDataHolder, this));
     }
   }
 
@@ -322,18 +322,6 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable {
     return myVisiblePack;
   }
 
-  @Override
-  public void addHighlighter(@NotNull VcsLogHighlighter highlighter) {
-    getTable().addHighlighter(highlighter);
-    repaintUI();
-  }
-
-  @Override
-  public void removeHighlighter(@NotNull VcsLogHighlighter highlighter) {
-    getTable().removeHighlighter(highlighter);
-    repaintUI();
-  }
-
   @Override
   public void addLogListener(@NotNull VcsLogListener listener) {
     ApplicationManager.getApplication().assertIsDispatchThread();
index 2d22189eb7d9f67b368305d74bda9e005c8d6fe1..fc2b267d23b49e75a1a26451391885c3c8d1dd0f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
  */
 package com.intellij.vcs.log.ui.actions;
 
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.vcs.log.VcsLogDataKeys;
-import com.intellij.vcs.log.VcsLogUi;
-import com.intellij.vcs.log.graph.PermanentGraph;
 import com.intellij.vcs.log.ui.VcsLogUiImpl;
 import icons.VcsLogIcons;
 import org.jetbrains.annotations.NotNull;
 
-public class CollapseGraphAction extends GraphAction {
-  public CollapseGraphAction() {
-    super("Collapse linear branches", "Collapse linear branches", VcsLogIcons.CollapseBranches);
+import javax.swing.*;
+
+public class CollapseGraphAction extends CollapseOrExpandGraphAction {
+  @Override
+  protected void executeAction(@NotNull VcsLogUiImpl vcsLogUi) {
+    vcsLogUi.collapseAll();
+  }
+
+  @NotNull
+  @Override
+  protected Icon getMergesIcon() {
+    return VcsLogIcons.CollapseMerges;
   }
 
+  @NotNull
   @Override
-  public void actionPerformed(@NotNull AnActionEvent e) {
-    VcsLogUi ui = e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI);
-    ((VcsLogUiImpl)ui).collapseAll();
+  protected Icon getBranchesIcon() {
+    return VcsLogIcons.CollapseMerges;
   }
 
+  @NotNull
   @Override
-  protected void update(@NotNull VcsLogUi ui, @NotNull AnActionEvent e) {
-    if (!ui.getFilterUi().getFilters().getDetailsFilters().isEmpty()) {
-      e.getPresentation().setEnabled(false);
-    }
-    if (ui.getBekType() == PermanentGraph.SortType.LinearBek) {
-      e.getPresentation().setIcon(VcsLogIcons.CollapseMerges);
-      e.getPresentation().setText("Collapse all merges");
-      e.getPresentation().setDescription("Collapse all merges");
-    }
-    else {
-      e.getPresentation().setIcon(VcsLogIcons.CollapseBranches);
-      e.getPresentation().setText("Collapse all linear branches");
-      e.getPresentation().setDescription("Collapse all linear branches");
-    }
+  protected String getPrefix() {
+    return "Collapse ";
   }
 }
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseOrExpandGraphAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/CollapseOrExpandGraphAction.java
new file mode 100644 (file)
index 0000000..53d1f3b
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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.vcs.log.ui.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
+import com.intellij.vcs.log.VcsLogDataKeys;
+import com.intellij.vcs.log.VcsLogUi;
+import com.intellij.vcs.log.graph.PermanentGraph;
+import com.intellij.vcs.log.ui.VcsLogUiImpl;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+abstract class CollapseOrExpandGraphAction extends DumbAwareAction {
+  private static final String LINEAR_BRANCHES = "Linear Branches";
+  private static final String LINEAR_BRANCHES_DESCRIPTION = "linear branches";
+  private static final String MERGES = "Merges";
+  private static final String MERGES_DESCRIPTION = "merges";
+
+  public CollapseOrExpandGraphAction() {
+    super("Collapse or Expand " + LINEAR_BRANCHES, "Collapse or Expand " + LINEAR_BRANCHES_DESCRIPTION, null);
+  }
+
+  @Override
+  public void actionPerformed(@NotNull AnActionEvent e) {
+    VcsLogUi ui = e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI);
+    executeAction((VcsLogUiImpl)ui);
+  }
+
+  @Override
+  public void update(@NotNull AnActionEvent e) {
+    VcsLogUi ui = e.getData(VcsLogDataKeys.VCS_LOG_UI);
+
+    if (ui != null && ui.areGraphActionsEnabled()) {
+      e.getPresentation().setEnabled(true);
+      if (!ui.getFilterUi().getFilters().getDetailsFilters().isEmpty()) {
+        e.getPresentation().setEnabled(false);
+      }
+
+      if (ui.getBekType() == PermanentGraph.SortType.LinearBek) {
+        e.getPresentation().setText(getPrefix() + MERGES);
+        e.getPresentation().setDescription(getPrefix() + MERGES_DESCRIPTION);
+      }
+      else {
+        e.getPresentation().setText(getPrefix() + LINEAR_BRANCHES);
+        e.getPresentation().setDescription(getPrefix() + LINEAR_BRANCHES_DESCRIPTION);
+      }
+    }
+    else {
+      e.getPresentation().setEnabled(false);
+    }
+
+    e.getPresentation().setText(getPrefix() + LINEAR_BRANCHES);
+    e.getPresentation().setDescription(getPrefix() + LINEAR_BRANCHES_DESCRIPTION);
+    if (isIconHidden(e)) {
+      e.getPresentation().setIcon(null);
+    }
+    else {
+      e.getPresentation().setIcon(ui != null && ui.getBekType() == PermanentGraph.SortType.LinearBek ? getMergesIcon() : getBranchesIcon());
+    }
+  }
+
+  protected abstract void executeAction(@NotNull VcsLogUiImpl vcsLogUi);
+
+  @NotNull
+  protected abstract Icon getMergesIcon();
+
+  @NotNull
+  protected abstract Icon getBranchesIcon();
+
+  @NotNull
+  protected abstract String getPrefix();
+
+  private static boolean isIconHidden(@NotNull AnActionEvent e) {
+    return e.getPlace().equals(ToolWindowContentUi.POPUP_PLACE);
+  }
+
+}
index a486b9272d45183818d4272aa2f25d15a45f4306..199468f7e3f79f507bc21816da51ba312d024153 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
  */
 package com.intellij.vcs.log.ui.actions;
 
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.vcs.log.VcsLogDataKeys;
-import com.intellij.vcs.log.VcsLogUi;
-import com.intellij.vcs.log.graph.PermanentGraph;
 import com.intellij.vcs.log.ui.VcsLogUiImpl;
 import icons.VcsLogIcons;
 import org.jetbrains.annotations.NotNull;
 
-public class ExpandGraphAction extends GraphAction {
-  public ExpandGraphAction() {
-    super("Expand all branches", "Expand all branches", VcsLogIcons.ExpandBranches);
+import javax.swing.*;
+
+public class ExpandGraphAction extends CollapseOrExpandGraphAction {
+  @Override
+  protected void executeAction(@NotNull VcsLogUiImpl vcsLogUi) {
+    vcsLogUi.expandAll();
+  }
+
+  @NotNull
+  @Override
+  protected Icon getMergesIcon() {
+    return VcsLogIcons.ExpandMerges;
   }
 
+  @NotNull
   @Override
-  public void actionPerformed(@NotNull AnActionEvent e) {
-    VcsLogUi ui = e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI);
-    ((VcsLogUiImpl)ui).expandAll();
+  protected Icon getBranchesIcon() {
+    return VcsLogIcons.ExpandMerges;
   }
 
+  @NotNull
   @Override
-  protected void update(@NotNull VcsLogUi ui, @NotNull AnActionEvent e) {
-    if (!ui.getFilterUi().getFilters().getDetailsFilters().isEmpty()) {
-      e.getPresentation().setEnabled(false);
-    }
-    if (ui.getBekType() == PermanentGraph.SortType.LinearBek) {
-      e.getPresentation().setIcon(VcsLogIcons.ExpandMerges);
-      e.getPresentation().setText("Expand all merges");
-      e.getPresentation().setDescription("Expand all merges");
-    }
-    else {
-      e.getPresentation().setIcon(VcsLogIcons.ExpandBranches);
-      e.getPresentation().setText("Expand all linear branches");
-      e.getPresentation().setDescription("Expand all linear branches");
-    }
+  protected String getPrefix() {
+    return "Expand ";
   }
 }
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/GraphAction.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/actions/GraphAction.java
deleted file mode 100644 (file)
index 1159d15..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.vcs.log.ui.actions;
-
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.project.DumbAwareAction;
-import com.intellij.vcs.log.VcsLogDataKeys;
-import com.intellij.vcs.log.VcsLogUi;
-import org.jetbrains.annotations.NotNull;
-
-import javax.swing.*;
-
-public abstract class GraphAction extends DumbAwareAction {
-
-  public GraphAction(@NotNull String text, @NotNull String description, @NotNull Icon icon) {
-    super(text, description, icon);
-  }
-
-  private static boolean areGraphActionsEnabled(@NotNull AnActionEvent e) {
-    VcsLogUi ui = e.getData(VcsLogDataKeys.VCS_LOG_UI);
-    if (ui == null) return false;
-    return ui.areGraphActionsEnabled();
-  }
-
-  @Override
-  public void update(@NotNull AnActionEvent e) {
-    boolean graphActionsEnabled = areGraphActionsEnabled(e);
-    e.getPresentation().setEnabled(graphActionsEnabled);
-    if (graphActionsEnabled) {
-      update(e.getRequiredData(VcsLogDataKeys.VCS_LOG_UI), e);
-    }
-  }
-
-  protected abstract void update(@NotNull VcsLogUi ui, @NotNull AnActionEvent e);
-}
index 973ded5aee52aeb693abc97b0f74429289fa53b3..ee5137ea4052ce0d4b84cf121c7850837eccdbe2 100644 (file)
@@ -39,7 +39,9 @@ public class HighlightersActionGroup extends ActionGroup {
       if (ui != null) {
         actions.add(new Separator("Highlight"));
         for (VcsLogHighlighterFactory factory : Extensions.getExtensions(VcsLogUiImpl.LOG_HIGHLIGHTER_FACTORY_EP, e.getProject())) {
-          actions.add(new EnableHighlighterAction(ui, factory));
+          if (factory.showMenuItem()) {
+            actions.add(new EnableHighlighterAction(ui, factory));
+          }
         }
       }
     }
index 9eaa533b3abd63e1c3c5f989d49f9dd342d8903d..47d22a24e0138dd1b40ccaba107e29de6a1657f8 100644 (file)
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
 
 public class ShowLongEdgesAction extends ToggleAction implements DumbAware {
   public ShowLongEdgesAction() {
-    super("Show long edges", "Show long branch edges even if commits are invisible in the current view.", VcsLogIcons.ShowHideLongEdges);
+    super("Show Long Edges", "Show long branch edges even if commits are invisible in the current view.", VcsLogIcons.ShowHideLongEdges);
   }
 
   @Override
index fcbc1ec1a5856bd0b76f5f7baa4de4c286962763..95adeea06a6edf4c8ca462fb6a81ebda0df40ca9 100644 (file)
@@ -146,7 +146,7 @@ public class MainFrame extends JPanel implements DataProvider {
   public void updateDataPack(@NotNull VisiblePack dataPack, boolean permGraphChanged) {
     myFilterUi.updateDataPack(dataPack);
     myDetailsPanel.updateDataPack(dataPack);
-    myGraphTable.updateDataPack(dataPack);
+    myGraphTable.updateDataPack(dataPack, permGraphChanged);
     myBranchesPanel.updateDataPack(dataPack, permGraphChanged);
   }
 
@@ -223,7 +223,7 @@ public class MainFrame extends JPanel implements DataProvider {
 
     Wrapper textFilter = new Wrapper(myFilterUi.createTextFilter());
     textFilter.setVerticalSizeReferent(toolbar.getComponent());
-    textFilter.setBorder(BorderFactory.createEmptyBorder(1, 5, 0, 0));
+    textFilter.setBorder(JBUI.Borders.emptyLeft(5));
 
     ActionToolbar settings =
       createActionsToolbar(new DefaultActionGroup(ActionManager.getInstance().getAction(VcsLogActionPlaces.VCS_LOG_QUICK_SETTINGS_ACTION)));
index 4f4e5e170e044007069bfad15230818da76a37fe..7d1721bde9e5d8eaed76b5689dfbb8386983c2b1 100644 (file)
@@ -35,6 +35,7 @@ import com.intellij.util.text.DateFormatUtil;
 import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.UIUtil;
 import com.intellij.vcs.log.*;
+import com.intellij.vcs.log.data.LoadingDetails;
 import com.intellij.vcs.log.data.VcsLogDataHolder;
 import com.intellij.vcs.log.data.VisiblePack;
 import com.intellij.vcs.log.graph.*;
@@ -128,10 +129,15 @@ public class VcsLogGraphTable extends JBTable implements DataProvider, CopyProvi
     initColumnSize();
   }
 
-  public void updateDataPack(@NotNull VisiblePack visiblePack) {
+  public void updateDataPack(@NotNull VisiblePack visiblePack, boolean permGraphChanged) {
     VcsLogGraphTable.Selection previousSelection = getSelection();
     getGraphTableModel().setVisiblePack(visiblePack);
     previousSelection.restore(visiblePack.getVisibleGraph(), true);
+
+    for (VcsLogHighlighter highlighter: myHighlighters) {
+      highlighter.update(visiblePack, permGraphChanged);
+    }
+
     setPaintBusy(false);
     initColumnSize();
   }
@@ -320,20 +326,22 @@ public class VcsLogGraphTable extends JBTable implements DataProvider, CopyProvi
         .createStyle(dummyRendererComponent.getForeground(), dummyRendererComponent.getBackground(), VcsLogHighlighter.TextStyle.NORMAL);
     }
 
-    final RowInfo<Integer> rowInfo = visibleGraph.getRowInfo(row);
+    RowInfo<Integer> rowInfo = visibleGraph.getRowInfo(row);
 
     VcsLogHighlighter.VcsCommitStyle defaultStyle = VcsCommitStyleFactory
       .createStyle(rowInfo.getRowType() == RowType.UNMATCHED ? JBColor.GRAY : dummyRendererComponent.getForeground(),
                    dummyRendererComponent.getBackground(), VcsLogHighlighter.TextStyle.NORMAL);
 
+    final VcsShortCommitDetails details = myLogDataHolder.getMiniDetailsGetter().getCommitDataIfAvailable(rowInfo.getCommit());
+    if (details == null || details instanceof LoadingDetails) return defaultStyle;
+
     List<VcsLogHighlighter.VcsCommitStyle> styles =
       ContainerUtil.map(myHighlighters, new Function<VcsLogHighlighter, VcsLogHighlighter.VcsCommitStyle>() {
         @Override
         public VcsLogHighlighter.VcsCommitStyle fun(VcsLogHighlighter highlighter) {
-          return highlighter.getStyle(rowInfo.getCommit(), selected);
+          return highlighter.getStyle(details, selected);
         }
       });
-
     return VcsCommitStyleFactory.combine(ContainerUtil.append(styles, defaultStyle));
   }
 
index 87c1896d57b02433db671112727a8fddd12c32b7..0985daa20b6b1512fe436975cb87e07ad0d0d2e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -134,7 +134,7 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
       markupModel = (MarkupModelEx)DocumentMarkupModel.forDocument(document, getProject(), false);
       if (markupModel != null) {
         // renderersChanged false - we don't change gutter size
-        markupModel.fireAttributesChanged((RangeHighlighterEx)highlighter, false);
+        markupModel.fireAttributesChanged((RangeHighlighterEx)highlighter, false, false);
       }
     }
   }
index db38f88d527b381557fdc9bc542196a560f8bb5d..b4887ab8d90b7365d1b61a136dd10defa052dfa9 100644 (file)
                      key="method.return.concrete.class.display.name" groupBundle="messages.InspectionsBundle"
                      groupKey="group.names.abstraction.issues" enabledByDefault="false" level="WARNING"
                      implementationClass="com.siyeh.ig.abstraction.MethodReturnOfConcreteClassInspection"/>
+    <localInspection groupPath="Java" language="JAVA" shortName="OptionalUsedAsFieldOrParameterType" bundle="com.siyeh.InspectionGadgetsBundle"
+                     key="optional.used.as.field.or.parameter.type.display.name" groupBundle="messages.InspectionsBundle"
+                     groupKey="group.names.abstraction.issues" enabledByDefault="true" level="WARNING"
+                     implementationClass="com.siyeh.ig.abstraction.OptionalUsedAsFieldOrParameterTypeInspection"/>
     <localInspection groupPath="Java" language="JAVA" shortName="OverlyStrongTypeCast" bundle="com.siyeh.InspectionGadgetsBundle" key="overly.strong.type.cast.display.name"
                      groupBundle="messages.InspectionsBundle" groupKey="group.names.abstraction.issues" enabledByDefault="false"
                      level="WARNING" implementationClass="com.siyeh.ig.abstraction.OverlyStrongTypeCastInspection"/>
                      level="WARNING" implementationClass="com.siyeh.ig.threading.AwaitNotInLoopInspection"/>
     <localInspection groupPath="Java" language="JAVA" shortName="AtomicFieldUpdaterIssues" bundle="com.siyeh.InspectionGadgetsBundle"
                      key="atomic.field.updater.issues.display.name" groupBundle="messages.InspectionsBundle"
-                     groupKey="group.names.threading.issues" enabledByDefault="false" level="WARNING"
+                     groupKey="group.names.threading.issues" enabledByDefault="true" level="WARNING"
                      implementationClass="com.siyeh.ig.threading.AtomicFieldUpdaterIssuesInspection"/>
     <localInspection groupPath="Java" language="JAVA" shortName="AtomicFieldUpdaterNotStaticFinal" bundle="com.siyeh.InspectionGadgetsBundle"
                      key="atomic.field.updater.not.static.final.display.name" groupBundle="messages.InspectionsBundle"
-                     groupKey="group.names.threading.issues" enabledByDefault="false" level="WARNING"
+                     groupKey="group.names.threading.issues" enabledByDefault="true" level="WARNING"
                      implementationClass="com.siyeh.ig.threading.AtomicFieldUpdaterNotStaticFinalInspection"/>
     <localInspection groupPath="Java" language="JAVA" shortName="AwaitWithoutCorrespondingSignal" bundle="com.siyeh.InspectionGadgetsBundle"
                      key="await.without.corresponding.signal.display.name" groupBundle="messages.InspectionsBundle"
index 284e38e0f2ba56eb49465c7ba3531365d8844161..c58420cb554aedeffa32b62eba01670e5ca00c97 100644 (file)
@@ -154,7 +154,8 @@ return.of.null.quickfix=Annotate method as @Nullable
 return.of.null.objects.option=Report methods that return objects
 return.of.null.collections.option=Report methods that return collection objects
 return.of.null.ignore.private.option=Ignore private methods
-return.of.null.optional.quickfix=Replace with 'Optional.empty()'
+return.of.null.optional.quickfix=Replace with ''{0}.empty()''
+return.of.null.optional.quickfix.family=Replace with 'Optional.empty()'
 static.method.via.subclass.display.name=Static method referenced via subclass
 static.method.via.subclass.problem.descriptor=Static method <code>#ref()</code> declared in class ''{0}'' but referenced via subclass ''{1}'' #loc
 static.method.via.subclass.rationalize.quickfix=Rationalize static method call
@@ -2158,4 +2159,7 @@ private.field.not.accessible.problem.descriptor=''private'' field ''{0}'' is not
 package.local.field.not.accessible=package local field ''{0}'' is not accessible from here
 protected.field.not.accessible.problem.descriptor=''protected'' field ''{0}'' is not accessible from here
 interface.clashes.with.object.class.display.name=Interface method clashes with method in 'java.lang.Object'
-interface.clashes.with.object.class.problem.descriptor=<code>#ref()</code> clashes with method in 'java.lang.Object'
\ No newline at end of file
+interface.clashes.with.object.class.problem.descriptor=<code>#ref()</code> clashes with method in 'java.lang.Object'
+optional.used.as.field.or.parameter.type.display.name='java.util.Optional<T>' used as field or parameter type
+optional.used.as.field.type.problem.descriptor=<code>#ref</code> used as type for field ''{0}''
+optional.used.as.parameter.type.problem.descriptor=<code>#ref</code> used as type for parameter ''{0}''
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OptionalUsedAsFieldOrParameterTypeInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/OptionalUsedAsFieldOrParameterTypeInspection.java
new file mode 100644 (file)
index 0000000..318600c
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * 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.siyeh.ig.abstraction;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiParameter;
+import com.intellij.psi.PsiTypeElement;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.BaseInspection;
+import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.psiutils.TypeUtils;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class OptionalUsedAsFieldOrParameterTypeInspection extends BaseInspection {
+
+  @Nls
+  @NotNull
+  @Override
+  public String getDisplayName() {
+    return InspectionGadgetsBundle.message("optional.used.as.field.or.parameter.type.display.name");
+  }
+
+  @NotNull
+  @Override
+  protected String buildErrorString(Object... infos) {
+    final PsiTypeElement typeElement = (PsiTypeElement)infos[0];
+    final PsiElement parent = typeElement.getParent();
+    if (parent instanceof PsiField) {
+      final PsiField field = (PsiField)parent;
+      return InspectionGadgetsBundle.message("optional.used.as.field.type.problem.descriptor", field.getName());
+    }
+    else if (parent instanceof PsiParameter) {
+      final PsiParameter parameter = (PsiParameter)parent;
+      return InspectionGadgetsBundle.message("optional.used.as.parameter.type.problem.descriptor", parameter.getName());
+    }
+    throw new AssertionError();
+  }
+
+  @Override
+  public BaseInspectionVisitor buildVisitor() {
+    return new OptionUsedAsFieldOrParameterTypeVisitor();
+  }
+
+  private static class OptionUsedAsFieldOrParameterTypeVisitor extends BaseInspectionVisitor {
+
+    @Override
+    public void visitField(PsiField field) {
+      super.visitField(field);
+      checkTypeElement(field.getTypeElement());
+    }
+
+    @Override
+    public void visitParameter(PsiParameter parameter) {
+      super.visitParameter(parameter);
+      checkTypeElement(parameter.getTypeElement());
+    }
+
+    private void checkTypeElement(PsiTypeElement typeElement) {
+      if (typeElement == null || !TypeUtils.isOptional(typeElement.getType())) {
+        return;
+      }
+      registerError(typeElement, typeElement);
+    }
+  }
+}
index 8bcf1ef776d8ef450620d9726d4290d857ad35fa..18f40ef33a8f4c2475176f5a7743590cdf42e8ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import com.siyeh.ig.BaseInspectionVisitor;
 import com.siyeh.ig.DelegatingFix;
 import com.siyeh.ig.InspectionGadgetsFix;
 import com.siyeh.ig.psiutils.ParenthesesUtils;
+import com.siyeh.ig.psiutils.TypeUtils;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
@@ -43,29 +44,31 @@ public class AssignmentToNullInspection extends BaseInspection {
   @Override
   @NotNull
   public String buildErrorString(Object... infos) {
-    return InspectionGadgetsBundle.message(
-      "assignment.to.null.problem.descriptor");
+    return InspectionGadgetsBundle.message("assignment.to.null.problem.descriptor");
   }
 
   @Override
   protected InspectionGadgetsFix buildFix(Object... infos) {
-    final Object info = infos[0];
-    if (!(info instanceof PsiReferenceExpression)) {
+    final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)infos[0];
+    if (TypeUtils.isOptional(referenceExpression.getType())) {
       return null;
     }
-    final PsiElement target = ((PsiReferenceExpression)info).resolve();
+    final PsiElement target = referenceExpression.resolve();
     if (!(target instanceof PsiVariable)) {
       return null;
     }
+    final PsiVariable variable = (PsiVariable)target;
+    if (NullableNotNullManager.isNotNull(variable)) {
+      return null;
+    }
     final NullableNotNullManager manager = NullableNotNullManager.getInstance(target.getProject());
-    return new DelegatingFix(new AddAnnotationPsiFix(manager.getDefaultNullable(), (PsiVariable)target,PsiNameValuePair.EMPTY_ARRAY));
+    return new DelegatingFix(new AddAnnotationPsiFix(manager.getDefaultNullable(), variable, PsiNameValuePair.EMPTY_ARRAY));
   }
 
   @Override
   public JComponent createOptionsPanel() {
     return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message(
-      "assignment.to.null.option"), this,
-                                          "ignoreAssignmentsToFields");
+      "assignment.to.null.option"), this, "ignoreAssignmentsToFields");
   }
 
   @Override
index 86b110da07018047c23e5e1fe38f12c98733c233..fcdd472fd35ced9f19416b54245f7f05ebb1c923 100644 (file)
@@ -23,11 +23,11 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.ArrayUtil;
 import com.siyeh.InspectionGadgetsBundle;
 import com.siyeh.ig.*;
 import com.siyeh.ig.psiutils.CollectionUtils;
+import com.siyeh.ig.psiutils.TypeUtils;
 import org.intellij.lang.annotations.Pattern;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
@@ -80,10 +80,10 @@ public class ReturnNullInspectionBase extends BaseInspection {
     }
     if (element instanceof PsiMethod) {
       final PsiMethod method = (PsiMethod)element;
-      final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(method.getReturnType());
-      if (aClass != null && CommonClassNames.JAVA_UTIL_OPTIONAL.equals(aClass.getQualifiedName())) {
+      final PsiType type = method.getReturnType();
+      if (TypeUtils.isOptional(type)) {
         // don't suggest to annotate Optional methods as Nullable
-        return new ReplaceWithEmptyOptionalFix();
+        return new ReplaceWithEmptyOptionalFix(((PsiClassType)type).rawType().getCanonicalText());
       }
     }
 
@@ -99,18 +99,25 @@ public class ReturnNullInspectionBase extends BaseInspection {
   }
 
   private static class ReplaceWithEmptyOptionalFix extends InspectionGadgetsFix {
+
+    private final String myTypeText;
+
+    public ReplaceWithEmptyOptionalFix(String typeText) {
+      myTypeText = typeText;
+    }
+
     @Nls
     @NotNull
     @Override
     public String getName() {
-      return InspectionGadgetsBundle.message("return.of.null.optional.quickfix");
+      return InspectionGadgetsBundle.message("return.of.null.optional.quickfix", myTypeText);
     }
 
     @Nls
     @NotNull
     @Override
     public String getFamilyName() {
-      return getName();
+      return InspectionGadgetsBundle.message("return.of.null.optional.quickfix.family");
     }
 
     @Override
@@ -120,7 +127,7 @@ public class ReturnNullInspectionBase extends BaseInspection {
         return;
       }
       final PsiLiteralExpression literalExpression = (PsiLiteralExpression)element;
-      PsiReplacementUtil.replaceExpression(literalExpression, "java.util.Optional.empty()");
+      PsiReplacementUtil.replaceExpression(literalExpression, myTypeText + ".empty()");
     }
   }
 
@@ -187,8 +194,7 @@ public class ReturnNullInspectionBase extends BaseInspection {
         return;
       }
 
-      final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(returnType);
-      if (aClass != null && "java.util.Optional".equals(aClass.getQualifiedName())) {
+      if (TypeUtils.isOptional(returnType)) {
         registerError(value, value);
         return;
       }
index 3cc581a6eaa62cedbbd214979d4bc7de038d8259..7d274a5f483d7d8258d0efa225cc446adad750d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
  *
  * 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 @@ import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiUtil;
 import com.intellij.psi.util.TypeConversionUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -83,6 +84,18 @@ public class TypeUtils {
     return typeEquals(CommonClassNames.JAVA_LANG_STRING, targetType);
   }
 
+  public static boolean isOptional(@Nullable PsiType type) {
+    final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type);
+    if (aClass == null) {
+      return false;
+    }
+    final String qualifiedName = aClass.getQualifiedName();
+    return CommonClassNames.JAVA_UTIL_OPTIONAL.equals(qualifiedName)
+           || "java.util.OptionalDouble".equals(qualifiedName)
+           || "java.util.OptionalInt".equals(qualifiedName)
+           || "java.util.OptionalLong".equals(qualifiedName);
+  }
+
   public static boolean isExpressionTypeAssignableWith(@NotNull PsiExpression expression, @NotNull Iterable<String> rhsTypeTexts) {
     final PsiType type = expression.getType();
     if (type == null) {
@@ -107,7 +120,7 @@ public class TypeUtils {
     if (expression == null) {
       return null;
     }
-    PsiType type = expression instanceof PsiFunctionalExpression ? ((PsiFunctionalExpression)expression).getFunctionalInterfaceType() 
+    PsiType type = expression instanceof PsiFunctionalExpression ? ((PsiFunctionalExpression)expression).getFunctionalInterfaceType()
                                                                  : expression.getType();
     if (type == null) {
       return null;
diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OptionalUsedAsFieldOrParameterType.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OptionalUsedAsFieldOrParameterType.html
new file mode 100644 (file)
index 0000000..15a9b56
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+<body>
+Reports any uses of <b>java.util.Optional&lt;T&gt;</b>, <b>java.util.OptionalDouble</b>, <b>java.util.OptionalInt</b> or
+<b>java.util.OptionalLong</b> as the type for a field or a parameter.
+Optional was designed to provide a limited mechanism for library method return types where there needed
+to be a clear way to represent "no result".
+Using a field with type Optional is also problematic if the class needs to be <b>Serializable</b>, which Optional isn't.
+<!-- tooltip end -->
+<p>
+<small>New in 16</small>
+</body>
+</html>
\ No newline at end of file
similarity index 55%
rename from plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/AssignmentToNullInspection.java
rename to plugins/InspectionGadgets/test/com/siyeh/igtest/assignment/assignment_to_null/AssignmentToNull.java
index 2c89c12f4d209859cf7bf0af40efa03fba23cbbd..b707992a79dbea0f72da0959d7ee900646a0a69c 100644 (file)
@@ -1,15 +1,15 @@
 package com.siyeh.igtest.bugs;
 
-public class AssignmentToNullInspection
+public class AssignmentToNull
 {
     private Object m_foo = null;
 
     public static void main(String[] args)
     {
-        new AssignmentToNullInspection(new Object()).bar();
+        new AssignmentToNull(new Object()).bar();
     }
 
-    public AssignmentToNullInspection(Object foo)
+    public AssignmentToNull(Object foo)
     {
         m_foo = foo;
     }
@@ -18,8 +18,8 @@ public class AssignmentToNullInspection
     {
         Object foo = new Object();
         System.out.println("foo = " + foo);
-        foo = null;
-        m_foo = null;
+        <warning descr="Assignment of variable 'foo' to 'null'">foo</warning> = null;
+        <warning descr="Assignment of variable 'm_foo' to 'null'">m_foo</warning> = null;
         System.out.println("foo = " + foo);
         System.out.println("m_foo = " + m_foo);
     }
index a989d40f197f0dff4c370be63d26183b2689fd94..e072d27ccb81a76a4154a475fd2f79208fe9a8bf 100644 (file)
@@ -1,4 +1,5 @@
 import java.util.Optional;
+import java.util.OptionalInt;
 
 class WarnOptional {
 
@@ -6,6 +7,10 @@ class WarnOptional {
     return <warning descr="Return of 'null'">null</warning>;
   }
 
+  public OptionalInt nothing() {
+    return <warning descr="Return of 'null'">null</warning>;
+  }
+
   Object give() {
     return null;
   }
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OptionalUsedAsFieldOrParameterTypeInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/OptionalUsedAsFieldOrParameterTypeInspectionTest.java
new file mode 100644 (file)
index 0000000..0a9770c
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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.siyeh.ig.abstraction;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class OptionalUsedAsFieldOrParameterTypeInspectionTest extends LightInspectionTestCase {
+
+  public void testOptionalField() {
+    doTest("import java.util.Optional;" +
+           "class X {" +
+           "  private /*'Optional<String>' used as type for field 's'*/Optional<String>/**/ s;" +
+           "}");
+  }
+
+  public void testOptionalParameter() {
+    doTest("import java.util.Optional;" +
+           "class X {" +
+           "  void m(/*'Optional<Object>' used as type for parameter 'o'*/Optional<Object>/**/ o) {}" +
+           "}");
+  }
+
+  public void testOptionalDoubleField() {
+    doTest("import java.util.OptionalDouble;" +
+           "class X {" +
+           "  private /*'OptionalDouble' used as type for field 'd'*/OptionalDouble/**/ d;" +
+           "}");
+  }
+
+  public void testNoWarnOnOptionalReturnType() {
+    doTest("import java.util.Optional;" +
+           "class X {" +
+           "  Optional<Integer> f() {" +
+           "    return null; // don't do this\n" +
+           "  }" +
+           "}");
+  }
+
+  @Nullable
+  @Override
+  protected InspectionProfileEntry getInspection() {
+    return new OptionalUsedAsFieldOrParameterTypeInspection();
+  }
+
+  @Override
+  protected String[] getEnvironmentClasses() {
+    return new String[] {
+      "package java.util;" +
+      "public final class Optional<T> {}",
+
+      "package java.util;" +
+      "public final class OptionalDouble {}"
+    };
+  }
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToNullInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/assignment/AssignmentToNullInspectionTest.java
new file mode 100644 (file)
index 0000000..c43e450
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.siyeh.ig.assignment;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+import junit.framework.TestCase;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class AssignmentToNullInspectionTest extends LightInspectionTestCase {
+
+  public void testAssignmentToNull() {
+    doTest();
+  }
+
+  @Nullable
+  @Override
+  protected InspectionProfileEntry getInspection() {
+    return new AssignmentToNullInspection();
+  }
+}
\ No newline at end of file
index 36cb5a0ae580784997aa4638b102d7718854e75d..b4678553d5291dc21431ae7bf8a9a142a525d466 100644 (file)
@@ -45,7 +45,10 @@ public class ReturnNullInspectionTest extends LightInspectionTestCase {
   protected String[] getEnvironmentClasses() {
     return new String[] {
       "package java.util;" +
-      "public final class Optional<T> {}"
+      "public final class Optional<T> {}",
+
+      "package java.util;" +
+      "public final class OptionalInt {}"
     };
   }
 }
\ No newline at end of file
index d261de41faea7ad572dd012bf21c3f1ebcb542bd..d41b3c4413f9f9a29358b97e269e20f0fc0e0b00 100644 (file)
 
     <fileTypeFactory implementation="git4idea.vfs.GitFileTypeFactory"/>
     <vcs.taskHandler implementation="git4idea.GitTaskHandler"/>
+
+    <logHighlighterFactory implementation="git4idea.branch.DeepComparator$Factory"/>
   </extensions>
 
   <extensionPoints>
index 970d06ec40dbd690b75873b65fa3906b670858f8..8ac75cf8fc12855210299a7538e4683345dcd74e 100644 (file)
@@ -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.
@@ -16,6 +16,7 @@
 package git4idea.branch;
 
 import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProgressIndicator;
@@ -28,75 +29,38 @@ import com.intellij.openapi.vcs.VcsNotifier;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.vcs.log.*;
+import com.intellij.vcs.log.data.VcsLogDataHolder;
 import com.intellij.vcs.log.impl.HashImpl;
 import com.intellij.vcs.log.impl.VcsLogUtil;
 import com.intellij.vcs.log.ui.MergeCommitsHighlighter;
+import com.intellij.vcs.log.ui.VcsLogHighlighterFactory;
 import git4idea.GitBranch;
 import git4idea.commands.GitCommand;
 import git4idea.commands.GitLineHandler;
 import git4idea.commands.GitLineHandlerAdapter;
 import git4idea.repo.GitRepository;
 import git4idea.repo.GitRepositoryManager;
-import gnu.trove.TIntHashSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Map;
+import java.util.Set;
 
-public class DeepComparator implements Disposable {
-
+public class DeepComparator implements VcsLogHighlighter, Disposable {
   private static final Logger LOG = Logger.getInstance(DeepComparator.class);
 
   @NotNull private final Project myProject;
   @NotNull private final GitRepositoryManager myRepositoryManager;
   @NotNull private final VcsLogUi myUi;
-  @NotNull private final VcsLogListener myLogListener;
 
-  @Nullable private VcsLogHighlighter myHighlighter;
   @Nullable private MyTask myTask;
+  @Nullable private Set<CommitId> myNonPickedCommits;
 
-  @NotNull
-  public static DeepComparator getInstance(@NotNull Project project, @NotNull VcsLogUi ui) {
-    DeepComparatorHolder holder = ServiceManager.getService(project, DeepComparatorHolder.class);
-    return holder.getInstance(ui);
-  }
-
-  DeepComparator(@NotNull Project project, @NotNull GitRepositoryManager manager, @NotNull VcsLogUi ui, @NotNull Disposable parent) {
+  public DeepComparator(@NotNull Project project, @NotNull GitRepositoryManager manager, @NotNull VcsLogUi ui, @NotNull Disposable parent) {
     myProject = project;
     myRepositoryManager = manager;
     myUi = ui;
     Disposer.register(parent, this);
-
-    myLogListener = new VcsLogListener() {
-      @Override
-      public void onChange(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
-        if (myTask == null) { // no task in progress => not interested in refresh events
-          return;
-        }
-
-        if (refreshHappened) {
-          // collect data
-          String comparedBranch = myTask.myComparedBranch;
-          Map<GitRepository, GitBranch> repositoriesWithCurrentBranches = myTask.myRepositoriesWithCurrentBranches;
-          VcsLogDataProvider provider = myTask.myProvider;
-
-          stopTask();
-
-          // highlight again
-          Map<GitRepository, GitBranch> repositories = getRepositories(myUi.getDataPack().getLogProviders(), comparedBranch);
-          if (repositories.equals(repositoriesWithCurrentBranches)) { // but not if current branch changed
-            highlightInBackground(comparedBranch, provider);
-          }
-        }
-        else {
-          VcsLogBranchFilter branchFilter = myUi.getFilterUi().getFilters().getBranchFilter();
-          if (branchFilter == null || !myTask.myComparedBranch.equals(VcsLogUtil.getSingleFilteredBranch(branchFilter, myUi.getDataPack().getRefs()))) {
-            stopAndUnhighlight();
-          }
-        }
-      }
-    };
-    myUi.addLogListener(myLogListener);
   }
 
   public void highlightInBackground(@NotNull String branchToCompare, @NotNull VcsLogDataProvider dataProvider) {
@@ -111,7 +75,7 @@ public class DeepComparator implements Disposable {
       return;
     }
 
-    myTask = new MyTask(myProject, myUi, repositories, dataProvider, branchToCompare);
+    myTask = new MyTask(myProject, repositories, dataProvider, branchToCompare);
     myTask.queue();
   }
 
@@ -143,41 +107,104 @@ public class DeepComparator implements Disposable {
   }
 
   private void removeHighlighting() {
-    if (myHighlighter != null) {
-      myUi.removeHighlighter(myHighlighter);
-    }
+    ApplicationManager.getApplication().assertIsDispatchThread();
+    myNonPickedCommits = null;
   }
 
   @Override
   public void dispose() {
     stopAndUnhighlight();
-    myUi.removeLogListener(myLogListener);
   }
 
   public boolean hasHighlightingOrInProgress() {
     return myTask != null;
   }
 
+  public static DeepComparator getInstance(@NotNull Project project, @NotNull VcsLogUi logUi) {
+    return ServiceManager.getService(project, DeepComparatorHolder.class).getInstance(logUi);
+  }
+
+  @NotNull
+  @Override
+  public VcsLogHighlighter.VcsCommitStyle getStyle(@NotNull VcsShortCommitDetails commitDetails, boolean isSelected) {
+    if (myNonPickedCommits == null) return VcsCommitStyle.DEFAULT;
+    return VcsCommitStyleFactory.foreground(!myNonPickedCommits.contains(new CommitId(commitDetails.getId(), commitDetails.getRoot()))
+                                            ? MergeCommitsHighlighter.MERGE_COMMIT_FOREGROUND
+                                            : null);
+  }
+
+  @Override
+  public void update(@NotNull VcsLogDataPack dataPack, boolean refreshHappened) {
+    if (myTask == null) { // no task in progress => not interested in refresh events
+      return;
+    }
+
+    if (refreshHappened) {
+      // collect data
+      String comparedBranch = myTask.myComparedBranch;
+      Map<GitRepository, GitBranch> repositoriesWithCurrentBranches = myTask.myRepositoriesWithCurrentBranches;
+      VcsLogDataProvider provider = myTask.myProvider;
+
+      stopTask();
+
+      // highlight again
+      Map<GitRepository, GitBranch> repositories = getRepositories(dataPack.getLogProviders(), comparedBranch);
+      if (repositories.equals(repositoriesWithCurrentBranches)) { // but not if current branch changed
+        highlightInBackground(comparedBranch, provider);
+      }
+    }
+    else {
+      VcsLogBranchFilter branchFilter = dataPack.getFilters().getBranchFilter();
+      if (branchFilter == null || !myTask.myComparedBranch.equals(VcsLogUtil.getSingleFilteredBranch(branchFilter, dataPack.getRefs()))) {
+        stopAndUnhighlight();
+      }
+    }
+  }
+
+  public static class Factory implements VcsLogHighlighterFactory {
+    @NotNull private static final String ID = "CHERRY_PICKED_COMMITS";
+
+    @NotNull
+    @Override
+    public VcsLogHighlighter createHighlighter(@NotNull VcsLogDataHolder logDataHolder, @NotNull VcsLogUi logUi) {
+      return getInstance(logDataHolder.getProject(), logUi);
+    }
+
+    @NotNull
+    @Override
+    public String getId() {
+      return ID;
+    }
+
+    @NotNull
+    @Override
+    public String getTitle() {
+      return "Cherry Picked Commits";
+    }
+
+    @Override
+    public boolean showMenuItem() {
+      return false;
+    }
+  }
+
   private class MyTask extends Task.Backgroundable {
 
     @NotNull private final Project myProject;
-    @NotNull private final VcsLogUi myUi;
     @NotNull private final Map<GitRepository, GitBranch> myRepositoriesWithCurrentBranches;
     @NotNull private final VcsLogDataProvider myProvider;
     @NotNull private final String myComparedBranch;
 
-    @NotNull private final TIntHashSet myNonPickedCommits = new TIntHashSet();
+    @NotNull private final Set<CommitId> myCollectedNonPickedCommits = ContainerUtil.newHashSet();
     @Nullable private VcsException myException;
     private boolean myCancelled;
 
     public MyTask(@NotNull Project project,
-                  @NotNull VcsLogUi ui,
                   @NotNull Map<GitRepository, GitBranch> repositoriesWithCurrentBranches,
                   @NotNull VcsLogDataProvider dataProvider,
                   @NotNull String branchToCompare) {
       super(project, "Comparing Branches...");
       myProject = project;
-      myUi = ui;
       myRepositoriesWithCurrentBranches = repositoriesWithCurrentBranches;
       myProvider = dataProvider;
       myComparedBranch = branchToCompare;
@@ -189,8 +216,8 @@ public class DeepComparator implements Disposable {
         for (Map.Entry<GitRepository, GitBranch> entry : myRepositoriesWithCurrentBranches.entrySet()) {
           GitRepository repo = entry.getKey();
           GitBranch currentBranch = entry.getValue();
-          myNonPickedCommits
-            .addAll(getNonPickedCommitsFromGit(myProject, repo.getRoot(), myProvider, currentBranch.getName(), myComparedBranch).toArray());
+          myCollectedNonPickedCommits
+            .addAll(getNonPickedCommitsFromGit(myProject, repo.getRoot(), currentBranch.getName(), myComparedBranch));
         }
       }
       catch (VcsException e) {
@@ -211,16 +238,7 @@ public class DeepComparator implements Disposable {
         VcsNotifier.getInstance(myProject).notifyError("Couldn't compare with branch " + myComparedBranch, myException.getMessage());
         return;
       }
-
-      myHighlighter = new VcsLogHighlighter() {
-        @NotNull
-        @Override
-        public VcsCommitStyle getStyle(int commitIndex, boolean isSelected) {
-          return VcsCommitStyleFactory
-            .foreground(!myNonPickedCommits.contains(commitIndex) ? MergeCommitsHighlighter.MERGE_COMMIT_FOREGROUND : null);
-        }
-      };
-      myUi.addHighlighter(myHighlighter);
+      myNonPickedCommits = myCollectedNonPickedCommits;
     }
 
     public void cancel() {
@@ -228,15 +246,14 @@ public class DeepComparator implements Disposable {
     }
 
     @NotNull
-    private TIntHashSet getNonPickedCommitsFromGit(@NotNull Project project,
-                                                   @NotNull final VirtualFile root,
-                                                   @NotNull final VcsLogDataProvider dataProvider,
-                                                   @NotNull String currentBranch,
-                                                   @NotNull String comparedBranch) throws VcsException {
+    private Set<CommitId> getNonPickedCommitsFromGit(@NotNull Project project,
+                                                     @NotNull final VirtualFile root,
+                                                     @NotNull String currentBranch,
+                                                     @NotNull String comparedBranch) throws VcsException {
       GitLineHandler handler = new GitLineHandler(project, root, GitCommand.CHERRY);
       handler.addParameters(currentBranch, comparedBranch); // upstream - current branch; head - compared branch
 
-      final TIntHashSet pickedCommits = new TIntHashSet();
+      final Set<CommitId> pickedCommits = ContainerUtil.newHashSet();
       handler.addLineListener(new GitLineHandlerAdapter() {
         @Override
         public void onLineAvailable(String line, Key outputType) {
@@ -250,7 +267,7 @@ public class DeepComparator implements Disposable {
                 line = line.substring(0, firstSpace); // safety-check: take just the first word for sure
               }
               Hash hash = HashImpl.build(line);
-              pickedCommits.add(dataProvider.getCommitIndex(hash, root));
+              pickedCommits.add(new CommitId(hash, root));
             }
             catch (Exception e) {
               LOG.error("Couldn't parse line [" + line + "]");
@@ -263,5 +280,4 @@ public class DeepComparator implements Disposable {
     }
 
   }
-
-}
+}
\ No newline at end of file
index 6da2d0aa50e7a861874ff31d5069295946041713..d52ef269c11b6c224586305ffc480f9d7e2bd10a 100644 (file)
@@ -1,3 +1,18 @@
+/*
+ * 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 org.jetbrains.plugins.groovy.mvc;
 
 import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -15,7 +30,7 @@ public class MvcActionGroup extends DefaultActionGroup implements DumbAware {
 
     Pair<MvcFramework, Module> pair = MvcActionBase.guessFramework(e);
 
-    if (pair != null) {
+    if (pair != null && pair.first.showActionGroup()) {
       presentation.setVisible(true);
       presentation.setText(pair.getFirst().getDisplayName());
       presentation.setIcon(pair.getFirst().getIcon());
index 69828752ea95ddfd00efd19fc3085824ad11cf80..4c7b68c1bd9111bcb96fe6452d723ffe5caf91bd 100644 (file)
@@ -672,4 +672,8 @@ public abstract class MvcFramework {
     }
     return null;
   }
+
+  public boolean showActionGroup() {
+    return true;
+  }
 }
index b301f0496da3ee78528db2761135162b11fcb394..5f073d88ef6967af62c1d8f077b2b399a1761054 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * 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.
@@ -21,21 +21,20 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder;
 import com.intellij.codeInsight.lookup.TailTypeDecorator;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.module.Module;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.UserDataHolderEx;
+import com.intellij.openapi.util.NotNullLazyValue;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.JavaPsiFacade;