From 4d13fc78262c364c9bde033e4fdc98899b61f3c4 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 25 Nov 2014 15:45:58 +0100 Subject: [PATCH 01/38] do not schedule unnecessary recompilation on duplicate-class check; fix data loss in classToSourceFile mapping after moving top-level class from one file to another file --- .../incremental/common/moveClassToAnotherRoot.log | 12 ++++++++++++ .../common/moveClassToAnotherRoot/.idea/misc.xml | 13 +++++++++++++ .../moveClassToAnotherRoot/.idea/modules.xml | 9 +++++++++ .../moveClassToAnotherRoot.iml | 14 ++++++++++++++ .../common/moveClassToAnotherRoot/src/pkg/A.java | 4 ++++ .../moveClassToAnotherRoot/src/pkg/A.java.remove | 0 .../moveClassToAnotherRoot/src/pkg/Client.java | 6 ++++++ .../moveClassToAnotherRoot/src2/pkg/A.java.new | 4 ++++ .../common/moveToplevelClassToAnotherFile.log | 9 +++++++++ .../moveToplevelClassToAnotherFile/src/pkg/A.java | 9 +++++++++ .../src/pkg/A.java.new | 5 +++++ .../moveToplevelClassToAnotherFile/src/pkg/B.java | 5 +++++ .../src/pkg/B.java.new | 9 +++++++++ .../jps/builders/java/dependencyView/Mappings.java | 11 +++++++++-- .../testSrc/org/jetbrains/ether/CommonTest.java | 8 ++++++++ 15 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot.log create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/.idea/misc.xml create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/.idea/modules.xml create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/moveClassToAnotherRoot.iml create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/A.java create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/A.java.remove create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/Client.java create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src2/pkg/A.java.new create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile.log create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/A.java create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/A.java.new create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/B.java create mode 100644 java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/B.java.new diff --git a/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot.log b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot.log new file mode 100644 index 000000000000..f16383a14224 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot.log @@ -0,0 +1,12 @@ +Cleaning output files: +out/production/moveClassToAnotherRoot/pkg/A.class +End of files +Compiling files: +src2/pkg/A.java +End of files +Cleaning output files: +out/production/moveClassToAnotherRoot/pkg/Client.class +End of files +Compiling files: +src/pkg/Client.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/.idea/misc.xml b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/.idea/misc.xml new file mode 100644 index 000000000000..9a249d2930c5 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + http://www.w3.org/1999/xhtml + + + + + + diff --git a/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/.idea/modules.xml b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/.idea/modules.xml new file mode 100644 index 000000000000..867c25e6704a --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/moveClassToAnotherRoot.iml b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/moveClassToAnotherRoot.iml new file mode 100644 index 000000000000..119c6ef0a879 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/moveClassToAnotherRoot.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/A.java b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/A.java new file mode 100644 index 000000000000..23093a48b165 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/A.java @@ -0,0 +1,4 @@ +package pkg; +public class A { + public static void foo() {} +} diff --git a/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/A.java.remove b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/A.java.remove new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/Client.java b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/Client.java new file mode 100644 index 000000000000..5147dd4705da --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src/pkg/Client.java @@ -0,0 +1,6 @@ +package pkg; +public class Client { + public static void main(String[] args) { + A.foo(); + } +} diff --git a/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src2/pkg/A.java.new b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src2/pkg/A.java.new new file mode 100644 index 000000000000..23093a48b165 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveClassToAnotherRoot/src2/pkg/A.java.new @@ -0,0 +1,4 @@ +package pkg; +public class A { + public static void foo() {} +} diff --git a/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile.log b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile.log new file mode 100644 index 000000000000..e799faeac6fa --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile.log @@ -0,0 +1,9 @@ +Cleaning output files: +out/production/MoveToplevelClassToAnotherFile/pkg/A.class +out/production/MoveToplevelClassToAnotherFile/pkg/B.class +out/production/MoveToplevelClassToAnotherFile/pkg/Local.class +End of files +Compiling files: +src/pkg/A.java +src/pkg/B.java +End of files diff --git a/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/A.java b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/A.java new file mode 100644 index 000000000000..8e27924d3577 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/A.java @@ -0,0 +1,9 @@ +package pkg; + +public class A { + +} + +class Local { + +} \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/A.java.new b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/A.java.new new file mode 100644 index 000000000000..da82dd784a15 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/A.java.new @@ -0,0 +1,5 @@ +package pkg; + +public class A { + +} diff --git a/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/B.java b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/B.java new file mode 100644 index 000000000000..654872faff47 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/B.java @@ -0,0 +1,5 @@ +package pkg; + +public class B { + +} diff --git a/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/B.java.new b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/B.java.new new file mode 100644 index 000000000000..ce93a37ef7c1 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/moveToplevelClassToAnotherFile/src/pkg/B.java.new @@ -0,0 +1,9 @@ +package pkg; + +public class B { + +} + +class Local { + +} \ No newline at end of file diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java index c47c4c9e6ec4..c17bba46eb92 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java @@ -237,8 +237,15 @@ public class Mappings { private void runPostPasses() { final Set> deleted = myDeletedClasses; if (deleted != null) { + final TIntHashSet added = new TIntHashSet(); + for (ClassRepr aClass : myAddedClasses) { + added.add(aClass.name); + } for (Pair pair : deleted) { - myChangedClasses.remove(pair.first.name); + final int deletedClassName = pair.first.name; + if (!added.contains(deletedClassName)) { + myChangedClasses.remove(deletedClassName); + } } } for (Runnable pass = myPostPasses.poll(); pass != null; pass = myPostPasses.poll()) { @@ -1864,7 +1871,7 @@ public class Mappings { final Collection currentSources = myClassToSourceFile.get(c.name); final File currentlyMappedTo = currentSources != null && currentSources.size() == 1? currentSources.iterator().next() : null; // only check, if exactly one file is mapped - if (currentlyMappedTo != null && !FileUtil.filesEqual(currentlyMappedTo, srcFile) && currentlyMappedTo.exists() && myFilter.belongsToCurrentTargetChunk(currentlyMappedTo)) { + if (currentlyMappedTo != null && !myCompiledFiles.contains(currentlyMappedTo) && !FileUtil.filesEqual(currentlyMappedTo, srcFile) && currentlyMappedTo.exists() && myFilter.belongsToCurrentTargetChunk(currentlyMappedTo)) { // Same classes from different source files. // Schedule for recompilation both to make possible 'duplicate sources' error evident debug("Scheduling for recompilation duplicated sources: ", currentlyMappedTo.getPath() + "; " + srcFile.getPath()); diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java b/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java index 5373924c84b3..12b04ead7257 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java @@ -150,4 +150,12 @@ public class CommonTest extends IncrementalTestCase { doTestBuild(1).assertSuccessful(); } + public void testMoveToplevelClassToAnotherFile() throws Exception { + doTest(); + } + + public void testMoveClassToAnotherRoot() throws Exception { + doTest(); + } + } From 4b9a3302a1d25004fe4a105dc63ba1c3302a4eac Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 25 Nov 2014 17:56:48 +0300 Subject: [PATCH 02/38] EA-62739 - IAE: CompoundPositionManager$Cache.get --- .../com/intellij/debugger/engine/CompoundPositionManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java index 2fbe2813d04a..8b3fd4cbe3a7 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -59,6 +59,7 @@ public class CompoundPositionManager extends PositionManagerEx { @Override public SourcePosition getSourcePosition(Location location) { + if (location == null) return null; SourcePosition res = mySourcePositionCache.get(location); if (res != null) return res; From ffc5659933baba0f6d425fac27c14789ee389701 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Nov 2014 16:09:18 +0100 Subject: [PATCH 03/38] remove unused FileUtils.saveText --- .../src/com/intellij/xml/actions/xmlbeans/FileUtils.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/xml/impl/src/com/intellij/xml/actions/xmlbeans/FileUtils.java b/xml/impl/src/com/intellij/xml/actions/xmlbeans/FileUtils.java index 832364cbff92..9d274e6f929b 100644 --- a/xml/impl/src/com/intellij/xml/actions/xmlbeans/FileUtils.java +++ b/xml/impl/src/com/intellij/xml/actions/xmlbeans/FileUtils.java @@ -16,8 +16,6 @@ package com.intellij.xml.actions.xmlbeans; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NonNls; import java.io.*; @@ -62,11 +60,6 @@ public class FileUtils { return name + num + ext; } - - public static void saveText(VirtualFile virtualFile, String text) throws IOException { - VfsUtil.saveText(virtualFile, text); - } - public static boolean copyFile(File in, File out) { try { FileInputStream fis = new FileInputStream(in); From ca31b7ff3dab069dab9d816b70a60c376cdc64fc Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Nov 2014 16:09:58 +0100 Subject: [PATCH 04/38] deprecate and unuse FileContentUtil.setFileText --- .../intellij/util/descriptors/impl/ConfigFileFactoryImpl.java | 3 +-- platform/lang-api/src/com/intellij/util/FileContentUtil.java | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileFactoryImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileFactoryImpl.java index 18055679c355..64d5a3cd8973 100644 --- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileFactoryImpl.java +++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileFactoryImpl.java @@ -21,7 +21,6 @@ import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.util.FileContentUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.io.FileUtil; @@ -100,7 +99,7 @@ public class ConfigFileFactoryImpl extends ConfigFileFactory { else { childData = existingFile; } - FileContentUtil.setFileText(project, childData, text); + VfsUtil.saveText(childData, text); return childData; } catch (final IOException e) { diff --git a/platform/lang-api/src/com/intellij/util/FileContentUtil.java b/platform/lang-api/src/com/intellij/util/FileContentUtil.java index bbe9bf40896c..cee5410c55fe 100644 --- a/platform/lang-api/src/com/intellij/util/FileContentUtil.java +++ b/platform/lang-api/src/com/intellij/util/FileContentUtil.java @@ -39,6 +39,9 @@ import java.util.LinkedHashSet; */ public class FileContentUtil extends FileContentUtilCore { + /** + * @deprecated to be removed after IDEA 15. Use {@link VfsUtil#saveText(VirtualFile, String)} instead. + */ public static void setFileText(@Nullable Project project, final VirtualFile virtualFile, final String text) throws IOException { if (project == null) { project = ProjectUtil.guessProjectForFile(virtualFile); From 929722f0ebd18d986d9178e681b932710ebd500d Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 25 Nov 2014 18:35:38 +0300 Subject: [PATCH 05/38] Revert "[vcs] Add toggle button to hide unregistered roots from the table" This reverts commit 3ec8e6dcf3efdd9700ed1581f63db0d69f9bef92. The implementation is buggy, and the need for the button is questionable, so removing it until explicitly requested. --- .../openapi/vcs/VcsConfiguration.java | 1 - .../VcsDirectoryConfigurationPanel.java | 32 ++++++------------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java index 840452df22e9..0d2ad32a66ff 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsConfiguration.java @@ -94,7 +94,6 @@ public final class VcsConfiguration implements PersistentStateComponent(VcsBundle.message("column.info.configure.vcses.directory")) { @Override public MapInfo valueOf(final MapInfo mapping) { @@ -568,18 +565,7 @@ public class VcsDirectoryConfigurationPanel extends JPanel implements Configurab public boolean isEnabled(AnActionEvent e) { return !myIsDisabled && onlyRegisteredRootsInSelection(); } - }).disableUpDownActions().addExtraAction(new ToggleActionButton("Show unregistered roots", AllIcons.General.Filter) { - @Override - public boolean isSelected(AnActionEvent e) { - return myVcsConfiguration.SHOW_UNREGISTERED_ROOTS_IN_SETTINGS; - } - - @Override - public void setSelected(AnActionEvent e, boolean state) { - myVcsConfiguration.SHOW_UNREGISTERED_ROOTS_IN_SETTINGS = state; - myDirectoryMappingTable.repaint(); - } - }).createPanel(); + }).disableUpDownActions().createPanel(); panelForTable.setPreferredSize(new Dimension(-1, 200)); return panelForTable; } From 0b0bdf6e472c1980d6fdb12df5ecf5757b4750cd Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 25 Nov 2014 18:54:55 +0300 Subject: [PATCH 06/38] [log] IDEA-133197 repaint after expanding/collapsing branches runUnderModalProgress not only runs under a modal progress, but also prohibits repaint requests (because the graph can be in inconsistent state while it is changing in the background modal thread) => repaint request should be done outside of this call. --- .../src/com/intellij/vcs/log/ui/VcsLogUiImpl.java | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java index 834d2c62ec55..6bce603e90b4 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUiImpl.java @@ -149,14 +149,9 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable { @Override public void run() { myVisiblePack.getVisibleGraph().getActionController().setLinearBranchesExpansion(false); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - handleAnswer(null, true); - } - }); } }); + handleAnswer(null, true); } public void hideAll() { @@ -164,14 +159,9 @@ public class VcsLogUiImpl implements VcsLogUi, Disposable { @Override public void run() { myVisiblePack.getVisibleGraph().getActionController().setLinearBranchesExpansion(true); - UIUtil.invokeAndWaitIfNeeded(new Runnable() { - @Override - public void run() { - handleAnswer(null, true); - } - }); } }); + handleAnswer(null, true); } public void setLongEdgeVisibility(boolean visibility) { From bb227e674f004aeff1320f822d7a58f5eb9e0112 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Nov 2014 16:23:14 +0100 Subject: [PATCH 07/38] show preview during DnD of classes; avoid custom refactorings run (IDEA-133079) --- .../JavaMoveClassesOrPackagesHandler.java | 23 ++++-------- ...ClassesOrPackagesToNewDirectoryDialog.java | 37 ++++++++----------- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java index 037badd03eba..cc27b3298e60 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/JavaMoveClassesOrPackagesHandler.java @@ -32,6 +32,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.file.JavaDirectoryServiceImpl; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.move.MoveCallback; @@ -215,11 +216,11 @@ public class JavaMoveClassesOrPackagesHandler extends MoveHandlerDelegate { final MoveClassesOrPackagesToNewDirectoryDialog dlg = new MoveClassesOrPackagesToNewDirectoryDialog(directories[0], new PsiElement[0], false, callback) { @Override - protected void performRefactoring(Project project, - final PsiDirectory targetDirectory, - PsiPackage aPackage, - boolean searchInComments, - boolean searchForTextOccurences) { + protected BaseRefactoringProcessor createRefactoringProcessor(Project project, + final PsiDirectory targetDirectory, + PsiPackage aPackage, + boolean searchInComments, + boolean searchForTextOccurences) { try { for (PsiDirectory dir: directories) { MoveFilesOrDirectoriesUtil.checkIfMoveIntoSelf(dir, targetDirectory); @@ -227,17 +228,9 @@ public class JavaMoveClassesOrPackagesHandler extends MoveHandlerDelegate { } catch (IncorrectOperationException e) { Messages.showErrorDialog(project, e.getMessage(), RefactoringBundle.message("cannot.move")); - return; + return null; } - final MoveDirectoryWithClassesProcessor processor = - new MoveDirectoryWithClassesProcessor(project, directories, targetDirectory, searchInComments, searchForTextOccurences, - true, callback); - processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() { - @Override - public void run() { - } - }); - processor.run(); + return new MoveDirectoryWithClassesProcessor(project, directories, targetDirectory, searchInComments, searchForTextOccurences, true, callback); } }; dlg.show(); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java index de16039b99b2..2640b2492a34 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesToNewDirectoryDialog.java @@ -25,19 +25,16 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.refactoring.JavaRefactoringFactory; -import com.intellij.refactoring.JavaRefactoringSettings; -import com.intellij.refactoring.MoveDestination; -import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.*; import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.MoveHandler; +import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.ui.DocumentAdapter; import com.intellij.usageView.UsageViewUtil; import com.intellij.util.IncorrectOperationException; @@ -54,7 +51,7 @@ import java.util.Set; /** * @author ven */ -public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { +public class MoveClassesOrPackagesToNewDirectoryDialog extends RefactoringDialog { private static final Logger LOG = Logger.getInstance("com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesToNewDirectoryDialog"); private final PsiDirectory myDirectory; @@ -69,7 +66,7 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { public MoveClassesOrPackagesToNewDirectoryDialog(@NotNull final PsiDirectory directory, PsiElement[] elementsToMove, boolean canShowPreserveSourceRoots, final MoveCallback moveCallback) { - super(false); + super(directory.getProject(), false); setTitle(MoveHandler.REFACTORING_NAME); myDirectory = directory; myElementsToMove = elementsToMove; @@ -149,7 +146,8 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { return myRootPanel; } - protected void doOKAction() { + @Override + protected void doAction() { final String path = FileUtil.toSystemIndependentName(myDestDirectoryField.getText()); final Project project = myDirectory.getProject(); PsiDirectory directory = ApplicationManager.getApplication().runWriteAction(new Computable() { @@ -169,7 +167,6 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { return; } - super.doOKAction(); final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory); if (aPackage == null) { Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"), @@ -182,8 +179,7 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { final boolean searchForTextOccurences = isSearchInNonJavaFiles(); refactoringSettings.MOVE_SEARCH_IN_COMMENTS = searchInComments; refactoringSettings.MOVE_SEARCH_FOR_TEXT = searchForTextOccurences; - - performRefactoring(project, directory, aPackage, searchInComments, searchForTextOccurences); + invokeRefactoring(createRefactoringProcessor(project, directory, aPackage, searchInComments, searchForTextOccurences)); } @Override @@ -204,14 +200,16 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { searchInComments, searchInNonJavaFiles, moveCallback); } - protected void performRefactoring(Project project, PsiDirectory directory, PsiPackage aPackage, - boolean searchInComments, - boolean searchForTextOccurences) { + protected BaseRefactoringProcessor createRefactoringProcessor(Project project, + PsiDirectory directory, + PsiPackage aPackage, + boolean searchInComments, + boolean searchForTextOccurences) { final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(directory.getVirtualFile()); if (sourceRoot == null) { Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"), RefactoringBundle.message("cannot.move")); - return; + return null; } final JavaRefactoringFactory factory = JavaRefactoringFactory.getInstance(project); final MoveDestination destination = myPreserveSourceRoot.isSelected() && myPreserveSourceRoot.isVisible() @@ -222,14 +220,9 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper { searchInComments, searchForTextOccurences, myMoveCallback); if (processor.verifyValidPackageName()) { - processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() { - @Override - public void run() { - } - }); - - processor.run(); + return processor; } + return null; } } From 152df440c664b211d7fae1e6694da2cf83847ec9 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Nov 2014 16:28:21 +0100 Subject: [PATCH 08/38] method call type: erasure should not be applied if method doesn't have type params; < 1.8 (IDEA-132810) --- .../tree/java/PsiMethodCallExpressionImpl.java | 6 +++++- ...ConversionWasAppliedButNoTypeParamsProvided.java | 13 +++++++++++++ .../daemon/GenericsHighlightingTest.java | 4 ++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/MethodCallTypeNotErasedWhenUncheckedConversionWasAppliedButNoTypeParamsProvided.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java index d57fbf207830..9bbb90a677cd 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java @@ -17,6 +17,8 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.JavaVersionService; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.pom.java.LanguageLevel; @@ -226,7 +228,9 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements // If unchecked conversion was necessary for the method to be applicable, // the parameter types of the invocation type are the parameter types of the method's type, // and the return type and thrown types are given by the erasures of the return type and thrown types of the method's type. - if (result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isApplicable()) { + if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && + (method.hasTypeParameters() || JavaVersionService.getInstance().isAtLeast(call, JavaSdkVersion.JDK_1_8)) && + result instanceof MethodCandidateInfo && ((MethodCandidateInfo)result).isApplicable()) { final PsiType[] args = call.getArgumentList().getExpressionTypes(); final boolean allowUncheckedConversion = false; final int applicabilityLevel = PsiUtil.getApplicabilityLevel(method, substitutor, args, languageLevel, allowUncheckedConversion, true); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/MethodCallTypeNotErasedWhenUncheckedConversionWasAppliedButNoTypeParamsProvided.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/MethodCallTypeNotErasedWhenUncheckedConversionWasAppliedButNoTypeParamsProvided.java new file mode 100644 index 000000000000..6254e4e92bee --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/MethodCallTypeNotErasedWhenUncheckedConversionWasAppliedButNoTypeParamsProvided.java @@ -0,0 +1,13 @@ +import java.util.List; +import java.util.Set; + +class Test { + + void testCall(final Set set) { + for (String position : sortInvoice(set)) {} + } + + private List sortInvoice(Set set) { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 99b26e91ba0f..663f674e813b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -417,6 +417,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testMethodCallTypeErasedWhenUncheckedConversionWasAppliedDuringApplicabilityCheck() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + + public void testMethodCallTypeNotErasedWhenUncheckedConversionWasAppliedButNoTypeParamsProvided() { + doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); + } public void testInferredParameterInBoundsInRecursiveGenerics() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); From 770e56a58a043513de3837c7bb88c43441ee0f1f Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 25 Nov 2014 19:21:25 +0300 Subject: [PATCH 09/38] [git] IDEA-133309 Fix possible NPE Although the setter is @NotNull and default value is not null, myUpdateMethod can still receive a null due to our serialization engine problems => protect against this by reusing default value. --- .../git4idea/src/git4idea/settings/GitPushSettings.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/git4idea/src/git4idea/settings/GitPushSettings.java b/plugins/git4idea/src/git4idea/settings/GitPushSettings.java index 7c66919777bd..3de4e57bc573 100644 --- a/plugins/git4idea/src/git4idea/settings/GitPushSettings.java +++ b/plugins/git4idea/src/git4idea/settings/GitPushSettings.java @@ -17,6 +17,7 @@ package git4idea.settings; import com.intellij.openapi.components.*; import com.intellij.openapi.project.Project; +import com.intellij.util.ObjectUtils; import git4idea.config.UpdateMethod; import org.jetbrains.annotations.NotNull; @@ -26,11 +27,13 @@ import org.jetbrains.annotations.NotNull; @State(name = "Git.Push.Settings", storages = {@Storage(file = StoragePathMacros.WORKSPACE_FILE)}) public class GitPushSettings implements PersistentStateComponent { + private static final UpdateMethod DEFAULT_UPDATE_METHOD = UpdateMethod.MERGE; + private State myState = new State(); public static class State { public boolean myUpdateAllRoots = true; - public UpdateMethod myUpdateMethod = UpdateMethod.MERGE; + public UpdateMethod myUpdateMethod = DEFAULT_UPDATE_METHOD; } public static GitPushSettings getInstance(Project project) { @@ -57,7 +60,7 @@ public class GitPushSettings implements PersistentStateComponent Date: Tue, 25 Nov 2014 19:26:25 +0300 Subject: [PATCH 10/38] [git] IDEA-133368 Enable git add on new files Until we know about the index (and therefore know if the file is added+unstaged-modified) it's better to allow the action than to disable it. --- plugins/git4idea/src/git4idea/actions/GitAdd.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/actions/GitAdd.java b/plugins/git4idea/src/git4idea/actions/GitAdd.java index 498f1708919a..98d35f936928 100644 --- a/plugins/git4idea/src/git4idea/actions/GitAdd.java +++ b/plugins/git4idea/src/git4idea/actions/GitAdd.java @@ -22,7 +22,10 @@ public class GitAdd extends ScheduleForAdditionAction { @Override protected boolean isStatusForAddition(FileStatus status) { - return status == FileStatus.UNKNOWN || status == FileStatus.MODIFIED || status == FileStatus.MERGED_WITH_CONFLICTS; + return status == FileStatus.UNKNOWN || + status == FileStatus.MODIFIED || + status == FileStatus.MERGED_WITH_CONFLICTS || + status == FileStatus.ADDED; } } From 3d96a509dd2379f121926ae1003f0b2832d125f7 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 25 Nov 2014 19:35:11 +0300 Subject: [PATCH 11/38] [log] IDEA-116400 Cut the compound commit list after multi-repo join --- .../src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java index 2ac22a90511a..d578a9241204 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java @@ -97,7 +97,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { LogInfo data = loadRecentData(new CommitCountRequirements(myRecentCommitCount).asMap(myProviders.keySet())); Collection>> commits = data.getCommits(); Map> refs = data.getRefs(); - DataPack dataPack = DataPack.build(multiRepoJoin(commits), refs, myProviders, myHashMap, false); + List> compoundList = multiRepoJoin(commits); + compoundList = compoundList.subList(0, Math.min(myRecentCommitCount, compoundList.size())); + DataPack dataPack = DataPack.build(compoundList, refs, myProviders, myHashMap, false); mySingleTaskController.request(RefreshRequest.RELOAD_ALL); // build/rebuild the full log in background return dataPack; } From 80a929ef9b85a40bba5d7c72b00c84303644ed93 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 25 Nov 2014 20:00:36 +0300 Subject: [PATCH 12/38] [log] IDEA-133475 Remember text filter in the model on-the-fly --- .../log/ui/filter/VcsLogClassicFilterUi.java | 56 +++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java index 76b3f091eb8c..49ea73ebb119 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java @@ -21,11 +21,13 @@ import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.actionSystem.ex.CustomComponentAction; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.NotNullComputable; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.DocumentAdapter; import com.intellij.ui.SearchTextFieldWithStoredHistory; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; @@ -39,6 +41,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.text.BadLocationException; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -49,6 +53,7 @@ import java.util.List; public class VcsLogClassicFilterUi implements VcsLogFilterUi { private static final String HASH_PATTERN = "[a-fA-F0-9]{7,}"; + private static final Logger LOG = Logger.getInstance(VcsLogClassicFilterUi.class); @NotNull private final VcsLogUiImpl myUi; @@ -61,7 +66,7 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { @NotNull private final FilterModel myUserFilterModel; @NotNull private final FilterModel myDateFilterModel; @NotNull private final FilterModel myStructureFilterModel; - @NotNull private final FilterModel myTextFilterModel; + @NotNull private final TextFilterModel myTextFilterModel; public VcsLogClassicFilterUi(@NotNull VcsLogUiImpl ui, @NotNull VcsLogDataHolder logDataHolder, @@ -83,7 +88,7 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { myUserFilterModel = new FilterModel(dataPackGetter); myDateFilterModel = new FilterModel(dataPackGetter); myStructureFilterModel = new FilterModel(dataPackGetter); - myTextFilterModel = new FilterModel(dataPackGetter); + myTextFilterModel = new TextFilterModel(dataPackGetter); updateUiOnFilterChange(); } @@ -196,9 +201,9 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { private static class TextFilterComponent extends DumbAwareAction implements CustomComponentAction { - private final FilterModel myFilterModel; + private final TextFilterModel myFilterModel; - public TextFilterComponent(FilterModel filterModel) { + public TextFilterComponent(TextFilterModel filterModel) { myFilterModel = filterModel; } @@ -219,6 +224,7 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { myFilterModel.setFilter(null); } }; + textFilter.setText(myFilterModel.getText()); textFilter.getTextEditor().addActionListener(new ActionListener() { @Override public void actionPerformed(@NotNull ActionEvent e) { @@ -226,6 +232,17 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { textFilter.addCurrentTextToHistory(); } }); + textFilter.addDocumentListener(new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + try { + myFilterModel.setUnsavedText(e.getDocument().getText(0, e.getDocument().getLength())); + } + catch (BadLocationException ex) { + LOG.error(ex); + } + } + }); return textFilter; } @@ -251,4 +268,35 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi { public void actionPerformed(@NotNull AnActionEvent e) { } } + + private static class TextFilterModel extends FilterModel { + @Nullable private String myText; + + public TextFilterModel(NotNullComputable dataPackProvider) { + super(dataPackProvider); + } + + @NotNull + String getText() { + if (myText != null) { + return myText; + } + else if (getFilter() != null) { + return getFilter().getText(); + } + else { + return ""; + } + } + + void setUnsavedText(@NotNull String text) { + myText = text; + } + + @Override + void setFilter(@Nullable VcsLogTextFilter filter) { + super.setFilter(filter); + myText = null; + } + } } From c23047cf7c4dfbd9ce114590e8393434d8a64380 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 25 Nov 2014 18:54:32 +0300 Subject: [PATCH 13/38] diff: change LST stripe marks color on change of color scheme --- .../openapi/editor/impl/RangeHighlighterData.java | 11 +++++++---- .../openapi/diff/impl/highlighting/DiffMarkup.java | 13 +++---------- .../intellij/openapi/vcs/ex/LineStatusTracker.java | 7 +++---- .../openapi/vcs/ex/LineStatusTrackerDrawing.java | 11 ++++++----- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/RangeHighlighterData.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/RangeHighlighterData.java index b787c337d46c..9a56a239ef72 100644 --- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/RangeHighlighterData.java +++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/impl/RangeHighlighterData.java @@ -33,6 +33,8 @@ import java.awt.*; * User: cdr */ abstract class RangeHighlighterData { + private static final Color NULL_COLOR = new Color(0, 0, 0); + private final MarkupModel myModel; private TextAttributes myTextAttributes; private LineMarkerRenderer myLineMarkerRenderer; @@ -54,9 +56,6 @@ abstract class RangeHighlighterData { myTextAttributes = textAttributes; setFlag(TARGET_AREA_IS_EXACT_FLAG, target == HighlighterTargetArea.EXACT_RANGE); myModel = model; - if (textAttributes != null) { - myErrorStripeColor = textAttributes.getErrorStripeColor(); - } } private static final int AFTER_END_OF_LINE_FLAG = 0; @@ -137,10 +136,14 @@ abstract class RangeHighlighterData { } public Color getErrorStripeMarkColor() { - return myErrorStripeColor; + if (myErrorStripeColor == NULL_COLOR) return null; + if (myErrorStripeColor != null) return myErrorStripeColor; + if (myTextAttributes != null) return myTextAttributes.getErrorStripeColor(); + return null; } public void setErrorStripeMarkColor(Color color) { + if (color == null) color = NULL_COLOR; Color old = myErrorStripeColor; myErrorStripeColor = color; if (!Comparing.equal(old, color)) { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java index f2fcc6a5e983..27c56f8f4f0b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java @@ -109,20 +109,13 @@ public abstract class DiffMarkup implements EditorSource, Disposable { } setLineMarkerRenderer(rangeMarker, fragment, type); - setErrorStripes(rangeMarker, fragment, attributes.getErrorStripeColor()); - saveHighlighter(rangeMarker); - } - private static void setErrorStripes(@NotNull RangeHighlighter rangeMarker, @NotNull Fragment fragment, @Nullable Color stripeBarColor) { + rangeMarker.setThinErrorStripeMark(true); if (DiffUtil.isInlineWrapper(fragment)) { rangeMarker.setErrorStripeMarkColor(null); } - else { - if (stripeBarColor != null) { - rangeMarker.setErrorStripeMarkColor(stripeBarColor); - rangeMarker.setThinErrorStripeMark(true); - } - } + + saveHighlighter(rangeMarker); } private static void setLineMarkerRenderer(RangeHighlighter rangeMarker, Fragment fragment, TextDiffType type) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java index 85d6e2a2b4e5..26a189737134 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java @@ -190,11 +190,10 @@ public class LineStatusTracker { int second = range.getLine2() >= getLineCount(myDocument) ? myDocument.getTextLength() : myDocument.getLineStartOffset(range.getLine2()); - final RangeHighlighter highlighter = DocumentMarkupModel.forDocument(myDocument, myProject, true) - .addRangeHighlighter(first, second, HighlighterLayer.FIRST - 1, null, HighlighterTargetArea.LINES_IN_RANGE); - final TextAttributes attr = LineStatusTrackerDrawing.getAttributesFor(range); - highlighter.setErrorStripeMarkColor(attr.getErrorStripeColor()); + final RangeHighlighter highlighter = DocumentMarkupModel.forDocument(myDocument, myProject, true) + .addRangeHighlighter(first, second, HighlighterLayer.FIRST - 1, attr, HighlighterTargetArea.LINES_IN_RANGE); + highlighter.setThinErrorStripeMark(true); highlighter.setGreedyToLeft(true); highlighter.setGreedyToRight(true); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java index af016745218b..8e44d9b960ea 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java @@ -33,7 +33,6 @@ import com.intellij.openapi.editor.ex.EditorGutterComponentEx; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; import com.intellij.openapi.editor.markup.ActiveGutterRenderer; -import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.LineMarkerRenderer; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -63,10 +62,12 @@ public class LineStatusTrackerDrawing { } static TextAttributes getAttributesFor(final Range range) { - final Color stripeColor = getDiffColor(range); - final TextAttributes textAttributes = new TextAttributes(null, stripeColor, null, EffectType.BOXED, Font.PLAIN); - textAttributes.setErrorStripeColor(stripeColor); - return textAttributes; + return new TextAttributes() { + @Override + public Color getErrorStripeColor() { + return getDiffColor(range); + } + }; } private static void paintGutterFragment(final Editor editor, final Graphics g, final Rectangle r, final Range range) { From db57b999b257ce979b774051aa07926649e6641e Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Nov 2014 16:25:12 +0100 Subject: [PATCH 14/38] rethrow PCE when dispatching events (EA-62823) --- .../util/messages/impl/MessageBusConnectionImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/util/messages/impl/MessageBusConnectionImpl.java b/platform/util/src/com/intellij/util/messages/impl/MessageBusConnectionImpl.java index a3051241c4ef..a22f74468a0d 100644 --- a/platform/util/src/com/intellij/util/messages/impl/MessageBusConnectionImpl.java +++ b/platform/util/src/com/intellij/util/messages/impl/MessageBusConnectionImpl.java @@ -20,6 +20,7 @@ package com.intellij.util.messages.impl; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.util.SmartFMap; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.messages.MessageHandler; @@ -117,7 +118,10 @@ public class MessageBusConnectionImpl implements MessageBusConnection { catch (AbstractMethodError e) { //Do nothing. This listener just does not implement something newly added yet. } - catch(Throwable e) { + catch (ProcessCanceledException e) { + throw e; + } + catch (Throwable e) { LOG.error(e.getCause() == null ? e : e.getCause()); } } From dd02c2f5983d0b133667f546d6ebc4504cbc1fa4 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Nov 2014 17:46:30 +0100 Subject: [PATCH 15/38] open files by full path in goto file (IDEA-132824) --- .../navigation/ChooseByNameHddTest.groovy | 47 ++++++++++++++ .../navigation/ChooseByNameTest.groovy | 2 +- .../intellij/ide/actions/GotoActionBase.java | 21 +++++-- .../intellij/ide/actions/GotoFileAction.java | 13 ++-- .../ide/actions/GotoFileItemProvider.java | 61 +++++++++++++++++++ 5 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 java/java-tests/testSrc/com/intellij/navigation/ChooseByNameHddTest.groovy create mode 100644 platform/lang-impl/src/com/intellij/ide/actions/GotoFileItemProvider.java diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameHddTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameHddTest.groovy new file mode 100644 index 000000000000..5b3e868ecda0 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameHddTest.groovy @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 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.navigation +import com.intellij.ide.actions.GotoFileItemProvider +import com.intellij.ide.util.gotoByName.ChooseByNamePopup +import com.intellij.ide.util.gotoByName.GotoFileModel +import com.intellij.openapi.util.io.FileUtil +import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull +/** + * @author peter + */ +class ChooseByNameHddTest extends JavaCodeInsightFixtureTestCase { + + public void "test go to file by full path"() { + def psiFile = myFixture.addFileToProject("foo/index.html", "foo") + def path = psiFile.virtualFile.path + + def popup = ChooseByNamePopup.createPopup(project, new GotoFileModel(project), new GotoFileItemProvider(project, null)) + assert ChooseByNameTest.calcPopupElements(popup, path) == [psiFile] + assert ChooseByNameTest.calcPopupElements(popup, FileUtil.toSystemDependentName(path)) == [psiFile] + popup.close(false) + } + + @Override + protected boolean runInDispatchThread() { + return false + } + + @Override + protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception { + runnable.run() + } +} diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy index c9edde467850..12f11bd266d7 100644 --- a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy +++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameTest.groovy @@ -260,7 +260,7 @@ class Intf { return calcPopupElements(createPopup(model), text, checkboxState) } - private static ArrayList calcPopupElements(ChooseByNamePopup popup, String text, boolean checkboxState = false) { + static ArrayList calcPopupElements(ChooseByNamePopup popup, String text, boolean checkboxState = false) { List elements = ['empty'] def semaphore = new Semaphore() semaphore.down() diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java index 5da112b375b9..bdbd798ca787 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoActionBase.java @@ -16,10 +16,7 @@ package com.intellij.ide.actions; -import com.intellij.ide.util.gotoByName.ChooseByNameFilter; -import com.intellij.ide.util.gotoByName.ChooseByNameModel; -import com.intellij.ide.util.gotoByName.ChooseByNamePopup; -import com.intellij.ide.util.gotoByName.ChooseByNamePopupComponent; +import com.intellij.ide.util.gotoByName.*; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; @@ -184,12 +181,24 @@ public abstract class GotoActionBase extends AnAction { @Nullable final String findUsagesTitle, boolean useSelectionFromEditor, final boolean allowMultipleSelection) { + showNavigationPopup(e, model, callback, findUsagesTitle, useSelectionFromEditor, allowMultipleSelection, + new DefaultChooseByNameItemProvider(getPsiContext(e))); + } + + protected void showNavigationPopup(AnActionEvent e, + ChooseByNameModel model, + final GotoActionCallback callback, + @Nullable final String findUsagesTitle, + boolean useSelectionFromEditor, + final boolean allowMultipleSelection, + final DefaultChooseByNameItemProvider itemProvider) { final Project project = e.getData(CommonDataKeys.PROJECT); boolean mayRequestOpenInCurrentWindow = model.willOpenEditor() && FileEditorManagerEx.getInstanceEx(project).hasSplitOrUndockedWindows(); Pair start = getInitialText(useSelectionFromEditor, e); showNavigationPopup(callback, findUsagesTitle, - ChooseByNamePopup.createPopup(project, model, getPsiContext(e), start.first, - mayRequestOpenInCurrentWindow, start.second), allowMultipleSelection); + ChooseByNamePopup.createPopup(project, model, itemProvider, start.first, + mayRequestOpenInCurrentWindow, + start.second), allowMultipleSelection); } protected void showNavigationPopup(final GotoActionCallback callback, diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoFileAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoFileAction.java index 5fbdfeaa93b3..280e4c7736b1 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoFileAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoFileAction.java @@ -17,13 +17,9 @@ package com.intellij.ide.actions; import com.intellij.featureStatistics.FeatureUsageTracker; -import com.intellij.ide.util.gotoByName.ChooseByNameFilter; -import com.intellij.ide.util.gotoByName.ChooseByNamePopup; -import com.intellij.ide.util.gotoByName.GotoFileConfiguration; -import com.intellij.ide.util.gotoByName.GotoFileModel; +import com.intellij.ide.util.gotoByName.*; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.fileEditor.OpenFileDescriptor; @@ -34,6 +30,7 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -58,7 +55,7 @@ public class GotoFileAction extends GotoActionBase implements DumbAware { FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file"); final Project project = e.getData(CommonDataKeys.PROJECT); final GotoFileModel gotoFileModel = new GotoFileModel(project); - showNavigationPopup(e, gotoFileModel, new GotoActionCallback() { + GotoActionCallback callback = new GotoActionCallback() { @Override protected ChooseByNameFilter createFilter(@NotNull ChooseByNamePopup popup) { return new GotoFileFilter(popup, gotoFileModel, project); @@ -84,7 +81,9 @@ public class GotoFileAction extends GotoActionBase implements DumbAware { } }, ModalityState.NON_MODAL); } - }, "Files matching pattern", true); + }; + PsiElement context = getPsiContext(e); + showNavigationPopup(e, gotoFileModel, callback, "Files matching pattern", true, true, new GotoFileItemProvider(project, context)); } protected static class GotoFileFilter extends ChooseByNameFilter { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoFileItemProvider.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoFileItemProvider.java new file mode 100644 index 000000000000..3a2559b5888d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoFileItemProvider.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 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.ide.actions; + +import com.intellij.ide.util.gotoByName.ChooseByNameBase; +import com.intellij.ide.util.gotoByName.DefaultChooseByNameItemProvider; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +/** +* @author peter +*/ +public class GotoFileItemProvider extends DefaultChooseByNameItemProvider { + private final Project myProject; + + public GotoFileItemProvider(@NotNull Project project, @Nullable PsiElement context) { + super(context); + myProject = project; + } + + @Override + public boolean filterElements(@NotNull ChooseByNameBase base, + @NotNull String pattern, + boolean everywhere, + @NotNull ProgressIndicator indicator, + @NotNull Processor consumer) { + if (pattern.contains("/") || pattern.contains("\\")) { + File ioFile = new File(pattern); + VirtualFile vFile = ioFile.exists() ? LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile) : null; + PsiFile psiFile = vFile == null ? null : PsiManager.getInstance(myProject).findFile(vFile); + if (psiFile != null && !consumer.process(psiFile)) { + return false; + } + } + + return super.filterElements(base, pattern, everywhere, indicator, consumer); + } +} From a1729ffa548c978b18480f30482b23119019a634 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Nov 2014 17:50:44 +0100 Subject: [PATCH 16/38] fix groovy super type cache NPE for local classes --- .../jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index 33b284ec7974..7f4313cb3316 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -381,11 +381,13 @@ public class ResolveUtil { else { key = base.getCanonicalText(); } - Map result = cache.get(key); + Map result = key == null ? null : cache.get(key); if (result == null) { result = new HashMap(); collectSuperTypes(base, result, project); - cache.put(key, result); + if (key != null) { + cache.put(key, result); + } } return result; } From b749c5ee35428c80827834daadaa7cb87a9ceeb6 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Nov 2014 18:30:17 +0100 Subject: [PATCH 17/38] wrap vfile writes in tests into write action --- .../maven/compiler/ResourceFilteringTest.java | 19 +++- ...avenModuleCompletionAndResolutionTest.java | 2 +- .../importing/EncodingImportingTest.groovy | 11 +-- .../InvalidProjectImportingTest.java | 11 ++- .../maven/project/MavenProjectReaderTest.java | 92 +++++++++---------- .../project/MavenProjectsTreeTestCase.java | 16 +++- 6 files changed, 90 insertions(+), 61 deletions(-) diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java index 5eebdb21d640..d3689cfd0db2 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java @@ -15,11 +15,14 @@ */ package org.jetbrains.idea.maven.compiler; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; +import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.model.MavenExplicitProfiles; import java.util.Arrays; @@ -520,7 +523,7 @@ public class ResourceFilteringTest extends MavenCompilingTestCase { } public void testUpdatingWhenPropertiesInFiltersAreChanged() throws Exception { - VirtualFile filter = createProjectSubFile("filters/filter.properties", "xxx=1"); + final VirtualFile filter = createProjectSubFile("filters/filter.properties", "xxx=1"); createProjectSubFile("resources/file.properties", "value=${xxx}"); importProject("test" + @@ -541,7 +544,12 @@ public class ResourceFilteringTest extends MavenCompilingTestCase { compileModules("project"); assertResult("target/classes/file.properties", "value=1"); - VfsUtil.saveText(filter, "xxx=2"); + new WriteAction() { + @Override + protected void run(@NotNull Result result) throws Throwable { + VfsUtil.saveText(filter, "xxx=2"); + } + }.execute().throwException(); PsiDocumentManager.getInstance(myProject).commitAllDocuments(); compileModules("project"); assertResult("target/classes/file.properties", "value=2"); @@ -1010,7 +1018,12 @@ public class ResourceFilteringTest extends MavenCompilingTestCase { public void testDoNotFilterButCopyBigFiles() throws Exception { assertEquals(FileTypeManager.getInstance().getFileTypeByFileName("file.xyz"), FileTypes.UNKNOWN); - createProjectSubFile("resources/file.xyz").setBinaryContent(new byte[1024 * 1024 * 20]); + new WriteAction() { + @Override + protected void run(@NotNull Result result) throws Throwable { + createProjectSubFile("resources/file.xyz").setBinaryContent(new byte[1024 * 1024 * 20]); + } + }.execute().throwException(); importProject("test" + "project" + diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenModuleCompletionAndResolutionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenModuleCompletionAndResolutionTest.java index 09fa85a96620..3a863c3fdce4 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenModuleCompletionAndResolutionTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenModuleCompletionAndResolutionTest.java @@ -521,7 +521,7 @@ public class MavenModuleCompletionAndResolutionTest extends MavenDomWithIndicesT importProject(parentPom); - VfsUtil.saveText(parentPom, createPomXml( + myFixture.saveText(parentPom, createPomXml( "test" + "project" + "1" + diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/EncodingImportingTest.groovy b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/EncodingImportingTest.groovy index 8a296154799d..364dc787e90a 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/EncodingImportingTest.groovy +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/EncodingImportingTest.groovy @@ -14,11 +14,10 @@ * limitations under the License. */ package org.jetbrains.idea.maven.importing - -import org.jetbrains.idea.maven.MavenImportingTestCase -import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.vfs.VfsUtil - +import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.idea.maven.MavenImportingTestCase /** * @author Sergey Evdokimov */ @@ -28,7 +27,7 @@ class EncodingImportingTest extends MavenImportingTestCase { byte[] text = [-12, -59, -53, -45, -44] // Russian text in koi8-r encoding. VirtualFile file = createProjectSubFile("src/main/resources/A.txt") - file.setBinaryContent(text) + ApplicationManager.application.runWriteAction { file.setBinaryContent(text) } importProject(""" test @@ -49,7 +48,7 @@ class EncodingImportingTest extends MavenImportingTestCase { byte[] text = [-12, -59, -53, 45, -44] // Russian text in koi8-r encoding. VirtualFile file = createProjectSubFile("src/main/resources/A.txt") - file.setBinaryContent(text) + ApplicationManager.application.runWriteAction { file.setBinaryContent(text) } importProject(""" test diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/InvalidProjectImportingTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/InvalidProjectImportingTest.java index 6abd27740e91..4a7a303783a3 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/InvalidProjectImportingTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/importing/InvalidProjectImportingTest.java @@ -15,6 +15,9 @@ */ package org.jetbrains.idea.maven.importing; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; +import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.MavenCustomRepositoryHelper; import org.jetbrains.idea.maven.MavenImportingTestCase; import org.jetbrains.idea.maven.model.MavenProjectProblem; @@ -34,7 +37,13 @@ public class InvalidProjectImportingTest extends MavenImportingTestCase { public void testUnknownProblemWithEmptyFile() throws Exception { createProjectPom(""); - myProjectPom.setBinaryContent(new byte[0]); + new WriteAction() { + @Override + protected void run(@NotNull Result result) throws Throwable { + myProjectPom.setBinaryContent(new byte[0]); + } + }.execute().throwException(); + importProject(); assertModules("project"); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectReaderTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectReaderTest.java index 7bb904d6965d..e943e2fb217a 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectReaderTest.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectReaderTest.java @@ -244,13 +244,13 @@ public class MavenProjectReaderTest extends MavenTestCase { protected void run(Result result) throws Throwable { VirtualFile res = myProjectRoot.createChildData(this, "pom.xml"); result.setResult(res); + VfsUtil.saveText(res, "" + + " test" + + " project" + + " 1" + + ""); } }.execute().getResultObject(); - VfsUtil.saveText(file, "" + - " test" + - " project" + - " 1" + - ""); PsiDocumentManager.getInstance(myProject).commitAllDocuments(); MavenModel p = readProject(file); @@ -309,49 +309,49 @@ public class MavenProjectReaderTest extends MavenTestCase { protected void run(Result result) throws Throwable { VirtualFile res = myProjectRoot.createChildData(this, "pom.xml"); result.setResult(res); + VfsUtil.saveText(res, "" + + " 1.2.3" + + " test" + + " project" + + " 1" + + " foo" + + " pom" + + + " " + + " testParent" + + " projectParent" + + " 2" + + " ../parent/pom.xml" + + " " + + + " " + + " xxx" + + " someGoal" + + " mySrc" + + " myTestSrc" + + " myScriptSrc" + + " " + + " " + + " myRes" + + " true" + + " dir" + + " **.properties" + + " **.xml" + + " " + + " " + + " " + + " " + + " myTestRes" + + " **.properties" + + " " + + " " + + " myOutput" + + " myClasses" + + " myTestClasses" + + " " + + ""); } }.execute().getResultObject(); - VfsUtil.saveText(file, "" + - " 1.2.3" + - " test" + - " project" + - " 1" + - " foo" + - " pom" + - - " " + - " testParent" + - " projectParent" + - " 2" + - " ../parent/pom.xml" + - " " + - - " " + - " xxx" + - " someGoal" + - " mySrc" + - " myTestSrc" + - " myScriptSrc" + - " " + - " " + - " myRes" + - " true" + - " dir" + - " **.properties" + - " **.xml" + - " " + - " " + - " " + - " " + - " myTestRes" + - " **.properties" + - " " + - " " + - " myOutput" + - " myClasses" + - " myTestClasses" + - " " + - ""); PsiDocumentManager.getInstance(myProject).commitAllDocuments(); MavenModel p = readProject(file); diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsTreeTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsTreeTestCase.java index 8d73c5f53bb1..7f4debf12394 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsTreeTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/project/MavenProjectsTreeTestCase.java @@ -15,7 +15,10 @@ */ package org.jetbrains.idea.maven.project; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.MavenImportingTestCase; import org.jetbrains.idea.maven.model.MavenExplicitProfiles; import org.jetbrains.idea.maven.utils.MavenProcessCanceledException; @@ -46,9 +49,14 @@ public abstract class MavenProjectsTreeTestCase extends MavenImportingTestCase { myTree.delete(asList(file), getMavenGeneralSettings(), EMPTY_MAVEN_PROCESS); } - protected void updateTimestamps(VirtualFile... files) throws IOException { - for (VirtualFile each : files) { - each.setBinaryContent(each.contentsToByteArray()); - } + protected void updateTimestamps(final VirtualFile... files) throws IOException { + new WriteAction() { + @Override + protected void run(@NotNull Result result) throws Throwable { + for (VirtualFile each : files) { + each.setBinaryContent(each.contentsToByteArray()); + } + } + }.execute().throwException(); } } From 52d29286d436ce8f55693cf83fd5154e4dfd4a6d Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 25 Nov 2014 18:39:58 +0100 Subject: [PATCH 18/38] do not produce very common index keys for this/super invokations, performance regression with rewriting duplicates index with light stub tree (IDEA-133154) --- .../src/com/intellij/dupLocator/index/DuplicatesIndex.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java index 26dbb106b753..97a5245e9b9b 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java @@ -62,7 +62,7 @@ public class DuplicatesIndex extends FileBasedIndexExtension NAME = ID.create("DuplicatesIndex"); - private static final int myBaseVersion = 13; + private static final int myBaseVersion = 14; private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() { @Override From bf2f3f84ee47885c8bf068000e9c5ec188e7cfd8 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Nov 2014 18:07:35 +0100 Subject: [PATCH 19/38] function expressions search: accept functional functional interfaces inheritors (IDEA-128086) --- .../psi/impl/search/JavaFunctionalExpressionSearcher.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java index 8fbe6ef11a5c..500841ffffe3 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java @@ -33,6 +33,7 @@ import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; import com.intellij.psi.search.*; import com.intellij.psi.search.searches.FunctionalExpressionSearch; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.CommonProcessors; @@ -148,7 +149,7 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor Date: Tue, 25 Nov 2014 18:53:13 +0100 Subject: [PATCH 20/38] find functional interface on arrow/dbl column (IDEA-122033) --- .../codeInsight/TargetElementUtil.java | 9 ++++ .../ShowImplementationHandlerTest.java | 44 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 java/java-tests/testSrc/com/intellij/navigation/ShowImplementationHandlerTest.java diff --git a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java index a82877e124d7..826a68e52253 100644 --- a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java @@ -99,6 +99,15 @@ public class TargetElementUtil extends TargetElementUtilBase { if (ref instanceof PsiJavaReference) { refElement = ((PsiJavaReference)ref).advancedResolve(true).getElement(); } + else if (ref == null) { + final PsiElement element = file.findElementAt(offset); + if (element != null) { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiFunctionalExpression) { + refElement = PsiUtil.resolveClassInType(((PsiFunctionalExpression)parent).getFunctionalInterfaceType()); + } + } + } } if (refElement != null) { diff --git a/java/java-tests/testSrc/com/intellij/navigation/ShowImplementationHandlerTest.java b/java/java-tests/testSrc/com/intellij/navigation/ShowImplementationHandlerTest.java new file mode 100644 index 000000000000..a657a7fafb86 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/navigation/ShowImplementationHandlerTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 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.navigation; + +import com.intellij.codeInsight.TargetElementUtilBase; +import com.intellij.psi.CommonClassNames; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; + +public class ShowImplementationHandlerTest extends JavaCodeInsightFixtureTestCase { + + public void testMultipleImplsFromAbstractCall() throws Throwable { + PsiFile file = myFixture.addFileToProject("Foo.java", "public abstract class Hello {" + + " {" + + " Runnable r = () -> {};\n" + + " }\n" + + "}\n" + + "\n"); + myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); + + final PsiElement element = + TargetElementUtilBase.findTargetElement(myFixture.getEditor(), TargetElementUtilBase.getInstance().getAllAccepted()); + assertTrue(element instanceof PsiClass); + final String qualifiedName = ((PsiClass)element).getQualifiedName(); + assertEquals(CommonClassNames.JAVA_LANG_RUNNABLE, qualifiedName); + } + +} \ No newline at end of file From 3f0ce404408e601777f5e8f4a31f77b21d6ad65b Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 25 Nov 2014 19:08:36 +0100 Subject: [PATCH 21/38] testdata for IDEA-127124 --- .../lambda/newLambda/IDEA127124.java | 22 +++++++++++++++++++ .../lambda/NewLambdaHighlightingTest.java | 4 ++++ 2 files changed, 26 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA127124.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA127124.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA127124.java new file mode 100644 index 000000000000..b9c0acc841ec --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA127124.java @@ -0,0 +1,22 @@ +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +class Test { + enum TestEnum {EnumOne, EnumTwo, EnumThree} + + public static void main(String[] args) { + String testString = "EnumOne=0, EnumTwo=2,EnumThree=1"; + + Map enumMap = Optional.ofNullable(testString) + .map(levelsString -> Arrays.stream(levelsString.split("\\s*,\\s*")) + .map(splitStringComponent -> splitStringComponent.split("=")) + .filter(keyValArray -> keyValArray.length == 2) + .collect(Collectors.toMap(keyValArray -> TestEnum.valueOf(keyValArray[0]), s -> Integer.valueOf(s[1])))) + .orElse(new HashMap<>()); + + System.out.println(enumMap); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 416f07e77b22..0391a8348700 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -160,6 +160,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIDEA127124() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } From 17b37b2bfa6c2dbdf273c062a7740aa029554ae1 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Nov 2014 16:43:26 +0100 Subject: [PATCH 22/38] remove unused testdata --- .../abstraction/weaken_type/expected.xml | 45 ------------------- 1 file changed, 45 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/expected.xml diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/expected.xml deleted file mode 100644 index 577f33646869..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/expected.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - TypeMayBeWeakened.java - 55 - Type may be weakened - Type of parameter <code>b</code> may be weakened to 'java.lang.Object' - - - - TypeMayBeWeakened.java - 85 - Type may be weakened - Type of parameter <code>list</code> may be weakened to 'java.lang.Iterable' - - - - TypeMayBeWeakened.java - 68 - Type may be weakened - Type of variable <code>iaex</code> may be weakened to 'java.lang.RuntimeException' - - - - TypeMayBeWeakened.java - 133 - Type may be weakened - Type of parameter <code>objectInput</code> may be weakened to 'com.siyeh.igtest.abstraction.weaken_type.DataInput' #loc - - - - AutoClosableTest.java - 34 - Type may be weakened - Type of variable <code>bar</code> may be weakened to 'com.siyeh.igtest.abstraction.weaken_type.AutoClosableTest2.Foo' #loc - - - - AutoClosableTest.java - 40 - Type may be weakened - Type of variable <code>reader</code> may be weakened to 'java.io.Closeable' #loc - - \ No newline at end of file From 5ecd85d2e3a26e3d64c807558006ed818540bfcd Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 25 Nov 2014 19:29:37 +0100 Subject: [PATCH 23/38] IDEA-132967 (TypeMayBeWeakened incorrectly advises weakening to java.util.function.Function on method which is used by reference) --- .../siyeh/ig/psiutils/WeakestTypeFinder.java | 11 ++++++-- .../weaken_type/TypeMayBeWeakened.java | 25 ++++++++++++++++--- .../TypeMayBeWeakenedInspectionTest.java | 5 ++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java index aade5a56361f..835d841e0de8 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java @@ -108,7 +108,14 @@ public class WeakestTypeFinder { referenceParent = referenceElement.getParent(); } final PsiElement referenceGrandParent = referenceParent.getParent(); - if (referenceParent instanceof PsiExpressionList) { + if (reference instanceof PsiMethodReferenceExpression) { + final PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression)reference; + final PsiType type = methodReferenceExpression.getFunctionalInterfaceType(); + final PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(type); + if (!PsiType.VOID.equals(returnType) && !checkType(returnType, weakestTypeClasses)) { + return Collections.emptyList(); + } + } else if (referenceParent instanceof PsiExpressionList) { if (!(referenceGrandParent instanceof PsiMethodCallExpression)) { return Collections.emptyList(); } @@ -186,7 +193,7 @@ public class WeakestTypeFinder { if (referenceElement.equals(condition)) { return Collections.emptyList(); } - final PsiType type = ExpectedTypeUtils.findExpectedType( conditionalExpression, true); + final PsiType type = ExpectedTypeUtils.findExpectedType(conditionalExpression, true); if (!checkType(type, weakestTypeClasses)) { return Collections.emptyList(); } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java index a134fcd8d9fb..aa0174ee9323 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java @@ -1,10 +1,8 @@ package com.siyeh.igtest.abstraction.weaken_type; -import java.util.HashMap; -import java.util.Map; -import java.util.ArrayList; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.util.*; public class TypeMayBeWeakened { @@ -173,4 +171,25 @@ class Helper { B b = new B(); b.foo(); } +} +class MethodReference1 { + public void m(Set list) { + f(MethodReference1::myTransform); + } + + void f(java.util.function.Function function) {} + + private static String myTransform(int in) { + return Integer.toString(in); + } +} +class MethodReference2 { + public void main(String[] args) { + Runnable r = MethodReference2::myTransform; + Object o = myTransform(); + } + + private static String myTransform() { + return "Integer.toString(in)"; + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspectionTest.java index df0048a5218f..52e5e8cc3db2 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspectionTest.java @@ -28,6 +28,11 @@ public class TypeMayBeWeakenedInspectionTest extends LightInspectionTestCase { " public int getNumberOne() {\n" + " return super.getNumberOne();\n" + " }\n" + + "}", + "package java.util.function;" + + "@FunctionalInterface " + + "public interface Function {" + + " R apply(T t);" + "}" }; } From 57f3f43532ad1a628f6e424a28f3f9508c07deb4 Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Nov 2014 19:41:58 +0100 Subject: [PATCH 24/38] clean groovy stub dirs via renameAndDelete less frequently --- .../jps/incremental/groovy/GroovyBuilder.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java index fdc08aa7e676..4d858953ed26 100644 --- a/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java +++ b/plugins/groovy/jps-plugin/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java @@ -326,6 +326,16 @@ public class GroovyBuilder extends ModuleLevelBuilder { return compiled; } + @Override + public void buildStarted(CompileContext context) { + if (myForStubs) { + File stubRoot = getStubRoot(context); + if (stubRoot.exists() && !FileUtil.deleteWithRenaming(stubRoot)) { + context.processMessage(new CompilerMessage(myBuilderName, BuildMessage.Kind.ERROR, "External make cannot clean " + stubRoot.getPath())); + } + } + } + @Override public void chunkBuildFinished(CompileContext context, ModuleChunk chunk) { JavaBuilderUtil.cleanupChunkResources(context); @@ -334,10 +344,10 @@ public class GroovyBuilder extends ModuleLevelBuilder { private static Map getStubGenerationOutputs(ModuleChunk chunk, CompileContext context) throws IOException { Map generationOutputs = new HashMap(); - File commonRoot = new File(context.getProjectDescriptor().dataManager.getDataPaths().getDataStorageRoot(), "groovyStubs"); + File commonRoot = getStubRoot(context); for (ModuleBuildTarget target : chunk.getTargets()) { File targetRoot = new File(commonRoot, target.getModule().getName() + File.separator + target.getTargetType().getTypeId()); - if (!FileUtil.deleteWithRenaming(targetRoot)) { + if (targetRoot.exists() && !FileUtil.deleteWithRenaming(targetRoot)) { throw new IOException("External make cannot clean " + targetRoot.getPath()); } if (!targetRoot.mkdirs()) { @@ -348,6 +358,10 @@ public class GroovyBuilder extends ModuleLevelBuilder { return generationOutputs; } + private static File getStubRoot(CompileContext context) { + return new File(context.getProjectDescriptor().dataManager.getDataPaths().getDataStorageRoot(), "groovyStubs"); + } + @Nullable public static Map getCanonicalModuleOutputs(CompileContext context, ModuleChunk chunk, Builder builder) { Map finalOutputs = new HashMap(); From 8a8b01d820f2182c6afd30c239a5748a3fbc6d7c Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 25 Nov 2014 19:42:17 +0100 Subject: [PATCH 25/38] don't hold AST references in SymbolCollectingProcessor cache --- .../source/resolve/SymbolCollectingProcessor.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java index b283b39360ca..fbf16015414d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java @@ -16,6 +16,7 @@ package com.intellij.psi.impl.source.resolve; import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiAnchor; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.ResolveState; @@ -23,6 +24,7 @@ import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.scope.ElementClassHint; import com.intellij.psi.scope.JavaScopeProcessorEvent; import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.util.ObjectUtils; import com.intellij.util.containers.MostlySingularMultiMap; import org.jetbrains.annotations.NotNull; @@ -71,21 +73,21 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele } public static class ResultWithContext { - private final PsiNamedElement myElement; - private final PsiElement myFileContext; + private final PsiAnchor myElement; + private final PsiAnchor myFileContext; public ResultWithContext(@NotNull PsiNamedElement element, PsiElement fileContext) { - myElement = element; - myFileContext = fileContext; + myElement = PsiAnchor.create(element); + myFileContext = fileContext == null ? null : PsiAnchor.create(fileContext); } @NotNull public PsiNamedElement getElement() { - return myElement; + return (PsiNamedElement)ObjectUtils.assertNotNull(myElement.retrieve()); } public PsiElement getFileContext() { - return myFileContext; + return myFileContext == null ? null : myFileContext.retrieve(); } @Override From a564f24d26b06de73238b0fafa4f282a8f731ef5 Mon Sep 17 00:00:00 2001 From: Konstantin Ulitin Date: Tue, 25 Nov 2014 21:47:36 +0300 Subject: [PATCH 26/38] revert "possibility to have several stub trees in a file" --- .../com/intellij/psi/stubs/PsiFileStub.java | 4 -- .../intellij/psi/stubs/PsiFileStubImpl.java | 11 --- .../psi/stubs/StubSerializationHelper.java | 32 +-------- .../intellij/psi/impl/source/PsiFileImpl.java | 19 +++-- .../psi/stubs/CumulativeStubVersion.java | 2 +- .../intellij/psi/stubs/ObjectStubTree.java | 21 ++---- .../src/com/intellij/psi/stubs/StubTree.java | 31 -------- .../intellij/psi/stubs/StubTreeBuilder.java | 71 +------------------ .../psi/stubs/StubProcessingHelperBase.java | 40 +++-------- .../intellij/psi/stubs/StubUpdatingIndex.java | 5 +- .../TemplateDataElementType.java | 13 ++-- 11 files changed, 36 insertions(+), 213 deletions(-) diff --git a/platform/core-api/src/com/intellij/psi/stubs/PsiFileStub.java b/platform/core-api/src/com/intellij/psi/stubs/PsiFileStub.java index 074954604c78..069c3b38585d 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/PsiFileStub.java +++ b/platform/core-api/src/com/intellij/psi/stubs/PsiFileStub.java @@ -22,11 +22,7 @@ package com.intellij.psi.stubs; import com.intellij.openapi.util.UserDataHolder; import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IStubFileElementType; -import org.jetbrains.annotations.NotNull; public interface PsiFileStub extends StubElement, UserDataHolder { IStubFileElementType getType(); - - @NotNull - PsiFileStub[] getStubRoots(); } diff --git a/platform/core-api/src/com/intellij/psi/stubs/PsiFileStubImpl.java b/platform/core-api/src/com/intellij/psi/stubs/PsiFileStubImpl.java index 207e7649a3d6..2ea7294c59ed 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/PsiFileStubImpl.java +++ b/platform/core-api/src/com/intellij/psi/stubs/PsiFileStubImpl.java @@ -29,7 +29,6 @@ public class PsiFileStubImpl extends StubBase implements P public static final IStubFileElementType TYPE = new IStubFileElementType(Language.ANY); private volatile T myFile; private volatile String myInvalidationReason; - private volatile PsiFileStub[] myStubRoots; public PsiFileStubImpl(final T file) { super(null, null); @@ -65,14 +64,4 @@ public class PsiFileStubImpl extends StubBase implements P public IStubFileElementType getType() { return TYPE; } - - @NotNull - @Override - public PsiFileStub[] getStubRoots() { - return myStubRoots != null ? myStubRoots : new PsiFileStub[]{this}; - } - - public void setStubRoots(@NotNull PsiFileStub[] roots) { - myStubRoots = roots; - } } \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java index d46d83f8de29..4ced12477ba4 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java +++ b/platform/core-api/src/com/intellij/psi/stubs/StubSerializationHelper.java @@ -17,7 +17,6 @@ package com.intellij.psi.stubs; import com.intellij.openapi.diagnostic.LogUtil; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; -import com.intellij.util.SmartList; import com.intellij.util.containers.RecentStringInterner; import com.intellij.util.io.AbstractStringEnumerator; import com.intellij.util.io.DataInputOutputUtil; @@ -79,17 +78,7 @@ public class StubSerializationHelper { FileLocalStringEnumerator storage = new FileLocalStringEnumerator(true); StubOutputStream stubOutputStream = new StubOutputStream(out, storage); - if (rootStub instanceof PsiFileStub) { - final PsiFileStub[] roots = ((PsiFileStub)rootStub).getStubRoots(); - DataInputOutputUtil.writeINT(stubOutputStream, roots.length); - for (PsiFileStub root : roots) { - doSerialize(root, stubOutputStream); - } - } - else { - DataInputOutputUtil.writeINT(stubOutputStream, 1); - doSerialize(rootStub, stubOutputStream); - } + doSerialize(rootStub, stubOutputStream); DataOutputStream resultStream = new DataOutputStream(stream); DataInputOutputUtil.writeINT(resultStream, storage.myStrings.size()); byte[] buffer = IOUtil.allocReadWriteUTFBuffer(); @@ -122,24 +111,7 @@ public class StubSerializationHelper { ++i; } - int stubFilesCount = DataInputOutputUtil.readINT(inputStream); - if (stubFilesCount > 1) { - final List stubs = new SmartList(); - while (stubFilesCount-- > 0) { - final PsiFileStub fileStub = (PsiFileStub)deserialize(inputStream, null); - stubs.add(fileStub); - } - final PsiFileStub[] stubsArray = stubs.toArray(new PsiFileStub[stubs.size()]); - for (PsiFileStub stub : stubsArray) { - if (stub instanceof PsiFileStubImpl) { - ((PsiFileStubImpl)stub).setStubRoots(stubsArray); - } - } - return stubsArray[0]; - } - else { - return deserialize(inputStream, null); - } + return deserialize(inputStream, null); } String intern(String str) { diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java index 615d4d6a2dd7..cc0be29ae7e3 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/PsiFileImpl.java @@ -675,10 +675,15 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF final VirtualFile vFile = getVirtualFile(); if (!(vFile instanceof VirtualFileWithId)) return null; + final PsiFile stubBindingRoot = getViewProvider().getStubBindingRoot(); + if (stubBindingRoot != this) { + LOG.error("Attempted to create stubs for non-root file: " + this + ", stub binding root: " + stubBindingRoot); + return null; + } + ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), vFile, this); if (!(tree instanceof StubTree)) return null; StubTree stubHolder = (StubTree)tree; - final List> roots = StubTreeBuilder.getStubbedRoots(getViewProvider()); synchronized (PsiLock.LOCK) { if (getTreeElement() != null) return null; @@ -686,14 +691,9 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF final StubTree derefdOnLock = derefStub(); if (derefdOnLock != null) return derefdOnLock; - final PsiFileStub[] stubRoots = stubHolder.getRoot().getStubRoots(); - int matchingRoot = 0; - for (Pair root : roots) { - final PsiFileStub matchingStub = stubRoots[matchingRoot++]; - //noinspection unchecked - ((StubBase)matchingStub).setPsi(this); - ((PsiFileImpl)root.second).myStub = new SoftReference(new StubTree(matchingStub)); - } + //noinspection unchecked + ((StubBase)stubHolder.getRoot()).setPsi(this); + myStub = new SoftReference(stubHolder); return stubHolder; } } @@ -777,7 +777,6 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF public int getStartOffsetInParent() { return calcTreeElement().getStartOffsetInParent(); } - @Override public int getTextOffset() { return calcTreeElement().getTextOffset(); diff --git a/platform/core-impl/src/com/intellij/psi/stubs/CumulativeStubVersion.java b/platform/core-impl/src/com/intellij/psi/stubs/CumulativeStubVersion.java index 74e1f63e9900..0d22e819579f 100644 --- a/platform/core-impl/src/com/intellij/psi/stubs/CumulativeStubVersion.java +++ b/platform/core-impl/src/com/intellij/psi/stubs/CumulativeStubVersion.java @@ -25,7 +25,7 @@ import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.IStubFileElementType; public class CumulativeStubVersion { - private static final int VERSION = 28; + private static final int VERSION = 27; public static int getCumulativeVersion() { int version = VERSION; diff --git a/platform/core-impl/src/com/intellij/psi/stubs/ObjectStubTree.java b/platform/core-impl/src/com/intellij/psi/stubs/ObjectStubTree.java index 514cc5412ba4..2d84c928db22 100644 --- a/platform/core-impl/src/com/intellij/psi/stubs/ObjectStubTree.java +++ b/platform/core-impl/src/com/intellij/psi/stubs/ObjectStubTree.java @@ -53,17 +53,12 @@ public class ObjectStubTree { return myPlainList; } - @NotNull - public List getPlainListFromAllRoots() { - return getPlainList(); - } - @NotNull public Map> indexStubTree() { StubIndexSink sink = new StubIndexSink(); - final List plainList = getPlainListFromAllRoots(); - for (int i = 0, plainListSize = plainList.size(); i < plainListSize; i++) { - final Stub stub = plainList.get(i); + + for (int i = 0, plainListSize = myPlainList.size(); i < plainListSize; i++) { + final Stub stub = myPlainList.get(i); sink.myStubIdx = i; StubSerializationUtil.getSerializer(stub).indexStub(stub, sink); } @@ -71,15 +66,11 @@ public class ObjectStubTree { return sink.getResult(); } - protected void enumerateStubs(@NotNull Stub root, @NotNull List result) { - enumerateStubs(root, result, 0); - } - - protected static void enumerateStubs(@NotNull Stub root, @NotNull List result, int idOffset) { - ((ObjectStubBase)root).id = idOffset + result.size(); + protected static void enumerateStubs(@NotNull Stub root, @NotNull List result) { + ((ObjectStubBase)root).id = result.size(); result.add(root); for (Stub child : root.getChildrenStubs()) { - enumerateStubs(child, result, idOffset); + enumerateStubs(child, result); } } diff --git a/platform/core-impl/src/com/intellij/psi/stubs/StubTree.java b/platform/core-impl/src/com/intellij/psi/stubs/StubTree.java index 036dfa3da86c..36a855d6458c 100644 --- a/platform/core-impl/src/com/intellij/psi/stubs/StubTree.java +++ b/platform/core-impl/src/com/intellij/psi/stubs/StubTree.java @@ -19,14 +19,8 @@ */ package com.intellij.psi.stubs; -import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - public class StubTree extends ObjectStubTree> { public StubTree(@NotNull final PsiFileStub root) { @@ -37,31 +31,6 @@ public class StubTree extends ObjectStubTree> { super((ObjectStubBase)root, withBackReference); } - @Override - protected void enumerateStubs(@NotNull Stub root, @NotNull List result) { - final PsiFileStub[] files = ((PsiFileStub)root).getStubRoots(); - int idOffset = 0; - final List dummyList = new ArrayList(); - for (PsiFileStub file : files) { - if (file == root) break; - dummyList.clear(); - enumerateStubs(file, dummyList, idOffset); - idOffset += dummyList.size(); - } - enumerateStubs(root, result, idOffset); - } - - @NotNull - @Override - public List> getPlainListFromAllRoots() { - return ContainerUtil.concat(getRoot().getStubRoots(), new Function>>() { - @Override - public Collection> fun(PsiFileStub stub) { - return new StubTree(stub).getPlainList(); - } - }); - } - @NotNull @Override public PsiFileStub getRoot() { diff --git a/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java b/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java index 8d6787e30968..830915968efd 100644 --- a/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java +++ b/platform/core-impl/src/com/intellij/psi/stubs/StubTreeBuilder.java @@ -20,29 +20,16 @@ import com.intellij.lang.LanguageParserDefinitions; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Trinity; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiFile; import com.intellij.psi.StubBuilder; -import com.intellij.psi.impl.source.PsiFileImpl; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.IStubFileElementType; -import com.intellij.util.Function; -import com.intellij.util.SmartList; -import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.FileContent; import com.intellij.util.indexing.FileContentImpl; import com.intellij.util.indexing.IndexingDataKeys; import com.intellij.util.indexing.SubstitutedFileType; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Comparator; -import java.util.List; - public class StubTreeBuilder { private static final Key stubElementKey = Key.create("stub.tree.for.file.content"); @@ -72,8 +59,7 @@ public class StubTreeBuilder { CharSequence contentAsText = inputData.getContentAsText(); FileContentImpl fileContent = (FileContentImpl)inputData; PsiFile psi = fileContent.getPsiFileForPsiDependentIndex(); - final FileViewProvider viewProvider = psi.getViewProvider(); - psi = viewProvider.getStubBindingRoot(); + psi = psi.getViewProvider().getStubBindingRoot(); psi.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, contentAsText); // if we load AST, it should be easily gc-able. See PsiFileImpl.createTreeElementPointer() @@ -94,31 +80,11 @@ public class StubTreeBuilder { stubFileElementType = null; } if (stubFileElementType != null) { - final StubBuilder stubBuilder = stubFileElementType.getBuilder(); + StubBuilder stubBuilder = stubFileElementType.getBuilder(); if (stubBuilder instanceof LightStubBuilder) { LightStubBuilder.FORCED_AST.set(fileContent.getLighterASTForPsiDependentIndex()); } data = stubBuilder.buildStubTree(psi); - - final List> stubbedRoots = getStubbedRoots(viewProvider); - if (stubbedRoots.size() > 1) { - final SmartList stubs = new SmartList(); - stubs.add((PsiFileStub)data); - - for (Pair stubbedRoot : stubbedRoots) { - if (psi == stubbedRoot.second) continue; - final StubElement element = stubbedRoot.first.getBuilder().buildStubTree(stubbedRoot.second); - if (element instanceof PsiFileStub) { - stubs.add((PsiFileStub)element); - } - } - final PsiFileStub[] stubsArray = stubs.toArray(new PsiFileStub[stubs.size()]); - for (PsiFileStub stub : stubsArray) { - if (stub instanceof PsiFileStubImpl) { - ((PsiFileStubImpl)stub).setStubRoots(stubsArray); - } - } - } } } finally { @@ -131,37 +97,4 @@ public class StubTreeBuilder { return data; } } - - /** Order is deterministic. First element matches {@link com.intellij.psi.FileViewProvider#getStubBindingRoot()} */ - @NotNull - public static List> getStubbedRoots(@NotNull FileViewProvider viewProvider) { - final List> roots = - new SmartList>(); - final PsiFile stubBindingRoot = viewProvider.getStubBindingRoot(); - for (Language language : viewProvider.getLanguages()) { - final PsiFile file = viewProvider.getPsi(language); - if (file instanceof PsiFileImpl) { - final IElementType contentType = ((PsiFileImpl)file).getContentElementType(); - if (contentType instanceof IStubFileElementType) { - roots.add(Trinity.create(language, (IStubFileElementType)contentType, file)); - } - } - } - - ContainerUtil.sort(roots, new Comparator>() { - @Override - public int compare(Trinity o1, Trinity o2) { - if (o1.third == stubBindingRoot) return o2.third == stubBindingRoot ? 0 : -1; - else if (o2.third == stubBindingRoot) return 1; - else return StringUtil.compare(o1.first.getID(), o2.first.getID(), false); - } - }); - - return ContainerUtil.map(roots, new Function, Pair>() { - @Override - public Pair fun(Trinity trinity) { - return Pair.create(trinity.second, trinity.third); - } - }); - } } diff --git a/platform/indexing-impl/src/com/intellij/psi/stubs/StubProcessingHelperBase.java b/platform/indexing-impl/src/com/intellij/psi/stubs/StubProcessingHelperBase.java index b45be7a17c22..83bd87271fc4 100644 --- a/platform/indexing-impl/src/com/intellij/psi/stubs/StubProcessingHelperBase.java +++ b/platform/indexing-impl/src/com/intellij/psi/stubs/StubProcessingHelperBase.java @@ -3,16 +3,17 @@ package com.intellij.psi.stubs; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiPlainTextFile; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.impl.source.PsiFileWithStubSupport; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IStubFileElementType; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.Processor; -import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -51,12 +52,11 @@ public abstract class StubProcessingHelperBase { boolean customStubs = false; if (candidatePsiFile != null && !(candidatePsiFile instanceof PsiPlainTextFile)) { - final FileViewProvider viewProvider = candidatePsiFile.getViewProvider(); - final PsiFile stubBindingRoot = viewProvider.getStubBindingRoot(); - if (stubBindingRoot instanceof PsiFileWithStubSupport) { - psiFile = (PsiFileWithStubSupport)stubBindingRoot; + candidatePsiFile = candidatePsiFile.getViewProvider().getStubBindingRoot(); + if (candidatePsiFile instanceof PsiFileWithStubSupport) { + psiFile = (PsiFileWithStubSupport)candidatePsiFile; stubTree = psiFile.getStubTree(); - if (stubTree == null && psiFile instanceof PsiFileImpl) { + if (stubTree == null && psiFile instanceof PsiFileImpl) { IElementType contentElementType = ((PsiFileImpl)psiFile).getContentElementType(); if (contentElementType instanceof IStubFileElementType) { stubTree = ((PsiFileImpl)psiFile).calcStubTree(); @@ -67,26 +67,6 @@ public abstract class StubProcessingHelperBase { } } } - if (!customStubs && stubTree != null) { - final List roots = new SmartList(stubTree.getRoot()); - final List> stubbedRoots = StubTreeBuilder.getStubbedRoots(viewProvider); - for (Pair stubbedRoot : stubbedRoots) { - if (stubbedRoot.second == stubBindingRoot) continue; - if (stubbedRoot.second instanceof PsiFileImpl) { - final StubTree secondaryStubTree = ((PsiFileImpl)stubbedRoot.second).calcStubTree(); - if (secondaryStubTree != null) { - final PsiFileStub root = secondaryStubTree.getRoot(); - roots.add(root); - } - } - } - final PsiFileStub[] rootsArray = roots.toArray(new PsiFileStub[roots.size()]); - for (PsiFileStub root : rootsArray) { - if (root instanceof PsiFileStubImpl) { - ((PsiFileStubImpl)root).setStubRoots(rootsArray); - } - } - } } if (stubTree == null && psiFile == null) { @@ -101,7 +81,7 @@ public abstract class StubProcessingHelperBase { return processor.process((Psi)psiFile); // e.g. dom indices } stubTree = (StubTree)objectStubTree; - final List> plained = stubTree.getPlainListFromAllRoots(); + final List> plained = stubTree.getPlainList(); for (int i = 0, size = value.size(); i < size; i++) { final int stubTreeIndex = value.get(i); if (stubTreeIndex >= plained.size()) { @@ -148,7 +128,7 @@ public abstract class StubProcessingHelperBase { } } else { - final List> plained = stubTree.getPlainListFromAllRoots(); + final List> plained = stubTree.getPlainList(); for (int i = 0, size = value.size(); i < size; i++) { final int stubTreeIndex = value.get(i); if (stubTreeIndex >= plained.size()) { diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java index 0819ee39e1cf..577494fa216d 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingIndex.java @@ -341,10 +341,7 @@ public class StubUpdatingIndex extends CustomImplementationFileBasedIndexExtensi if (!data.isEmpty()) { final SerializedStubTree stub = data.values().iterator().next(); ObjectStubBase root = (ObjectStubBase)stub.getStub(true); - - ObjectStubTree objectStubTree = root instanceof PsiFileStub ? new StubTree((PsiFileStub)root, false) : - new ObjectStubTree(root, false); - Map> map = objectStubTree.indexStubTree(); + Map> map = new ObjectStubTree(root, false).indexStubTree(); // xxx:fix refs inplace stubTree = (Map)map; diff --git a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataElementType.java b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataElementType.java index 2e814f9f2290..00f8cfe409eb 100644 --- a/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataElementType.java +++ b/platform/lang-impl/src/com/intellij/psi/templateLanguages/TemplateDataElementType.java @@ -32,7 +32,7 @@ import com.intellij.psi.impl.source.DummyHolder; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.IStubFileElementType; +import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.TokenSet; import com.intellij.testFramework.LightVirtualFile; import com.intellij.util.CharTable; @@ -46,7 +46,7 @@ import javax.swing.*; /** * @author peter */ -public class TemplateDataElementType extends IStubFileElementType implements ITemplateDataElementType { +public class TemplateDataElementType extends IFileElementType implements ITemplateDataElementType { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.templateLanguages.TemplateDataElementType"); public static final LanguageExtension TREE_PATCHER = new LanguageExtension("com.intellij.lang.treePatcher", new SimpleTreePatcher()); @@ -72,8 +72,7 @@ public class TemplateDataElementType extends IStubFileElementType implements ITe public ASTNode parseContents(ASTNode chameleon) { final CharTable table = SharedImplUtil.findCharTableByTree(chameleon); final FileElement treeElement = new DummyHolder(((TreeElement)chameleon).getManager(), null, table).getTreeElement(); - final FileElement fileElement = TreeUtil.getFileElement((TreeElement)chameleon); - final PsiFile file = (PsiFile)fileElement.getPsi(); + final PsiFile file = (PsiFile)TreeUtil.getFileElement((TreeElement)chameleon).getPsi(); PsiFile originalFile = file.getOriginalFile(); final TemplateLanguageFileViewProvider viewProvider = (TemplateLanguageFileViewProvider)originalFile.getViewProvider(); @@ -113,10 +112,8 @@ public class TemplateDataElementType extends IStubFileElementType implements ITe DebugUtil.checkTreeStructure(parsed); DebugUtil.checkTreeStructure(treeElement); DebugUtil.checkTreeStructure(chameleon); - if (fileElement != chameleon) { - DebugUtil.checkTreeStructure(file.getNode()); - DebugUtil.checkTreeStructure(originalFile.getNode()); - } + DebugUtil.checkTreeStructure(file.getNode()); + DebugUtil.checkTreeStructure(originalFile.getNode()); return childNode; } From 02192ce18b038bee3c476195a2693a0ee2ee17df Mon Sep 17 00:00:00 2001 From: Michael Golubev Date: Tue, 25 Nov 2014 19:37:23 +0100 Subject: [PATCH 27/38] IDEA-105509 - CreateProcess error=87 - Due to empty environment variables --- .../execution/util/EnvVariablesTable.java | 23 ++++ .../execution/util/ListTableWithButtons.java | 18 ++- .../impl/ConfigurationSettingsEditor.java | 112 ++++++++++++++---- .../ConfigurationSettingsEditorWrapper.java | 9 ++ .../execution/impl/RunConfigurable.java | 10 +- .../impl/SingleConfigurationConfigurable.java | 18 ++- .../openapi/options/GroupSettingsBuilder.java | 14 +++ 7 files changed, 175 insertions(+), 29 deletions(-) diff --git a/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java b/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java index eb774d58a32c..e500ff630124 100644 --- a/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java +++ b/platform/lang-api/src/com/intellij/execution/util/EnvVariablesTable.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.AnActionButton; import com.intellij.util.containers.ContainerUtil; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.util.ui.ColumnInfo; import com.intellij.util.ui.ListTableModel; import org.jetbrains.annotations.NotNull; @@ -93,6 +94,28 @@ public class EnvVariablesTable extends ListTableWithButtons return new ListTableModel((new ColumnInfo[]{name, value})); } + public void editVariableName(final EnvironmentVariable environmentVariable) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + + @Override + public void run() { + final EnvironmentVariable actualEnvVar = ContainerUtil.find(getElements(), new Condition() { + @Override + public boolean value(EnvironmentVariable item) { + return StringUtil.equals(environmentVariable.getName(), item.getName()); + } + }); + if (actualEnvVar == null) { + return; + } + + setSelection(actualEnvVar); + if (actualEnvVar.getNameIsWriteable()) { + editSelection(0); + } + } + }); + } public List getEnvironmentVariables() { return getElements(); diff --git a/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java b/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java index f310a3c59603..278b8bfd8de8 100644 --- a/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java +++ b/platform/lang-api/src/com/intellij/execution/util/ListTableWithButtons.java @@ -16,10 +16,7 @@ package com.intellij.execution.util; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.ui.AnActionButton; -import com.intellij.ui.AnActionButtonRunnable; -import com.intellij.ui.AnActionButtonUpdater; -import com.intellij.ui.ToolbarDecorator; +import com.intellij.ui.*; import com.intellij.ui.table.TableView; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.ColumnInfo; @@ -32,6 +29,7 @@ import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; +import java.util.Collections; import java.util.List; import java.util.Observable; @@ -172,6 +170,18 @@ public abstract class ListTableWithButtons extends Observable { myTableView.getComponent().repaint(); } + protected void setSelection(T element) { + myTableView.setSelection(Collections.singleton(element)); + TableUtil.scrollSelectionToVisible(myTableView); + } + + protected void editSelection(int column) { + int row = myElements.indexOf(getSelection()); + if (row != -1) { + TableUtil.editCellAt(myTableView, row, column); + } + } + protected abstract T createElement(); protected abstract boolean isEmpty(T element); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditor.java b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditor.java index 7bae2105014a..f95fa0ab1499 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditor.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditor.java @@ -22,12 +22,14 @@ import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.RunnerSettings; import com.intellij.execution.runners.ProgramRunner; import com.intellij.openapi.options.*; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ListScrollingUtil; import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Convertor; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -36,25 +38,30 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; -import java.util.ArrayList; -import java.util.Collection; +import java.util.*; import java.util.List; /** * @author dyoma */ -class ConfigurationSettingsEditor extends CompositeSettingsEditor { +public class ConfigurationSettingsEditor extends CompositeSettingsEditor { private final ArrayList> myRunnerEditors = new ArrayList>(); + private final Map> myRunner2UnwrappedEditors = new HashMap>(); private RunnersEditorComponent myRunnersComponent; private final RunConfiguration myConfiguration; private final SettingsEditor myConfigurationEditor; private SettingsEditorGroup myCompound; + private static final String RUNNERS_TAB_NAME = ExecutionBundle.message("run.configuration.startup.connection.rab.title"); + + private GroupSettingsBuilder myGroupSettingsBuilder; + @Override public CompositeSettingsBuilder getBuilder() { init(); - return new GroupSettingsBuilder(myCompound); + myGroupSettingsBuilder = new GroupSettingsBuilder(myCompound); + return myGroupSettingsBuilder; } private void init() { @@ -88,7 +95,7 @@ class ConfigurationSettingsEditor extends CompositeSettingsEditor 0) { - myCompound.addEditor(ExecutionBundle.message("run.configuration.startup.connection.rab.title"), + myCompound.addEditor(RUNNERS_TAB_NAME, new CompositeSettingsEditor(getFactory()) { @Override public CompositeSettingsBuilder getBuilder() { @@ -125,27 +132,25 @@ class ConfigurationSettingsEditor extends CompositeSettingsEditor wrappedConfigEditor = null; SettingsEditor wrappedRunEditor = null; if (configEditor != null) { - wrappedConfigEditor = new SettingsEditorWrapper(configEditor, - new Convertor() { - @Override - public ConfigurationPerRunnerSettings convert(RunnerAndConfigurationSettings configurationSettings) { - return configurationSettings.getConfigurationSettings(runner); - } - }); - myRunnerEditors.add(wrappedConfigEditor); - Disposer.register(this, wrappedConfigEditor); + wrappedConfigEditor = wrapEditor(configEditor, + new Convertor() { + @Override + public ConfigurationPerRunnerSettings convert(RunnerAndConfigurationSettings configurationSettings) { + return configurationSettings.getConfigurationSettings(runner); + } + }, + runner); } if (runnerEditor != null) { - wrappedRunEditor = new SettingsEditorWrapper(runnerEditor, - new Convertor() { - @Override - public RunnerSettings convert(RunnerAndConfigurationSettings configurationSettings) { - return configurationSettings.getRunnerSettings(runner); - } - }); - myRunnerEditors.add(wrappedRunEditor); - Disposer.register(this, wrappedRunEditor); + wrappedRunEditor = wrapEditor(runnerEditor, + new Convertor() { + @Override + public RunnerSettings convert(RunnerAndConfigurationSettings configurationSettings) { + return configurationSettings.getRunnerSettings(runner); + } + }, + runner); } if (wrappedRunEditor != null && wrappedConfigEditor != null) { @@ -161,6 +166,55 @@ class ConfigurationSettingsEditor extends CompositeSettingsEditor SettingsEditor wrapEditor(SettingsEditor editor, + Convertor convertor, + ProgramRunner runner) { + SettingsEditor wrappedEditor + = new SettingsEditorWrapper(editor, convertor); + + List unwrappedEditors = myRunner2UnwrappedEditors.get(runner); + if (unwrappedEditors == null) { + unwrappedEditors = new ArrayList(); + myRunner2UnwrappedEditors.put(runner, unwrappedEditors); + } + unwrappedEditors.add(editor); + + myRunnerEditors.add(wrappedEditor); + Disposer.register(this, wrappedEditor); + + return wrappedEditor; + } + + public T selectExecutorAndGetEditor(final ProgramRunner runner, Class editorClass) { + myGroupSettingsBuilder.selectEditor(RUNNERS_TAB_NAME); + Executor executor = ContainerUtil.find(myRunnersComponent.getExecutors(), new Condition() { + + @Override + public boolean value(Executor executor) { + return runner.equals(RunnerRegistry.getInstance().getRunner(executor.getId(), myConfiguration)); + } + }); + if (executor == null) { + return null; + } + myRunnersComponent.selectExecutor(executor); + return ContainerUtil.findInstance(myRunner2UnwrappedEditors.get(runner), editorClass); + } + + public T selectTabAndGetEditor(Class editorClass) { + for (Pair> name2editor : myCompound.getEditors()) { + SettingsEditor editor = name2editor.getSecond(); + if (editor instanceof ConfigToSettingsWrapper) { + SettingsEditor configEditor = ((ConfigToSettingsWrapper)editor).getConfigEditor(); + if (editorClass.isInstance(configEditor)) { + myGroupSettingsBuilder.selectEditor(name2editor.getFirst()); + return editorClass.cast(configEditor); + } + } + } + return null; + } + public ConfigurationSettingsEditor(RunnerAndConfigurationSettings settings) { super(settings.createFactory()); myConfigurationEditor = (SettingsEditor)settings.getConfiguration().getConfigurationEditor(); @@ -224,6 +278,14 @@ class ConfigurationSettingsEditor extends CompositeSettingsEditor getExecutors() { + return Collections.list((Enumeration)myListModel.elements()); + } + + public void selectExecutor(Executor executor) { + myRunnersList.setSelectedValue(executor, true); + } + public JComponent getComponent() { return myRunnersPanel; } @@ -239,6 +301,10 @@ class ConfigurationSettingsEditor extends CompositeSettingsEditor getConfigEditor() { + return myConfigEditor; + } + @Override public void resetEditorFrom(RunnerAndConfigurationSettings configurationSettings) { myConfigEditor.resetFrom(configurationSettings.getConfiguration()); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java index 72a9e3b35e03..700644ce2411 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java @@ -20,6 +20,7 @@ import com.intellij.execution.BeforeRunTask; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.UnknownRunConfiguration; +import com.intellij.execution.runners.ProgramRunner; import com.intellij.ide.DataManager; import com.intellij.ide.impl.TypeSafeDataProviderAdapter; import com.intellij.ide.util.PropertiesComponent; @@ -55,6 +56,14 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor T selectExecutorAndGetEditor(ProgramRunner runner, Class editorClass) { + return myEditor.selectExecutorAndGetEditor(runner, editorClass); + } + + public T selectTabAndGetEditor(Class editorClass) { + return myEditor.selectTabAndGetEditor(editorClass); + } + public ConfigurationSettingsEditorWrapper(final RunnerAndConfigurationSettings settings) { myEditor = new ConfigurationSettingsEditor(settings); Disposer.register(this, myEditor); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java index 0763cf6b82cf..76d2a33853ad 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java @@ -20,6 +20,7 @@ import com.intellij.execution.*; import com.intellij.execution.configuration.ConfigurationFactoryEx; import com.intellij.execution.configurations.*; import com.intellij.icons.AllIcons; +import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; @@ -387,11 +388,18 @@ class RunConfigurable extends BaseConfigurable { myRightPanel.removeAll(); mySelectedConfigurable = configurable; - final JBScrollPane scrollPane = new JBScrollPane(configurable.createComponent()); + JComponent configurableComponent = configurable.createComponent(); + final JBScrollPane scrollPane = new JBScrollPane(configurableComponent); scrollPane.setBorder(null); myRightPanel.add(scrollPane, BorderLayout.CENTER); if (configurable instanceof SingleConfigurationConfigurable) { myRightPanel.add(((SingleConfigurationConfigurable)configurable).getValidationComponent(), BorderLayout.SOUTH); + if (configurableComponent != null) { + DataProvider dataProvider = DataManager.getDataProvider(configurableComponent); + if (dataProvider != null) { + DataManager.registerDataProvider(myRightPanel, dataProvider); + } + } } setupDialogBounds(); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java index 4a750f22a15d..b881784b1dd9 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/SingleConfigurationConfigurable.java @@ -20,6 +20,11 @@ import com.intellij.execution.*; import com.intellij.execution.configurations.*; import com.intellij.execution.runners.ProgramRunner; import com.intellij.icons.AllIcons; +import com.intellij.ide.DataManager; +import com.intellij.ide.impl.TypeSafeDataProviderAdapter; +import com.intellij.openapi.actionSystem.DataKey; +import com.intellij.openapi.actionSystem.DataSink; +import com.intellij.openapi.actionSystem.TypeSafeDataProvider; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SettingsEditor; @@ -126,7 +131,9 @@ public final class SingleConfigurationConfigurable" + configurationException.getTitle() + ": " + configurationException.getMessage() + ""; } } + + private class MyDataProvider implements TypeSafeDataProvider { + @Override + public void calcData(DataKey key, DataSink sink) { + if (key.equals(ConfigurationSettingsEditorWrapper.CONFIGURATION_EDITOR_KEY)) { + sink.put(ConfigurationSettingsEditorWrapper.CONFIGURATION_EDITOR_KEY, (ConfigurationSettingsEditorWrapper)getEditor()); + } + } + } } diff --git a/platform/platform-api/src/com/intellij/openapi/options/GroupSettingsBuilder.java b/platform/platform-api/src/com/intellij/openapi/options/GroupSettingsBuilder.java index 5d9328c88396..ce46d82e588d 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/GroupSettingsBuilder.java +++ b/platform/platform-api/src/com/intellij/openapi/options/GroupSettingsBuilder.java @@ -16,6 +16,7 @@ package com.intellij.openapi.options; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.components.JBTabbedPane; import javax.swing.*; @@ -63,4 +64,17 @@ public class GroupSettingsBuilder implements CompositeSettingsBuilder { return tabs; } + + public void selectEditor(String tabName) { + List>> editors = myGroup.getEditors(); + if (myComponent != null && editors.size() > 1) { + for (int i = 0; i < editors.size(); i++) { + Pair> pair = editors.get(i); + if (StringUtil.equals(tabName, pair.getFirst())) { + ((JTabbedPane)myComponent).setSelectedIndex(i); + return; + } + } + } + } } \ No newline at end of file From 3d1552b7173ceec9b22c43c28316f0eac8b6faf8 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 25 Nov 2014 20:42:28 +0100 Subject: [PATCH 28/38] make isTopFrameSelected method public --- .../src/com/intellij/xdebugger/impl/XDebugSessionImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index a3af1e13a874..77d3fc1b47e2 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -572,7 +572,7 @@ public class XDebugSessionImpl implements XDebugSession { myDebuggerManager.updateExecutionPoint(myCurrentStackFrame.getSourcePosition(), !isTopFrame, getPositionIconRenderer(isTopFrame)); } - private boolean isTopFrameSelected() { + public boolean isTopFrameSelected() { return myCurrentExecutionStack != null && myIsTopFrame; } From fba7237298d85e3d685e067dc9478da51ab24694 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 25 Nov 2014 20:43:49 +0100 Subject: [PATCH 29/38] there are different line highlighters now for execution line. Check for top frame --- .../xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java index a71b6ec5de7a..a346eef46ea0 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java @@ -34,6 +34,7 @@ import com.intellij.util.NotNullProducer; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.frame.presentation.XValuePresentation; +import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.frame.XDebugView; import com.intellij.xdebugger.impl.frame.XVariablesView; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; @@ -98,7 +99,9 @@ public class XDebuggerEditorLinePainter extends EditorLinePainter { catch (Exception e) { continue; } - final Color color = bpLine == lineNumber ? new JBColor(new Color(0, 255, 86), new Color(255, 235, 9)) : getForeground(); + XDebugSession session = XDebugView.getSession(values.iterator().next().getTree()); + boolean isTopFrame = session instanceof XDebugSessionImpl && ((XDebugSessionImpl)session).isTopFrameSelected(); + final Color color = bpLine == lineNumber && isTopFrame ? new JBColor(new Color(0, 255, 86), new Color(255, 235, 9)) : getForeground(); final String name = value.getName(); if (StringUtil.isEmpty(text.toString())) { From 17c1e4254ad3e83ce23df681d84eea6939e566f4 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Tue, 25 Nov 2014 23:12:41 +0300 Subject: [PATCH 30/38] [vcs] IDEA-133320 Fix html tag in notification text --- .../com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java index 8be0c61e7c42..be69c616f31b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootProblemNotifier.java @@ -186,7 +186,7 @@ public class VcsRootProblemNotifier { description.append("
"); } - String add = invalidRoots.isEmpty() ? "Add " + pluralize("root", unregisteredRoots.size()) + "  " : ""; + String add = invalidRoots.isEmpty() ? "Add " + pluralize("root", unregisteredRoots.size()) + "  " : ""; String configure = "Configure"; String ignore = invalidRoots.isEmpty() ? "  Ignore" : ""; description.append(add + configure + ignore); From 3eaad2e221a154573f096854a41792997e3639ea Mon Sep 17 00:00:00 2001 From: Michael Golubev Date: Tue, 25 Nov 2014 22:15:36 +0100 Subject: [PATCH 31/38] CR-IC-6875 - get rid of TypeSafeDataProvider --- .../ConfigurationSettingsEditorWrapper.java | 18 ++++++++++-------- .../impl/SingleConfigurationConfigurable.java | 18 +++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java index 700644ce2411..a1cb7b8c23f3 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java @@ -22,17 +22,16 @@ import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.UnknownRunConfiguration; import com.intellij.execution.runners.ProgramRunner; import com.intellij.ide.DataManager; -import com.intellij.ide.impl.TypeSafeDataProviderAdapter; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.DataKey; -import com.intellij.openapi.actionSystem.DataSink; -import com.intellij.openapi.actionSystem.TypeSafeDataProvider; +import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.util.Disposer; import com.intellij.ui.HideableDecorator; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -100,7 +99,7 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor Date: Tue, 25 Nov 2014 17:07:38 +0100 Subject: [PATCH 32/38] =?UTF-8?q?aware=20of=20boolean.class=20=E2=80=94=20?= =?UTF-8?q?kotlin=20creates=20primitive=20boolean=20class=20from=20javaCla?= =?UTF-8?q?ss()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/intellij/ui/table/TableView.java | 24 ++++++++++++++++++- .../util/ui/table/TableModelEditor.java | 7 +++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/table/TableView.java b/platform/platform-api/src/com/intellij/ui/table/TableView.java index 6051152c07fc..1be1903bf18b 100644 --- a/platform/platform-api/src/com/intellij/ui/table/TableView.java +++ b/platform/platform-api/src/com/intellij/ui/table/TableView.java @@ -15,6 +15,7 @@ */ package com.intellij.ui.table; +import com.intellij.ui.BooleanTableCellRenderer; import com.intellij.ui.GuiUtils; import com.intellij.ui.TableUtil; import com.intellij.util.SmartList; @@ -266,6 +267,24 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel TableUtil.stopEditing(this); } + @Override + protected void createDefaultRenderers() { + super.createDefaultRenderers(); + + UIDefaults.LazyValue booleanRenderer = new UIDefaults.LazyValue() { + @Override + public Object createValue(@NotNull UIDefaults table) { + DefaultCellEditor editor = new DefaultCellEditor(GuiUtils.createUndoableTextField()); + editor.setClickCountToStart(1); + return new BooleanTableCellRenderer(); + } + }; + //noinspection unchecked + defaultRenderersByColumnClass.put(boolean.class, booleanRenderer); + //noinspection unchecked + defaultRenderersByColumnClass.put(Boolean.class, booleanRenderer); + } + @Override protected void createDefaultEditors() { super.createDefaultEditors(); @@ -273,11 +292,14 @@ public class TableView extends BaseTableView implements ItemsProvider, Sel //noinspection unchecked defaultEditorsByColumnClass.put(String.class, new UIDefaults.LazyValue() { @Override - public Object createValue(UIDefaults table) { + public Object createValue(@NotNull UIDefaults table) { DefaultCellEditor editor = new DefaultCellEditor(GuiUtils.createUndoableTextField()); editor.setClickCountToStart(1); return editor; } }); + + //noinspection unchecked + defaultEditorsByColumnClass.put(boolean.class, defaultEditorsByColumnClass.get(Boolean.class)); } } diff --git a/platform/platform-impl/src/com/intellij/util/ui/table/TableModelEditor.java b/platform/platform-impl/src/com/intellij/util/ui/table/TableModelEditor.java index 8b148a3d791d..63d38ed57fcb 100644 --- a/platform/platform-impl/src/com/intellij/util/ui/table/TableModelEditor.java +++ b/platform/platform-impl/src/com/intellij/util/ui/table/TableModelEditor.java @@ -76,7 +76,8 @@ public class TableModelEditor implements ElementProducer { table.setEnableAntialiasing(true); preferredScrollableViewportHeightInRows(JBTable.PREFERRED_SCROLLABLE_VIEWPORT_HEIGHT_IN_ROWS); new TableSpeedSearch(table); - if (columns[0].getColumnClass() == Boolean.class && columns[0].getName().isEmpty()) { + ColumnInfo firstColumn = columns[0]; + if ((firstColumn.getColumnClass() == boolean.class || firstColumn.getColumnClass() == Boolean.class) && firstColumn.getName().isEmpty()) { TableUtil.setupCheckboxColumn(table.getColumnModel().getColumn(0)); } @@ -168,7 +169,7 @@ public class TableModelEditor implements ElementProducer { public abstract void dataChanged(@NotNull ColumnInfo columnInfo, int rowIndex); @Override - public void tableChanged(TableModelEvent e) { + public void tableChanged(@NotNull TableModelEvent e) { } } @@ -357,7 +358,7 @@ public class TableModelEditor implements ElementProducer { return toolbarDecorator.addExtraAction( new ToolbarDecorator.ElementActionButton(IdeBundle.message("button.copy"), PlatformIcons.COPY_ICON) { @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { TableUtil.stopEditing(table); List selectedItems = table.getSelectedObjects(); From d3896aa011fffb2311dcdfb6f96429d6c5f0cd49 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 25 Nov 2014 17:08:27 +0100 Subject: [PATCH 33/38] don't create panel for titlePane if not needed --- .../src/com/intellij/openapi/ui/DialogWrapper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java index 00bf9d23c16c..e3a2e9757f97 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java @@ -1204,11 +1204,11 @@ public abstract class DialogWrapper { }; toggleShowOptions.registerCustomShortcutSet(sc, root); - final JPanel northSection = new JPanel(new BorderLayout()); - root.add(northSection, BorderLayout.NORTH); - JComponent titlePane = createTitlePane(); if (titlePane != null) { + JPanel northSection = new JPanel(new BorderLayout()); + root.add(northSection, BorderLayout.NORTH); + northSection.add(titlePane, BorderLayout.CENTER); } From e2274ebcf6e1da38e302ddaa0a5abd0b13ef5740 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 26 Nov 2014 08:29:41 +0100 Subject: [PATCH 34/38] cleanup --- .../src/com/intellij/ide/browsers/BrowserSettingsPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/impl/src/com/intellij/ide/browsers/BrowserSettingsPanel.java b/xml/impl/src/com/intellij/ide/browsers/BrowserSettingsPanel.java index a904e9c57e6a..6869262765c4 100644 --- a/xml/impl/src/com/intellij/ide/browsers/BrowserSettingsPanel.java +++ b/xml/impl/src/com/intellij/ide/browsers/BrowserSettingsPanel.java @@ -278,7 +278,7 @@ final class BrowserSettingsPanel { browsersEditor = new TableModelEditor(COLUMNS, itemEditor, "No web browsers configured") .modelListener(new TableModelEditor.DataChangedListener() { @Override - public void tableChanged(TableModelEvent event) { + public void tableChanged(@NotNull TableModelEvent event) { update(); } From 87bd26df440726d5c1c0c973a5323bbd54374099 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Wed, 26 Nov 2014 12:59:22 +0200 Subject: [PATCH 35/38] sample code in code style settings preview: added initializer block, corrected blank lines after initializer block behaviour --- ...JavaLanguageCodeStyleSettingsProvider.java | 4 +++ .../java/JavaSpacePropertyProcessor.java | 6 ++++- .../java/JavaFormatterBlankLinesTest.java | 25 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java b/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java index 37332ff434dc..9690ccf825c8 100644 --- a/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java +++ b/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java @@ -272,6 +272,10 @@ public class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSett " private int field1;\n" + " private int field2;\n" + "\n" + + " {\n" + + " field1 = 2;\n" + + " }\n" + + "\n" + " public void foo1() {\n" + " new Runnable() {\n" + " public void run() {\n" + diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index 7957119898d1..f544a071997d 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -428,7 +428,7 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { } else if (myRole1 == ChildRole.FIELD) { int blankLines = myJavaSettings.BLANK_LINES_AROUND_INITIALIZER + 1; - myResult = Spacing.createSpacing(0, mySettings.SPACE_BEFORE_CLASS_LBRACE ? 1 : 0, blankLines, true, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE); + myResult = Spacing.createSpacing(0, mySettings.SPACE_BEFORE_CLASS_LBRACE ? 1 : 0, blankLines, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE); } else if (myRole1 == ChildRole.CLASS) { setAroundClassSpacing(); @@ -547,6 +547,10 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { if (myRole1 == ChildRole.LBRACE) { myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, 0); } + else if (myRole1 == ChildRole.CLASS_INITIALIZER) { + int blankLines = myJavaSettings.BLANK_LINES_AROUND_INITIALIZER + 1; + myResult = Spacing.createSpacing(0, Integer.MAX_VALUE, blankLines, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_BEFORE_RBRACE); + } else { final int blankLines = getLinesAroundMethod() + 1; myResult = Spacing.createSpacing(0, 0, blankLines, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS); diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBlankLinesTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBlankLinesTest.java index e0c845d066c6..e50e1ec8076f 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBlankLinesTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterBlankLinesTest.java @@ -433,4 +433,29 @@ public class JavaFormatterBlankLinesTest extends AbstractJavaFormatterTest { "}" ); } + + public void testBlankLinesAroundInitializer() { + getJavaSettings().BLANK_LINES_AROUND_INITIALIZER = 3; + doTextTest( + "public class JavaClass {\n" + + " int a = 3;\n" + + " {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + "\n" + + " public void test() {\n" + + " }\n" + + "}", + "public class JavaClass {\n" + + " int a = 3;\n" + + "\n\n\n" + + " {\n" + + " System.out.println(\"Hello\");\n" + + " }\n" + + "\n\n\n" + + " public void test() {\n" + + " }\n" + + "}" + ); + } } From 58e2620010a621574ff712c1894ee2d699623c58 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Wed, 26 Nov 2014 13:14:08 +0300 Subject: [PATCH 36/38] fix duplicates not detected in case they intersect: do not remove old fragments unless they are cheaper or fully contained in new fragment --- .../treeHash/DuplocatorHashCallback.java | 16 ++++++++++------ .../intellij/dupLocator/util/PsiFragment.java | 10 ++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplocatorHashCallback.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplocatorHashCallback.java index 03685d181afc..ea1aefba5593 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplocatorHashCallback.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/treeHash/DuplocatorHashCallback.java @@ -112,16 +112,20 @@ public class DuplocatorHashCallback implements FragmentsCollector { PsiFragment aFrag = fi.get(0); if (aFrag.isEqual(elements, discardCost)) { - boolean skip = false; + boolean skipNew = false; - for (Iterator frags = fi.iterator(); frags.hasNext() && !skip; ) { - skip = frag.intersectsWith(frags.next()); - if (skip) { - frags.remove(); + for (Iterator frags = fi.iterator(); frags.hasNext() && !skipNew; ) { + final PsiFragment old = frags.next(); + if (frag.intersectsWith(old)) { + if (old.getCost() < frag.getCost() || frag.contains(old)) { + frags.remove(); + } else { + skipNew = true; + } } } - fi.add(frag); + if (!skipNew) fi.add(frag); found = true; } diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/util/PsiFragment.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/util/PsiFragment.java index 5bf5b3e137e7..b9b9cc26a22a 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/util/PsiFragment.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/util/PsiFragment.java @@ -169,6 +169,16 @@ public abstract class PsiFragment { Comparing.equal(f.getFile(), getFile()) && ((start <= fStart && fStart <= end) || (start <= fEnd && fEnd <= end)); } + public boolean contains(PsiFragment f) { + final int start = getStartOffset(); + final int end = getEndOffset(); + final int fStart = f.getStartOffset(); + final int fEnd = f.getEndOffset(); + + return + Comparing.equal(f.getFile(), getFile()) && (start <= fStart && end >= fEnd); + } + public abstract boolean isEqual(PsiElement[] elements, int discardCost); @Nullable From 63a2dfad30fdca8634a896da59a949fa127ceb3f Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Nov 2014 11:36:35 +0100 Subject: [PATCH 37/38] a dirty fix for gdsl deadlock (IDEA-133502) --- .../jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java index 991425131df9..e9692292588f 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/GroovyDslFileIndex.java @@ -385,6 +385,13 @@ public class GroovyDslFileIndex extends ScalarIndexExtension { return Result.create(Collections.emptyList(), ModificationTracker.NEVER_CHANGED); } + // eagerly initialize some services used by background gdsl parsing threads + // because service init requires a read action + // and there could be a deadlock with a write action waiting already on EDT + // if current thread is inside a non-cancellable read action + GroovyDslExecutor.getIdeaVersion(); + DslActivationStatus.getInstance(); + int count = 0; List result = new ArrayList(); From 4bba9c184b66a6bc8297c20be3aa4e01640610fd Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Nov 2014 11:38:04 +0100 Subject: [PATCH 38/38] make DslActivationStatus thread-safe --- .../plugins/groovy/dsl/DslActivationStatus.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/DslActivationStatus.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/DslActivationStatus.java index b8994fdbea23..de1d162148bb 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/DslActivationStatus.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/dsl/DslActivationStatus.java @@ -38,27 +38,27 @@ public class DslActivationStatus implements PersistentStateComponent { return ServiceManager.getService(DslActivationStatus.class); } - public void activateUntilModification(@NotNull VirtualFile vfile) { + public synchronized void activateUntilModification(@NotNull VirtualFile vfile) { myStatus.put(vfile, ENABLED); } - public void disableFile(@NotNull VirtualFile vfile, @NotNull String error) { + public synchronized void disableFile(@NotNull VirtualFile vfile, @NotNull String error) { myStatus.put(vfile, error); } @Nullable - public String getInactivityReason(VirtualFile file) { + public synchronized String getInactivityReason(VirtualFile file) { String status = myStatus.get(file); return status == null || status == ENABLED ? null : status; } - public boolean isActivated(VirtualFile file) { + public synchronized boolean isActivated(VirtualFile file) { return myStatus.get(file) == ENABLED; } @Nullable @Override - public Element getState() { + public synchronized Element getState() { Element root = new Element("x"); for (Map.Entry entry : myStatus.entrySet()) { VirtualFile file = entry.getKey(); @@ -72,7 +72,7 @@ public class DslActivationStatus implements PersistentStateComponent { } @Override - public void loadState(Element state) { + public synchronized void loadState(Element state) { List children = state.getChildren("file"); for (Element element : children) { String url = element.getAttributeValue("url", "");