From d3a08b9513255906dca7d795d948125feb84ecb1 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Wed, 16 Feb 2011 19:50:31 +0300 Subject: [PATCH 01/90] heavyweight editor hints look fix --- .../com/intellij/codeInsight/lookup/impl/LookupImpl.java | 2 -- .../src/com/intellij/codeInsight/hint/HintManagerImpl.java | 2 +- .../platform-impl/src/com/intellij/ui/LightweightHint.java | 6 +++--- platform/platform-resources-en/src/misc/registry.properties | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 68e544cc82f8..9e8ae7915aec 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1158,8 +1158,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { panel.remove(0); panel.add(hintComponent); } - //todo[kirillk] comment the following line - HintManagerImpl.adjustEditorHintPosition(myAutopopupHint, editor, bestPoint); } } diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java index e8abfbfcd70b..c9291dc10394 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java @@ -369,7 +369,7 @@ public class HintManagerImpl extends HintManager implements Disposable { p = rectangle.getLocation(); SwingUtilities.convertPointFromScreen(p, layeredPane); } - else if ((layeredPane.getWidth() < p.x + size.width) && !hintInfo.isAwtTooltip()) { + else if ((layeredPane.getWidth() < p.x + size.width) && !hintInfo.isAwtTooltip() && !hint.isRealPopup()) { p.x = Math.max(0, layeredPane.getWidth() - size.width); } diff --git a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java index 8743c13f8324..a95522649c04 100644 --- a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java +++ b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java @@ -185,11 +185,11 @@ public class LightweightHint extends UserDataHolderBase implements Hint { .setMovable(myTitle != null) .setTitle(myTitle) .setModalContext(false) - .setShowShadow(!myForceLightweightPopup && myForceShowAsPopup) + .setShowShadow(isRealPopup()) .setCancelKeyEnabled(false) .setCancelOnClickOutside(myCancelOnClickOutside) .setCancelOnOtherWindowOpen(myCancelOnOtherWindowOpen) - .setForceHeavyweight(!myForceLightweightPopup && myForceShowAsPopup) + .setForceHeavyweight(!myForceLightweightPopup && isRealPopup()) .createPopup(); beforeShow(); @@ -241,7 +241,7 @@ public class LightweightHint extends UserDataHolderBase implements Hint { } public final boolean isRealPopup() { - return myIsRealPopup; + return myIsRealPopup | myForceShowAsPopup; } public void hide() { diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 7e58a12cb257..314156f91f45 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -35,7 +35,7 @@ ide.debugMode=false ide.debugMode.description=Record additonal information to make bug reports more informative ide.forcedShowTooltip=alt ide.forcedShowTooltip.description=Shortcut for forced show tooltip -ide.popup.dropShadow=false +ide.popup.dropShadow=true ide.consumeKnownToolkitBugs=true ide.appIcon.progress=true From fd3f92202fef5e5782e0288a1662dc7af910d381 Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 16 Feb 2011 20:02:35 +0300 Subject: [PATCH 02/90] IDEA-53590 Moving ignored files automatically marks them for add --- .../intellij/openapi/vcs/VcsVFSListener.java | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java index 09ae9dde27a2..29de04c41f31 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java @@ -25,6 +25,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.actions.VcsContextFactory; import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.vcsUtil.VcsUtil; @@ -37,6 +38,8 @@ import java.util.*; * @author yole */ public abstract class VcsVFSListener implements Disposable { + private VcsDirtyScopeManager myDirtyScopeManager; + protected static class MovedFileInfo { public final String myOldPath; public String myNewPath; @@ -59,6 +62,7 @@ public abstract class VcsVFSListener implements Disposable { protected final List myDeletedFiles = new ArrayList(); protected final List myDeletedWithoutConfirmFiles = new ArrayList(); protected final List myMovedFiles = new ArrayList(); + protected final List myDirtyFiles = new ArrayList(); protected enum VcsDeleteType {SILENT, CONFIRM, IGNORE} @@ -66,6 +70,7 @@ public abstract class VcsVFSListener implements Disposable { myProject = project; myVcs = vcs; myChangeListManager = ChangeListManager.getInstance(project); + myDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); final MyVirtualFileAdapter myVFSListener = new MyVirtualFileAdapter(); final MyCommandAdapter myCommandListener = new MyCommandAdapter(); @@ -200,7 +205,14 @@ public abstract class VcsVFSListener implements Disposable { protected void processMovedFile(VirtualFile file, String newParentPath, String newName) { - if (FileStatusManager.getInstance(myProject).getStatus(file) != FileStatus.UNKNOWN) { + final FileStatus status = FileStatusManager.getInstance(myProject).getStatus(file); + if (status == FileStatus.IGNORED) { + if (file.getParent() != null) { + myDirtyFiles.add(file.getParent()); + myDirtyFiles.add(file); // will be at new path + } + } + if (status != FileStatus.UNKNOWN && status != FileStatus.IGNORED) { final String newPath = newParentPath + "/" + newName; boolean foundExistingInfo = false; for (MovedFileInfo info : myMovedFiles) { @@ -359,7 +371,8 @@ public abstract class VcsVFSListener implements Disposable { if (myProject != event.getProject()) return; myCommandLevel--; if (myCommandLevel == 0) { - if (!myAddedFiles.isEmpty() || !myDeletedFiles.isEmpty() || !myDeletedWithoutConfirmFiles.isEmpty() || !myMovedFiles.isEmpty()) { + if (!myAddedFiles.isEmpty() || !myDeletedFiles.isEmpty() || !myDeletedWithoutConfirmFiles.isEmpty() || !myMovedFiles.isEmpty() || + ! myDirtyFiles.isEmpty()) { // avoid reentering commandFinished handler - saving the documents may cause a "before file deletion" event firing, // which will cause closing the text editor, which will itself run a command that will be caught by this listener myCommandLevel++; @@ -379,6 +392,20 @@ public abstract class VcsVFSListener implements Disposable { if (!myMovedFiles.isEmpty()) { executeMoveRename(); } + if (! myDirtyFiles.isEmpty()) { + final List files = new ArrayList(); + final List dirs = new ArrayList(); + for (VirtualFile dirtyFile : myDirtyFiles) { + if (dirtyFile != null) { + if (dirtyFile.isDirectory()) { + dirs.add(dirtyFile); + } else { + files.add(dirtyFile); + } + } + } + myDirtyScopeManager.filesDirty(files, dirs); + } } } } From 7414445e899bd5fbbddeb025104b194a65f857ab Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 17:19:17 +0100 Subject: [PATCH 03/90] completion stats should care of class qualified names (IDEA-65112) --- .../completion/JavaCompletionStatistician.java | 6 ++++-- .../completion/normalSorting/FqnStats.java | 4 ++++ .../completion/NormalCompletionOrderingTest.java | 13 +++++++++++++ .../fixtures/JavaCodeInsightTestFixture.java | 2 +- .../impl/JavaCodeInsightTestFixtureImpl.java | 4 +--- 5 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normalSorting/FqnStats.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java index d782d4137cbc..d05c520a1a67 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionStatistician.java @@ -23,13 +23,11 @@ import com.intellij.psi.*; import com.intellij.psi.statistics.JavaStatisticsManager; import com.intellij.psi.statistics.StatisticsInfo; import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NonNls; /** * @author peter */ public class JavaCompletionStatistician extends CompletionStatistician{ - @NonNls public static final String CLASS_NAME_COMPLETION_PREFIX = "classNameCompletion#"; public StatisticsInfo serialize(final LookupElement element, final CompletionLocation location) { final Object o = element.getObject(); @@ -76,6 +74,10 @@ public class JavaCompletionStatistician extends CompletionStatistician{ if (!isClass && type == CompletionType.BASIC) return JavaStatisticsManager.createInfo(qualifierType, (PsiMember)o); return StatisticsInfo.EMPTY; } + + if (isClass) { + return JavaStatisticsManager.createInfo(qualifierType, (PsiMember)o); + } } if (qualifierType != null) return StatisticsInfo.EMPTY; diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/FqnStats.java b/java/java-tests/testData/codeInsight/completion/normalSorting/FqnStats.java new file mode 100644 index 000000000000..9ba38412a11f --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/FqnStats.java @@ -0,0 +1,4 @@ +class Foo { + Baaax + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java index 8144fd1e8772..c2337c2f945d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java @@ -182,4 +182,17 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { checkPreferredItems(0, "XcodeProjectTemplate", "XcodeConfigurable"); } + public void testFqnStats() { + myFixture.addClass("public interface Baaaaaaar {}"); + myFixture.addClass("package zoo; public interface Baaaaaaar {}"); + + final LookupImpl lookup = invokeCompletion(getTestName(false) + ".java"); + assertEquals("Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(0)).getQualifiedName()); + assertEquals("zoo.Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(1)).getQualifiedName()); + incUseCount(lookup, 1); + + assertEquals("zoo.Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(0)).getQualifiedName()); + assertEquals("Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(1)).getQualifiedName()); + } + } \ No newline at end of file diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java index f7a308580bac..d168a632b97c 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java @@ -29,7 +29,7 @@ import java.io.IOException; public interface JavaCodeInsightTestFixture extends CodeInsightTestFixture { JavaPsiFacade getJavaFacade(); - PsiClass addClass(@NotNull @NonNls final String classText) throws IOException; + PsiClass addClass(@NotNull @NonNls final String classText); @NotNull PsiClass findClass(@NotNull @NonNls String name); diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java index c14dff95cc19..d6ae873272de 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java @@ -27,8 +27,6 @@ import com.intellij.testFramework.fixtures.TempDirTestFixture; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.io.IOException; - /** * @author yole */ @@ -44,7 +42,7 @@ public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl i } @Override - public PsiClass addClass(@NotNull @NonNls final String classText) throws IOException { + public PsiClass addClass(@NotNull @NonNls final String classText) { assertInitialized(); final PsiClass psiClass = addClass(getTempDirPath(), classText); final VirtualFile file = psiClass.getContainingFile().getVirtualFile(); From d43faca81d1fe2a88321114404367987ac1b80c6 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 17:37:30 +0100 Subject: [PATCH 04/90] IDEA-65252 Static nested classes are first proposal on values --- ...ocalVariablesLiteralsAndAnnoMethodsWeigher.java | 5 +++++ .../normalSorting/DispreferInnerClasses.java | 14 ++++++++++++++ .../completion/NormalCompletionOrderingTest.java | 8 +++++++- .../codeInsight/lookup/ComparingClassifier.java | 3 ++- 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normalSorting/DispreferInnerClasses.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java index 4d9450ad5f64..c8a837d1177a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/PreferLocalVariablesLiteralsAndAnnoMethodsWeigher.java @@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull; public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends CompletionWeigher { enum MyResult { + className, classLiteral, normal, superMethodParameters, @@ -54,6 +55,10 @@ public class PreferLocalVariablesLiteralsAndAnnoMethodsWeigher extends Completio if (object instanceof PsiAnnotationMethod && ((PsiAnnotationMethod)object).getContainingClass().isAnnotationType()) { return MyResult.annoMethod; } + + if (object instanceof PsiClass) { + return MyResult.className; + } } return MyResult.normal; diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferInnerClasses.java b/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferInnerClasses.java new file mode 100644 index 000000000000..db2e1d04d69a --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/DispreferInnerClasses.java @@ -0,0 +1,14 @@ +abstract class Base { + public static @interface IfNotParsed {} + + static class X {} +} + +class Derived extends Base { + +} +class B { + void foo(Derived b) { + b. + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java index c2337c2f945d..e3b88bd2b5e5 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionOrderingTest.java @@ -8,6 +8,7 @@ import com.intellij.JavaTestUtil; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.impl.LookupImpl; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import java.util.List; @@ -192,7 +193,12 @@ public class NormalCompletionOrderingTest extends CompletionSortingTestCase { incUseCount(lookup, 1); assertEquals("zoo.Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(0)).getQualifiedName()); - assertEquals("Baaaaaaar", ((JavaPsiClassReferenceElement) lookup.getItems().get(1)).getQualifiedName()); + assertEquals("Baaaaaaar", ((JavaPsiClassReferenceElement)lookup.getItems().get(1)).getQualifiedName()); + } + + public void testDispreferInnerClasses() { + checkPreferredItems(0); //no chosen items + assertFalse(getLookup().getItems().get(0).getObject() instanceof PsiClass); } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java index a4f49b76467a..42e363939a57 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.lookup; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -71,7 +72,7 @@ public abstract class ComparingClassifier extends Classifier { @Override public void describeItems(LinkedHashMap map) { final TreeMap> treeMap = groupByWeights(new ArrayList(map.keySet())); - if (treeMap.size() > 1) { + if (treeMap.size() > 1 || ApplicationManager.getApplication().isUnitTestMode()) { for (Map.Entry> entry: treeMap.entrySet()){ for (T t : entry.getValue()) { final StringBuilder builder = map.get(t); From 05516baf2a771d50ed37dd004a501a7c754246fa Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 18:11:50 +0100 Subject: [PATCH 05/90] those shadows look horrible on linux, revert --- .../platform-impl/src/com/intellij/ui/LightweightHint.java | 6 ++---- platform/platform-resources-en/src/misc/registry.properties | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java index a95522649c04..ee8865ba3a0e 100644 --- a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java +++ b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java @@ -20,13 +20,11 @@ import com.intellij.ide.IdeTooltip; import com.intellij.ide.IdeTooltipManager; import com.intellij.ide.TooltipEvent; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; import com.intellij.ui.awt.RelativePoint; -import com.intellij.ui.popup.AbstractPopup; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -185,11 +183,11 @@ public class LightweightHint extends UserDataHolderBase implements Hint { .setMovable(myTitle != null) .setTitle(myTitle) .setModalContext(false) - .setShowShadow(isRealPopup()) + .setShowShadow(!myForceLightweightPopup && myForceShowAsPopup) .setCancelKeyEnabled(false) .setCancelOnClickOutside(myCancelOnClickOutside) .setCancelOnOtherWindowOpen(myCancelOnOtherWindowOpen) - .setForceHeavyweight(!myForceLightweightPopup && isRealPopup()) + .setForceHeavyweight(!myForceLightweightPopup && myForceShowAsPopup) .createPopup(); beforeShow(); diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 314156f91f45..7e58a12cb257 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -35,7 +35,7 @@ ide.debugMode=false ide.debugMode.description=Record additonal information to make bug reports more informative ide.forcedShowTooltip=alt ide.forcedShowTooltip.description=Shortcut for forced show tooltip -ide.popup.dropShadow=true +ide.popup.dropShadow=false ide.consumeKnownToolkitBugs=true ide.appIcon.progress=true From 47be5ffb301789b8d9c256e90a3b13384318f540 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 18:12:20 +0100 Subject: [PATCH 06/90] shadows in hint autopopup, update the size correctly --- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 9e8ae7915aec..f3d7b0b46e91 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1150,13 +1150,13 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { panel.add(hintComponent); myAutopopupHint = new LightweightHint(panel); myAutopopupHint.setForceShowAsPopup(true); - myAutopopupHint.setForceLightweightPopup(true); hintManager.showEditorHint(myAutopopupHint, editor, new Point(bestPoint), HintManagerImpl.HIDE_BY_ESCAPE | HintManagerImpl.UPDATE_BY_SCROLLING, 0, false, hintHint); } else { final JComponent panel = myAutopopupHint.getComponent(); panel.remove(0); panel.add(hintComponent); + HintManagerImpl.adjustEditorHintPosition(myAutopopupHint, editor, bestPoint); } } } From c35483cfef4dc0cb0db95b98073344a280978161 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 18:28:14 +0100 Subject: [PATCH 07/90] shorter list --- .../com/intellij/codeInsight/lookup/impl/LookupImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index f3d7b0b46e91..5d2853265639 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1131,7 +1131,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } else if (myHintMode) { final int itemTextPadding = 2; - final int borderWidth = 1; + final int borderWidth = 0; final JPanel hintComponent = createAutopopupHintComponent(itemTextPadding, borderWidth); Point bestPoint = calculatePosition(hintComponent); @@ -1162,7 +1162,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } private JPanel createAutopopupHintComponent(int itemTextPadding, int borderWidth) { - int maxAutopopupItems = 10; + int maxAutopopupItems = 7; JPanel pane = new JPanel(new GridBagLayout()); pane.setBackground(HintUtil.INFORMATION_COLOR); @@ -1221,7 +1221,9 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { KeymapUtil .getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION)) + " for more suggestions)"; - pane.add(new JLabel(moreText), c); + final JLabel label = new JLabel(moreText); + label.setFont(label.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); + pane.add(label, c); } } From deec377e9668310838a61b5485e1e5a6294eb8a2 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 18:31:24 +0100 Subject: [PATCH 08/90] use registry --- .../completion/CompletionProgressIndicator.java | 10 +++++++--- .../platform-resources-en/src/misc/registry.properties | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index a6bb506cbe7b..5fcd8bf67dc6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -38,6 +38,7 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.ElementPattern; import com.intellij.psi.PsiFile; @@ -102,7 +103,6 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } }; private final Semaphore myDuringCompletionSemaphore = new Semaphore(); - private static final boolean ourHintAutopopup = "true".equals(System.getProperty("hint.autopopup", "false")); private volatile int myCount; @@ -336,7 +336,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement } } - if (isAutopopupCompletion() && ourHintAutopopup) { + if (isAutopopupCompletion() && showHintAutopopup()) { myLookup.setHintMode(true); } else { @@ -348,6 +348,10 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement updateFocus(); } + private static boolean showHintAutopopup() { + return "true".equals(Registry.stringValue("hint.autopopup")); + } + final boolean isInsideIdentifier() { return getIdentifierEndOffset() != getSelectionEndOffset(); } @@ -466,7 +470,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement if (isAutopopupCompletion() && !myLookup.isSelectionTouched() && !myLookup.isCalculating()) { myLookup.refreshUi(); final List items = myLookup.getItems(); - if (!items.isEmpty() && ourHintAutopopup) { + if (!items.isEmpty() && showHintAutopopup()) { return false; } diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 7e58a12cb257..e7786120e6e3 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -116,4 +116,6 @@ vcs.show.history.numbers=true navbar.updateMergeTime=250 navbar.userActivityMergeTime=500 -inspectionGadgets.telemetry.enabled=false \ No newline at end of file +inspectionGadgets.telemetry.enabled=false + +hint.autopopup=false \ No newline at end of file From cdc9a9a5f0c892ff9cfda52cd0af898357a289a0 Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Wed, 16 Feb 2011 20:35:01 +0300 Subject: [PATCH 09/90] IDEA-65144 New library created from downloaded jars is not visible --- .../org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java index a0e12bcf9500..b11a8c027973 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/RepositoryAttachHandler.java @@ -157,7 +157,7 @@ public class RepositoryAttachHandler implements LibraryTableAttachHandler { FileUtil.copy(repoFile, toFile); } } - String url = VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(toFile.getPath())); + final String url = VfsUtil.getUrlForLibraryRoot(toFile); manager.refreshAndFindFileByUrl(url); if (MavenExtraArtifactType.DOCS.getDefaultClassifier().equals(each.getClassifier())) { libraryEditor.addRoot(url, JavadocOrderRootType.getInstance()); From 28d7b61b7789097d442f3074d67d6b1d20efff37 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 16 Feb 2011 18:50:14 +0100 Subject: [PATCH 10/90] more compiler logs --- .../javaCompiler/CompilerParsingThread.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java index e440d1d8666f..6dabf6c78cdc 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -144,6 +144,9 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { processCompiledClass(previousPath); } catch (CacheCorruptedException e) { + if (CompileDriver.ourDebugMode) { + e.printStackTrace(); + } myError = e; LOG.info(e); killProcess(); @@ -177,6 +180,9 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { buffer = StringBuilderSpinAllocator.alloc(); } catch (SpinAllocator.AllocatorExhaustedException e) { + if (CompileDriver.ourDebugMode) { + e.printStackTrace(); + } LOG.info(e); buffer = new StringBuilder(); releaseBuffer = false; @@ -220,6 +226,16 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { try { while(!reader.ready()) { if (isProcessTerminated()) { + if (CompileDriver.ourDebugMode) { + String text; + try { + text = reader.ready()? "ready" : "not ready"; + } + catch (IOException e) { + text = "Exception " + e.getMessage(); + } + System.out.println("COMPILER PARSING THREAD: reader not ready before isTerminatedCheck(), after the check: isReady= " + text); + } return -1; } try { @@ -231,7 +247,7 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { return reader.read(); } catch (IOException e) { - return -1; // When process terminated Process.getInputStream()'s underlaying stream becomes closed on Linux. + return -1; // When process terminated Process.getInputStream()'s underlying stream becomes closed on Linux. } } From a7ee426a7f2fe41d4a52f291d2ed6402d1922622 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 16 Feb 2011 21:26:45 +0300 Subject: [PATCH 11/90] Focus Tracer --- .../internal/focus/FocusTracesAction.java | 67 +++++++++++ .../internal/focus/FocusTracesDialog.form | 54 +++++++++ .../internal/focus/FocusTracesDialog.java | 105 ++++++++++++++++++ .../openapi/wm/impl/FocusManagerImpl.java | 17 +++ .../openapi/wm/impl/FocusRequestInfo.java | 56 ++++++++++ .../src/idea/PlatformActions.xml | 4 + 6 files changed, 303 insertions(+) create mode 100644 platform/platform-impl/src/com/intellij/internal/focus/FocusTracesAction.java create mode 100644 platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.form create mode 100644 platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java create mode 100644 platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java diff --git a/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesAction.java b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesAction.java new file mode 100644 index 000000000000..e90aa6a7b251 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesAction.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2011 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.internal.focus; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.impl.FocusManagerImpl; +import com.intellij.openapi.wm.impl.FocusRequestInfo; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public class FocusTracesAction extends AnAction implements DumbAware { + private static boolean myActive = false; + + public static boolean isActive() { + return myActive; + } + + @Override + public void actionPerformed(AnActionEvent e) { + final Project project = e.getData(PlatformDataKeys.PROJECT); + final IdeFocusManager manager = IdeFocusManager.getGlobalInstance(); + if (! (manager instanceof FocusManagerImpl)) return; + final FocusManagerImpl focusManager = (FocusManagerImpl)manager; + + myActive = !myActive; + + if (!myActive) { + final List requests = focusManager.getRequests(); + new FocusTracesDialog(project, new ArrayList(requests)).show(); + requests.clear(); + } + } + + @Override + public void update(AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + if (myActive) { + presentation.setText("Stop Focus Tracing"); + } else { + presentation.setText("Start Focus Tracing"); + } + presentation.setEnabled(e.getData(PlatformDataKeys.PROJECT) != null); + } +} diff --git a/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.form b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.form new file mode 100644 index 000000000000..9dc1d1074339 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.form @@ -0,0 +1,54 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java new file mode 100644 index 000000000000..5699b2a290cf --- /dev/null +++ b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java @@ -0,0 +1,105 @@ +/* + * Copyright 2000-2011 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.internal.focus; + +import com.intellij.openapi.ide.CopyPasteManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.wm.impl.FocusRequestInfo; +import com.intellij.ui.table.JBTable; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumnModel; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public class FocusTracesDialog extends DialogWrapper { + private JTextPane myStacktrace; + private JBTable myRequestsTable; + private JPanel myRootPanel; + private final List myRequests; + private static final String[] COLUMNS = {"Time", "Forced", "Component"}; + + public FocusTracesDialog(Project project, ArrayList requests) { + super(project); + myRequests = requests; + setTitle("Focus Traces"); + init(); + final String[][] data = new String[requests.size()][]; + for (int i = 0; i < data.length; i++) { + final FocusRequestInfo r = requests.get(i); + data[i] = new String[]{r.getDate(), String.valueOf(r.isForced()), r.getComponent()}; + } + myRequestsTable.setModel(new DefaultTableModel(data, COLUMNS)); + final ListSelectionListener selectionListener = new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + final int index = myRequestsTable.getSelectedRow(); + if (-1 < index && index < myRequests.size()) { + myStacktrace.setText(myRequests.get(index).getStackTrace()); + } + else { + myStacktrace.setText(""); + } + } + }; + myRequestsTable.getSelectionModel().addListSelectionListener(selectionListener); + final TableColumnModel columnModel = myRequestsTable.getColumnModel(); + columnModel.getColumn(0).setMaxWidth(120); + columnModel.getColumn(1).setMaxWidth(60); + columnModel.getSelectionModel().addListSelectionListener(selectionListener); + columnModel.setColumnSelectionAllowed(false); + myRequestsTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myRequestsTable.changeSelection(0, 0, false, true); + } + + @Override + protected String getDimensionServiceKey() { + return "ide.internal.focus.trace.dialog"; + } + + @Override + protected JComponent createCenterPanel() { + return myRootPanel; + } + + @Override + public JComponent getPreferredFocusedComponent() { + return myRequestsTable; + } + + @Override + protected Action[] createActions() { + return new Action[] {getOKAction(), getCopyStackTraceAction()}; + } + + private Action getCopyStackTraceAction() { + return new AbstractAction("&Copy stacktrace") { + @Override + public void actionPerformed(ActionEvent e) { + CopyPasteManager.getInstance().setContents(new StringSelection(myStacktrace.getText())); + } + }; + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index c685df5286fc..8ea3b8bdbf78 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -16,12 +16,14 @@ package com.intellij.openapi.wm.impl; import com.intellij.ide.IdeEventQueue; +import com.intellij.internal.focus.FocusTracesAction; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationAdapter; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.EdtRunnable; @@ -60,6 +62,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { private FocusCommand myFocusCommandOnAppActivation; private ActionCallback myCallbackOnActivation; + private final boolean isInternalMode = ApplicationManagerEx.getApplicationEx().isInternal(); + private List myRequests = new ArrayList(); private final IdeEventQueue myQueue; private final KeyProcessorConext myKeyProcessorContext = new KeyProcessorConext(); @@ -156,6 +160,9 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { @NotNull public ActionCallback requestFocus(@NotNull final FocusCommand command, final boolean forced) { + if (isInternalMode) { + recordCommand(command, new Throwable(), forced); + } final ActionCallback result = new ActionCallback(); if (!forced) { @@ -183,6 +190,16 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { return result; } + public List getRequests() { + return myRequests; + } + + private void recordCommand(FocusCommand command, Throwable trace, boolean forced) { + if (FocusTracesAction.isActive()) { + myRequests.add(new FocusRequestInfo(command.getDominationComponent(), trace, forced)); + } + } + private void _requestFocus(final FocusCommand command, final boolean forced, final ActionCallback result) { if (checkForRejectOrByPass(command, forced, result)) return; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java new file mode 100644 index 000000000000..387b3ca4bd26 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.wm.impl; + +import com.intellij.util.ExceptionUtil; + +import java.awt.*; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author Konstantin Bulenkov + */ +public final class FocusRequestInfo { + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS"); + private final String when; + private final Throwable trace; + private final String component; + private final boolean forced; + + public FocusRequestInfo(Component component, Throwable trace, boolean forced) { + this.forced = forced; + this.component = component == null ? "null" : component.toString(); + this.trace = trace; + when = DATE_FORMAT.format(new Date()); + } + + public String getStackTrace() { + return ExceptionUtil.getThrowableText(trace); + } + + public String getComponent() { + return component; + } + + public boolean isForced() { + return forced; + } + + public String getDate() { + return when; + } +} diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index 0edd287cb336..f448f143b688 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -441,6 +441,10 @@ + + + + From a304cbf6f471d36dc20764ae617bc9cb619ccb6b Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 16 Feb 2011 21:24:25 +0300 Subject: [PATCH 12/90] git log null byte problem again %x00 Changed %x00 to %x04. made parseTimestamp catch NumberFormatException and log it, but return current Date() instead of failing. --- plugins/git4idea/src/git4idea/GitUtil.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java index 45b6bddfb3c1..54e17021f122 100644 --- a/plugins/git4idea/src/git4idea/GitUtil.java +++ b/plugins/git4idea/src/git4idea/GitUtil.java @@ -312,7 +312,14 @@ public class GitUtil { * @return timestamp as {@link Date} object */ public static Date parseTimestamp(String value) { - return new Date(Long.parseLong(value.trim()) * 1000); + final long parsed; + try { + parsed = Long.parseLong(value.trim()); + return new Date(parsed * 1000); + } catch (NumberFormatException e) { + LOG.error("Error parsing timestamp from " + value, e); + return new Date(); + } } /** @@ -743,7 +750,7 @@ public class GitUtil { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.LOG); h.setSilent(true); h.setNoSSH(true); - h.addParameters("--pretty=format:%x00%x01" + GitChangeUtils.COMMITTED_CHANGELIST_FORMAT, "--name-status"); + h.addParameters("--pretty=format:%x04%x01" + GitChangeUtils.COMMITTED_CHANGELIST_FORMAT, "--name-status"); parametersSpecifier.consume(h); String output = h.run(); @@ -753,7 +760,7 @@ public class GitUtil { boolean firstStep = true; while (s.hasMoreData()) { final String line = s.line(); - final boolean lineIsAStart = line.startsWith("\u0000\u0001"); + final boolean lineIsAStart = line.startsWith("\u0004\u0001"); if ((!firstStep) && lineIsAStart) { final StringScanner innerScanner = new StringScanner(sb.toString()); sb.setLength(0); From 55f2f5f61f562d055421d0614473a7b048146151 Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Wed, 16 Feb 2011 21:29:10 +0300 Subject: [PATCH 13/90] InjectedLanguageEditingTest.testHighlightSelectionInWholeEditor fixed. --- .../intellij/find/impl/FindManagerImpl.java | 6 ++++-- .../com/intellij/find/impl/LivePreview.java | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java index fde74bf81261..dc3eef7c724c 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java @@ -658,8 +658,10 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo private boolean tryToFindNextUsageViaEditorSearchComponent(Editor editor, boolean forwardOrBackward) { if (editor.getHeaderComponent() instanceof EditorSearchComponent) { EditorSearchComponent searchComponent = (EditorSearchComponent)editor.getHeaderComponent(); - searchComponent.moveCursor(forwardOrBackward); - return true; + if (searchComponent.hasMatches()) { + searchComponent.moveCursor(forwardOrBackward); + return true; + } } return false; } diff --git a/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java b/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java index 6c1f8a346b1d..5882ea6c05a9 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java +++ b/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java @@ -224,12 +224,17 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele myShouldStop = false; myLivePreviewAlarm.cancelAllRequests(); if (updateEditorReference() != null) { - myLivePreviewAlarm.addRequest(new Runnable() { + Runnable request = new Runnable() { @Override public void run() { updateInBackground(); } - }, myUserActivityDelay); + }; + if (ApplicationManager.getApplication().isUnitTestMode()) { + request.run(); + } else { + myLivePreviewAlarm.addRequest(request, myUserActivityDelay); + } } } @@ -270,7 +275,7 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele } }); if (mySearchResults != null) { - ApplicationManager.getApplication().invokeLater(new Runnable() { + Runnable highlightUsagesBlock = new Runnable() { @Override public void run() { doInternalCleanUp(); @@ -280,7 +285,12 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele myContinuation = null; } } - }); + }; + if (ApplicationManager.getApplication().isUnitTestMode()) { + highlightUsagesBlock.run(); + } else { + ApplicationManager.getApplication().invokeLater(highlightUsagesBlock); + } } } From e6c5b35ab3e4ff414a59af9922379dd4d59d8355 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 16 Feb 2011 21:35:28 +0300 Subject: [PATCH 14/90] IDEA-65616 show dialog in AWT thread --- .../com/intellij/execution/util/ExecutableValidator.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/execution/util/ExecutableValidator.java b/platform/platform-api/src/com/intellij/execution/util/ExecutableValidator.java index 0bf4efa93977..212ca37c6cae 100644 --- a/platform/platform-api/src/com/intellij/execution/util/ExecutableValidator.java +++ b/platform/platform-api/src/com/intellij/execution/util/ExecutableValidator.java @@ -122,8 +122,13 @@ public abstract class ExecutableValidator { } public boolean showDialog() { - ExecutableDialog dialog = new ExecutableDialog(myProject, this); - dialog.show(); + final ExecutableDialog dialog = new ExecutableDialog(myProject, this); + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + dialog.show(); + } + }); if (dialog.isOK()) { saveCurrentExecutable(dialog.getPath()); return true; From 5bd4c9112bbcb3362b7b62e9b5c323d5aba6cfd2 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 19:28:38 +0100 Subject: [PATCH 15/90] IDEA-65503 groovy joint compiler can't handle Groovy script files with only numeric names --- .../groovy/compiler/generator/GroovycStubGenerator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java index d5aab3694a53..5c27421ab3db 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovycStubGenerator.java @@ -44,6 +44,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.compiler.GroovyCompilerBase; import org.jetbrains.plugins.groovy.compiler.GroovyCompilerConfiguration; +import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil; import java.io.File; import java.io.IOException; @@ -77,7 +78,7 @@ public class GroovycStubGenerator extends GroovyCompilerBase { } if (!excluded.isExcluded(virtualFile)) { - if (fileType == GroovyFileType.GROOVY_FILE_TYPE && !"package-info".equals(virtualFile.getNameWithoutExtension())) { + if (fileType == GroovyFileType.GROOVY_FILE_TYPE && GroovyNamesUtil.isIdentifier(virtualFile.getNameWithoutExtension())) { total.add(virtualFile); } } From af59eeb605c68e5e18012eafdf823dfefc1cc3c4 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 20:06:51 +0100 Subject: [PATCH 16/90] IDEA-65500 Update to 10.0.2 breaks Java-Groovy integration --- .../generator/GroovyToJavaGenerator.java | 33 +++++--------- .../groovy/lang/psi/util/GrClassImplUtil.java | 11 ++--- .../groovy/compiler/GeneratorTest.java | 12 +++-- .../stubGenerator/delegationGenerics.test | 44 +++++++++++++++++++ 4 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java index 9177e6552db6..2e091407d312 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/generator/GroovyToJavaGenerator.java @@ -63,6 +63,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDef import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; +import org.jetbrains.plugins.groovy.lang.psi.util.GrClassImplUtil; import java.io.File; import java.io.IOException; @@ -355,7 +356,7 @@ public class GroovyToJavaGenerator { final PsiMethod method = ((MethodSignatureBackedByPsiMethod)signature).getMethod(); final PsiClass baseClass = method.getContainingClass(); if (isAbstractInJava(method) && baseClass != null && typeDefinition.isInheritor(baseClass, true)) { - methods.add(mirrorMethod(typeDefinition, method, baseClass, JAVA_MODIFIERS)); + methods.add(mirrorMethod(typeDefinition, method, baseClass, PsiSubstitutor.EMPTY, JAVA_MODIFIERS)); } } } @@ -368,20 +369,22 @@ public class GroovyToJavaGenerator { methods.add(factory.createMethodFromText("public void setProperty(String propertyName, Object newValue) {}", null)); } - for (PsiClass resolve : collectDelegateTypes(typeDefinition)) { - for (PsiMethod method : resolve.getAllMethods()) { - if (method.hasModifierProperty(PsiModifier.ABSTRACT) && !method.hasModifierProperty(PsiModifier.STATIC)) { - methods.add(mirrorMethod(typeDefinition, method, typeDefinition, PsiModifier.PUBLIC, PsiModifier.PROTECTED, PsiModifier.PRIVATE)); - } + if (typeDefinition instanceof GrTypeDefinition) { + for (PsiMethod delegatedMethod : GrClassImplUtil.getDelegatedMethods((GrTypeDefinition)typeDefinition)) { + methods.add(delegatedMethod); } } return methods; } - private static LightMethodBuilder mirrorMethod(PsiClass typeDefinition, PsiMethod method, PsiClass baseClass, String... modifierFilter) { + private static LightMethodBuilder mirrorMethod(PsiClass typeDefinition, + PsiMethod method, + PsiClass baseClass, + PsiSubstitutor substitutor, + String... modifierFilter) { final LightMethodBuilder builder = new LightMethodBuilder(method.getManager(), method.getName()); - final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(baseClass, typeDefinition, PsiSubstitutor.EMPTY); + substitutor = substitutor.putAll(TypeConversionUtil.getSuperClassSubstitutor(baseClass, typeDefinition, PsiSubstitutor.EMPTY)); for (PsiParameter parameter : method.getParameterList().getParameters()) { builder.addParameter(StringUtil.notNullize(parameter.getName()), substitutor.substitute(parameter.getType())); } @@ -394,20 +397,6 @@ public class GroovyToJavaGenerator { return builder; } - private static List collectDelegateTypes(PsiClass typeDefinition) { - final ArrayList result = new ArrayList(); - for (PsiField field : typeDefinition.getFields()) { - final PsiModifierList modifierList = field.getModifierList(); - if (modifierList != null && modifierList.findAnnotation("groovy.lang.Delegate") != null) { - final PsiType type = field.getType(); - if (type instanceof PsiClassType) { - ContainerUtil.addIfNotNull(result, ((PsiClassType)type).resolve()); - } - } - } - return result; - } - private static boolean isAbstractInJava(PsiMethod method) { if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java index 8f771b38ddf1..74595e8790db 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GrClassImplUtil.java @@ -513,7 +513,8 @@ public class GrClassImplUtil { final PsiType type = field.getDeclaredType(); if (!(type instanceof PsiClassType)) continue; - final PsiClass psiClass = ((PsiClassType)type).resolve(); + final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics(); + final PsiClass psiClass = resolveResult.getElement(); if (psiClass == null) continue; final boolean deprecated = shouldDelegateDeprecated(delegate); @@ -527,7 +528,7 @@ public class GrClassImplUtil { for (PsiMethod method : methods) { if (method.isConstructor()) continue; if (!deprecated && getAnnotation(method, "java.lang.Deprecated") != null) continue; - result.add(generateDelegateMethod(method, clazz)); + result.add(generateDelegateMethod(method, clazz, resolveResult.getSubstitutor())); } } return new Result>(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); @@ -538,15 +539,15 @@ public class GrClassImplUtil { return cachedValue.getValue(); } - private static PsiMethod generateDelegateMethod(PsiMethod method, PsiClass clazz) { + private static PsiMethod generateDelegateMethod(PsiMethod method, PsiClass clazz, PsiSubstitutor substitutor) { final LightMethodBuilder builder = new LightMethodBuilder(clazz.getManager(), GroovyFileType.GROOVY_LANGUAGE, method.getName()); builder.setContainingClass(clazz); - builder.setReturnType(method.getReturnType()); + builder.setReturnType(substitutor.substitute(method.getReturnType())); builder.setNavigationElement(method); builder.addModifier(PsiModifier.PUBLIC); final PsiParameter[] originalParameters = method.getParameterList().getParameters(); for (PsiParameter originalParameter : originalParameters) { - builder.addParameter(originalParameter); + builder.addParameter(originalParameter.getName(), substitutor.substitute(originalParameter.getType())); } builder.setBaseIcon(GroovyIcons.METHOD); return builder; diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java index d87d6de0de25..e070a7404cab 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GeneratorTest.java @@ -58,11 +58,10 @@ public class GeneratorTest extends LightGroovyTestCase { public void testThrowsCheckedException() throws Throwable { doTest(); } public void testSubclassProperty() throws Throwable { doTest(); } - public void testRawReturnTypeInImplementation() throws Throwable { - myFixture.addClass("package java.util.concurrent;" + - "public interface Callable {" + - " V call() throws java.lang.Exception;" + - "}"); + public void testRawReturnTypeInImplementation() throws Throwable { doTest(); } + + public void testDelegationGenerics() throws Throwable { + myFixture.addClass("package groovy.lang; public @interface Delegate { boolean interfaces() default true; }"); doTest(); } @@ -75,8 +74,7 @@ public class GeneratorTest extends LightGroovyTestCase { } public void testInaccessiblePropertyType() throws Throwable { - myFixture.addClass("package foo;" + - "class Hidden {}"); + myFixture.addClass("package foo; class Hidden {}"); doTest(); } diff --git a/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test b/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test new file mode 100644 index 000000000000..e00eff8e74ef --- /dev/null +++ b/plugins/groovy/testdata/groovy/stubGenerator/delegationGenerics.test @@ -0,0 +1,44 @@ +interface Foo { + V get(K k); +} + +class ConfigNode { + @Delegate final Foo delegate +} +----- +public interface Foo { + public V get(K k) ; +} +--- +public class ConfigNode extends groovy.lang.GroovyObjectSupport implements Foo, groovy.lang.GroovyObject { + public final Foo getDelegate() { + return null; + } + + public java.lang.Object get(java.lang.String k) { + return null; + } + + public groovy.lang.MetaClass getMetaClass() { + return null; + } + + public void setMetaClass(groovy.lang.MetaClass mc) { + return ; + } + + public java.lang.Object invokeMethod(java.lang.String name, java.lang.Object args) { + return null; + } + + public java.lang.Object getProperty(java.lang.String propertyName) { + return null; + } + + public void setProperty(java.lang.String propertyName, java.lang.Object newValue) { + return ; + } + + private final Foo delegate = null; +} +--- \ No newline at end of file From 9208f80798f413e6ab4115b360e448215778f86f Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Wed, 16 Feb 2011 21:33:03 +0300 Subject: [PATCH 17/90] fix shortcut registration --- .../src/com/intellij/execution/console/LanguageConsoleImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index e12c24eb94cc..af25959298ce 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -497,7 +497,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { if (file != myFile.getVirtualFile()) return; if (myConsoleEditor != null) { queueUiUpdate(false); - for (FileEditor fileEditor : source.getAllEditors()) { + for (FileEditor fileEditor : source.getAllEditors(file)) { if (!(fileEditor instanceof TextEditor)) continue; final Editor editor = ((TextEditor)fileEditor).getEditor(); registerActionShortcuts(editor.getComponent()); From 880ea436e5111a44bbed757aff474dd000461f4c Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 20:35:16 +0100 Subject: [PATCH 18/90] hide autopopup hint on variants like null, return, true, false --- .../completion/CompletionProgressIndicator.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 5fcd8bf67dc6..5d094f15c129 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -470,14 +470,19 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement if (isAutopopupCompletion() && !myLookup.isSelectionTouched() && !myLookup.isCalculating()) { myLookup.refreshUi(); final List items = myLookup.getItems(); - if (!items.isEmpty() && showHintAutopopup()) { - return false; - } for (LookupElement item : items) { if (!(item.getPrefixMatcher().getPrefix() + myLookup.getAdditionalPrefix()).equals(item.getLookupString())) { return false; } + + if (showHintAutopopup()) { + final LookupElementPresentation presentation = new LookupElementPresentation(); + item.renderElement(presentation); + if (StringUtil.isNotEmpty(presentation.getTailText())) { + return false; + } + } } myLookup.hideLookup(false); From 63cdf7dbafcaba9588a37c76a35d00dba155acca Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 20:40:09 +0100 Subject: [PATCH 19/90] hint autopopup can be shown even when typing inside identifier --- .../completion/CompletionProgressIndicator.java | 2 +- .../editorActions/CompletionAutoPopupHandler.java | 10 ++++++---- .../intellij/codeInsight/lookup/impl/LookupImpl.java | 4 ++++ .../lookup/impl/actions/ChooseItemReplaceAction.java | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 5d094f15c129..9336b40c3c3b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -348,7 +348,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement updateFocus(); } - private static boolean showHintAutopopup() { + public static boolean showHintAutopopup() { return "true".equals(Registry.stringValue("hint.autopopup")); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java index 1cf7cfa90d96..ad76f7e76f2f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CompletionAutoPopupHandler.java @@ -91,10 +91,12 @@ public class CompletionAutoPopupHandler extends TypedHandlerDelegate { } - final CharSequence text = editor.getDocument().getCharsSequence(); - final int offset = editor.getSelectionModel().hasSelection() ? editor.getSelectionModel().getSelectionEnd() : editor.getCaretModel().getOffset(); - if (text.length() > offset && Character.isUnicodeIdentifierPart(text.charAt(offset))) { - return Result.CONTINUE; + if (!CompletionProgressIndicator.showHintAutopopup()) { + final CharSequence text = editor.getDocument().getCharsSequence(); + final int offset = editor.getSelectionModel().hasSelection() ? editor.getSelectionModel().getSelectionEnd() : editor.getCaretModel().getOffset(); + if (text.length() > offset && Character.isUnicodeIdentifierPart(text.charAt(offset))) { + return Result.CONTINUE; + } } final boolean isMainEditor = FileEditorManager.getInstance(project).getSelectedTextEditor() == editor; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 5d2853265639..8a4982f74396 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -484,6 +484,10 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { myHintMode = hintMode; } + public boolean isHintMode() { + return myHintMode; + } + private static LookupElementPresentation renderItemApproximately(LookupElement item) { final LookupElementPresentation p = new LookupElementPresentation(); item.renderElement(p); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java index d1d4690cce1a..54c84064dc0a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/actions/ChooseItemReplaceAction.java @@ -44,7 +44,7 @@ public class ChooseItemReplaceAction extends EditorAction { FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_REPLACE); LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor); assert lookup != null; - lookup.finishLookup(Lookup.REPLACE_SELECT_CHAR); + lookup.finishLookup(lookup.isHintMode() ? Lookup.NORMAL_SELECT_CHAR : Lookup.REPLACE_SELECT_CHAR); } @Override From 0e0e777c2dfcb0256fd87629f4a809c6aa765e18 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 16 Feb 2011 20:41:04 +0100 Subject: [PATCH 20/90] home/end should work while hint autopopup is active --- .../src/com/intellij/codeInsight/lookup/impl/EndHandler.java | 2 +- .../src/com/intellij/codeInsight/lookup/impl/HomeHandler.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java index 419d88935ad3..8c443306c5f5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java @@ -31,7 +31,7 @@ public class EndHandler extends EditorActionHandler { public void execute(Editor editor, DataContext dataContext){ LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor); - if (lookup == null || !lookup.isFocused()) { + if (lookup == null || !lookup.isFocused() || lookup.isHintMode()) { myOriginalHandler.execute(editor, dataContext); return; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java index a8699b9454c8..badc854bea87 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java @@ -31,7 +31,7 @@ public class HomeHandler extends EditorActionHandler { public void execute(Editor editor, DataContext dataContext){ LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor); - if (lookup == null || !lookup.isFocused()) { + if (lookup == null || !lookup.isFocused() || lookup.isHintMode()) { myOriginalHandler.execute(editor, dataContext); return; } From d5357576adccb2ce06336b5a1c535f953968f22b Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Wed, 16 Feb 2011 22:52:33 +0300 Subject: [PATCH 21/90] [RUBY-7850] Show 32-bit optimization hint only once --- .../src/componentSets/PlatformComponents.xml | 3 +++ .../src/componentSets/PlatformLangComponents.xml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/platform/platform-resources/src/componentSets/PlatformComponents.xml b/platform/platform-resources/src/componentSets/PlatformComponents.xml index 8913d4536489..51b1d2960dc1 100644 --- a/platform/platform-resources/src/componentSets/PlatformComponents.xml +++ b/platform/platform-resources/src/componentSets/PlatformComponents.xml @@ -8,6 +8,9 @@ com.intellij.openapi.components.impl.ServiceManagerImpl + + com.intellij.openapi.util.registry.RegistryState + com.intellij.openapi.project.impl.ProjectStoreClassProvider com.intellij.openapi.components.impl.stores.PlatformProjectStoreClassProvider diff --git a/platform/platform-resources/src/componentSets/PlatformLangComponents.xml b/platform/platform-resources/src/componentSets/PlatformLangComponents.xml index 8b66914a36fd..31eee9d568f8 100644 --- a/platform/platform-resources/src/componentSets/PlatformLangComponents.xml +++ b/platform/platform-resources/src/componentSets/PlatformLangComponents.xml @@ -8,6 +8,9 @@ com.intellij.openapi.components.impl.ServiceManagerImpl + + com.intellij.openapi.util.registry.RegistryState + com.intellij.openapi.project.impl.ProjectStoreClassProvider com.intellij.openapi.components.impl.stores.PlatformLangProjectStoreClassProvider From a5cfe765f21bc2f8553d203a672c7af32ecd2722 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Wed, 16 Feb 2011 23:08:20 +0300 Subject: [PATCH 22/90] fixed [PY-2902] Django Test: NPE at com.intellij.ide.util.treeView.AbstractTreeBuilder.select --- .../testframework/sm/runner/ui/SMTestRunnerResultsForm.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java index e5ce8f978436..7726ada0f3e8 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java @@ -465,6 +465,9 @@ public class SMTestRunnerResultsForm extends TestResultsPanel implements TestFra SMRunnerUtil.runInEventDispatchThread(new Runnable() { public void run() { + if (myTreeBuilder.isDisposed()) { + return; + } myTreeBuilder.select(testProxy, null); } }, ModalityState.NON_MODAL); From cfff57399de0b807cdcb01d1eba353f3ae58cdfa Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Mon, 24 Jan 2011 18:15:30 +0300 Subject: [PATCH 23/90] IDEA-64453 GitHub task server configuration changes can't be saved --- .../src/com/intellij/tasks/config/BaseRepositoryEditor.form | 2 +- .../src/com/intellij/tasks/config/BaseRepositoryEditor.java | 1 + .../src/com/intellij/tasks/github/GitHubRepositoryEditor.java | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.form b/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.form index 25bb74aca16c..c15452cabdb4 100644 --- a/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.form +++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.form @@ -21,7 +21,7 @@ - + diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.java index 81f5e99c0fb4..ff9ee32403ea 100644 --- a/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.java +++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/config/BaseRepositoryEditor.java @@ -34,6 +34,7 @@ import java.awt.event.ActionListener; */ public class BaseRepositoryEditor extends TaskRepositoryEditor { + protected JLabel myUrlLabel; protected JTextField myURLText; protected JTextField myUserNameText; protected JLabel myUsernameLabel; diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/github/GitHubRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/github/GitHubRepositoryEditor.java index 0782a5b65f71..ea02946fd69d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/github/GitHubRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/github/GitHubRepositoryEditor.java @@ -20,6 +20,9 @@ public class GitHubRepositoryEditor extends BaseRepositoryEditor changeListener) { super(project, repository, changeListener); + myUrlLabel.setVisible(false); + myURLText.setVisible(false); + // project author, by default same as username myRepoAuthor = new JTextField(); myRepoAuthor.setText(repository.getRepoAuthor()); From bb599c7f1430ffd9f904de7cf4a5a54bd891ac4e Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 17 Feb 2011 10:46:50 +0300 Subject: [PATCH 24/90] draw border on focused components --- .../internal/focus/FocusTracesDialog.java | 56 ++++++++++++++++++- .../openapi/wm/impl/FocusRequestInfo.java | 14 ++--- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java index 5699b2a290cf..b44576067612 100644 --- a/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java +++ b/platform/platform-impl/src/com/intellij/internal/focus/FocusTracesDialog.java @@ -20,12 +20,14 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.wm.impl.FocusRequestInfo; import com.intellij.ui.table.JBTable; +import com.intellij.util.ui.UIUtil; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumnModel; +import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.util.ArrayList; @@ -49,7 +51,7 @@ public class FocusTracesDialog extends DialogWrapper { final String[][] data = new String[requests.size()][]; for (int i = 0; i < data.length; i++) { final FocusRequestInfo r = requests.get(i); - data[i] = new String[]{r.getDate(), String.valueOf(r.isForced()), r.getComponent()}; + data[i] = new String[]{r.getDate(), String.valueOf(r.isForced()), String.valueOf(r.getComponent())}; } myRequestsTable.setModel(new DefaultTableModel(data, COLUMNS)); final ListSelectionListener selectionListener = new ListSelectionListener() { @@ -102,4 +104,56 @@ public class FocusTracesDialog extends DialogWrapper { } }; } + + @Override + public void show() { + final BorderDrawer drawer = new BorderDrawer(); + drawer.start(); + super.show(); + drawer.setDone(); + } + + class BorderDrawer extends Thread { + Component prev = null; + private volatile boolean running = true; + BorderDrawer() { + super("Focus Border Drawer"); + } + + @Override + public void run() { + try { + while (running) { + sleep(100); + paintBorder(); + } + if (prev != null) { + prev.repaint(); + } + } + catch (InterruptedException e) {// + } + } + + private void paintBorder() { + final int row = FocusTracesDialog.this.myRequestsTable.getSelectedRow(); + if (row != -1) { + final FocusRequestInfo info = FocusTracesDialog.this.myRequests.get(row); + if (prev != null && prev != info.getComponent()) { + prev.repaint(); + } + prev = info.getComponent(); + if (prev != null && prev.isDisplayable()) { + final Graphics g = prev.getGraphics(); + g.setColor(Color.RED); + final Dimension sz = prev.getSize(); + UIUtil.drawDottedRectangle(g, 1, 1, sz.width - 2, sz.height - 2); + } + } + } + + public void setDone() { + running = false; + } + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java index 387b3ca4bd26..a1dccc18630a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusRequestInfo.java @@ -28,24 +28,20 @@ public final class FocusRequestInfo { private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm:ss.SSS"); private final String when; private final Throwable trace; - private final String component; private final boolean forced; + private Component component; - public FocusRequestInfo(Component component, Throwable trace, boolean forced) { + public FocusRequestInfo(Component c, Throwable trace, boolean forced) { this.forced = forced; - this.component = component == null ? "null" : component.toString(); this.trace = trace; when = DATE_FORMAT.format(new Date()); + component = c; } public String getStackTrace() { return ExceptionUtil.getThrowableText(trace); } - public String getComponent() { - return component; - } - public boolean isForced() { return forced; } @@ -53,4 +49,8 @@ public final class FocusRequestInfo { public String getDate() { return when; } + + public Component getComponent() { + return component; + } } From b04fb3b9f5cefb167a97b7ca1b83a6094a691938 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 16 Feb 2011 21:42:34 +0300 Subject: [PATCH 25/90] IDEA-64895 GitPushActiveBranches view button View button (to view commit details) produces a request to git, thus it is made in Task.Backgroundable. It was run in the same BackgroundTaskQueue as fetching, and thus was block by the fetching process. It is not necessary to use the same queue since the view task executes read operations only. --- .../git4idea/actions/GitShowAllSubmittedFilesAction.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/git4idea/src/git4idea/actions/GitShowAllSubmittedFilesAction.java b/plugins/git4idea/src/git4idea/actions/GitShowAllSubmittedFilesAction.java index dfbd405b8bb5..9eb2533feda9 100644 --- a/plugins/git4idea/src/git4idea/actions/GitShowAllSubmittedFilesAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitShowAllSubmittedFilesAction.java @@ -32,7 +32,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ui.UIUtil; import git4idea.GitFileRevision; import git4idea.GitUtil; -import git4idea.GitVcs; import git4idea.changes.GitChangeUtils; import git4idea.i18n.GitBundle; import git4idea.ui.GitUIUtil; @@ -98,8 +97,7 @@ public class GitShowAllSubmittedFilesAction extends AnAction implements DumbAwar * @param file file affected by the revision */ public static void showSubmittedFiles(final Project project, final String revision, final VirtualFile file) { - GitVcs.getInstance(project).runInBackground(new Task.Backgroundable(project, GitBundle.message("changes.retrieving", revision)) { - + new Task.Backgroundable(project, GitBundle.message("changes.retrieving", revision)) { public void run(@NotNull ProgressIndicator indicator) { indicator.setIndeterminate(true); try { @@ -122,7 +120,7 @@ public class GitShowAllSubmittedFilesAction extends AnAction implements DumbAwar }); } } - }); + }.queue(); } From ba34a57b57371a7ffdf9be9f47b150daefa81203 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Tue, 15 Feb 2011 15:51:17 +0300 Subject: [PATCH 26/90] IDEA-57891 Reformat file: run under modal progress 1. Formatter processing is rewritten in order to be able to process sequentially; 2. Progress window doesn't use shared thread for showing dialog with progress bar anymore (standard swing Timer is used instead); --- .../src/com/intellij/util/SequentialTask.java | 43 ++ .../ReformatAndOptimizeImportsProcessor.java | 4 +- .../actions/ReformatCodeProcessor.java | 2 +- .../intellij/formatting/FormatProcessor.java | 399 ++++++++++++++---- .../com/intellij/formatting/FormatterEx.java | 5 +- .../intellij/formatting/FormatterImpl.java | 264 +++++++++--- .../FormattingProgressIndicator.java | 121 ++++++ .../FormattingProgressIndicatorImpl.java | 285 +++++++++++++ .../formatting/FormattingStateId.java | 92 ++++ .../formatting/InitialInfoBuilder.java | 243 ++++++++--- .../source/codeStyle/CodeFormatterFacade.java | 4 +- .../openapi/progress/util/ProgressWindow.java | 93 ++-- .../src/messages/CodeInsightBundle.properties | 7 +- 13 files changed, 1309 insertions(+), 253 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/util/SequentialTask.java create mode 100644 platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicator.java create mode 100644 platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java create mode 100644 platform/lang-impl/src/com/intellij/formatting/FormattingStateId.java diff --git a/platform/lang-api/src/com/intellij/util/SequentialTask.java b/platform/lang-api/src/com/intellij/util/SequentialTask.java new file mode 100644 index 000000000000..8ba9ff218cb5 --- /dev/null +++ b/platform/lang-api/src/com/intellij/util/SequentialTask.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util; + +/** + * Defines general contract for processing that may be executed by parts, i.e. it remembers the state after every iteration + * and allows to resume the processing any time. + * + * @author Denis Zhdanov + * @since 2/14/11 9:15 AM + */ +public interface SequentialTask { + + /** + * Callback method that is assumed to be called before the processing. + */ + void prepare(); + + /** + * @return true if the processing is complete; false otherwise + */ + boolean isDone(); + + /** + * Asks current task to perform one more processing iteration. + * + * @return true if the processing is done; false otherwise + */ + boolean iteration(); +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java index 3e1b737f88a5..085cb6e2aeb4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatAndOptimizeImportsProcessor.java @@ -28,8 +28,8 @@ import org.jetbrains.annotations.NotNull; * @author max */ public class ReformatAndOptimizeImportsProcessor extends AbstractLayoutCodeProcessor { - private static final String PROGRESS_TEXT = CodeInsightBundle.message("progress.text.reformatting.code"); - private static final String COMMAND_NAME = CodeInsightBundle.message("process.reformat.code"); + private static final String PROGRESS_TEXT = CodeInsightBundle.message("reformat.progress.common.text"); + private static final String COMMAND_NAME = CodeInsightBundle.message("progress.reformat.code.prepare"); private final OptimizeImportsProcessor myOptimizeImportsProcessor; private final ReformatCodeProcessor myReformatCodeProcessor; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java index e3d357609dba..32c786dad77a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java @@ -31,7 +31,7 @@ public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.actions.ReformatCodeProcessor"); private final TextRange myRange; - private static final String PROGRESS_TEXT = CodeInsightBundle.message("progress.text.reformatting.code"); + private static final String PROGRESS_TEXT = CodeInsightBundle.message("reformat.progress.common.text"); private static final String COMMAND_NAME = CodeInsightBundle.message("process.reformat.code"); public ReformatCodeProcessor(Project project) { diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java index 72421e87eefb..02e449313a74 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java @@ -99,16 +99,24 @@ class FormatProcessor { }); private final HashSet myAlignAgain = new HashSet(); + @NotNull + private final FormattingProgressIndicator myProgressIndicator; + private WhiteSpace myLastWhiteSpace; private boolean myDisposed; private CodeStyleSettings.IndentOptions myJavaIndentOptions; + + @NotNull + private State myCurrentState; public FormatProcessor(final FormattingDocumentModel docModel, Block rootBlock, CodeStyleSettings settings, CodeStyleSettings.IndentOptions indentOptions, - @Nullable FormatTextRanges affectedRanges) { - this(docModel, rootBlock, settings, indentOptions, affectedRanges, -1); + @Nullable FormatTextRanges affectedRanges, + @NotNull FormattingProgressIndicator progressIndicator) + { + this(docModel, rootBlock, settings, indentOptions, affectedRanges, -1, progressIndicator); } public FormatProcessor(final FormattingDocumentModel docModel, @@ -116,22 +124,13 @@ class FormatProcessor { CodeStyleSettings settings, CodeStyleSettings.IndentOptions indentOptions, @Nullable FormatTextRanges affectedRanges, - int interestingOffset) { + int interestingOffset, + @NotNull FormattingProgressIndicator progressIndicator) + { + myProgressIndicator = progressIndicator; myIndentOption = indentOptions; mySettings = settings; - final InitialInfoBuilder builder = InitialInfoBuilder.buildBlocks(rootBlock, - docModel, - affectedRanges, - indentOptions, - interestingOffset); - myInfos = builder.getBlockToInfoMap(); - myRootBlockWrapper = builder.getRootBlockWrapper(); - myFirstTokenBlock = builder.getFirstTokenBlock(); - myLastTokenBlock = builder.getLastTokenBlock(); - myCurrentBlock = myFirstTokenBlock; - myTextRangeToWrapper = buildTextRangeToInfoMap(myFirstTokenBlock); - myLastWhiteSpace = new WhiteSpace(getLastBlock().getEndOffset(), false); - myLastWhiteSpace.append(docModel.getTextLength(), docModel, indentOptions); + myCurrentState = new WrapBlocksState(rootBlock, docModel, affectedRanges, interestingOffset); } private LeafBlockWrapper getLastBlock() { @@ -153,20 +152,72 @@ class FormatProcessor { } public void format(FormattingModel model) { - formatWithoutRealModifications(); - performModifications(model); + format(model, false); + } + + /** + * Asks current processor to perform formatting. + *

+ * There are two processing approaches at the moment: + *

+   * 
    + *
  • perform formatting during the current method call;
  • + *
  • + * split the whole formatting process to the set of fine-grained tasks and execute them sequentially during + * subsequent {@link #iteration()} calls; + *
  • + *
+ *
+ *

+ * Here is rationale for the second approach - formatting may introduce changes to the underlying document and IntelliJ IDEA + * is designed in a way that write access is allowed from EDT only. That means that every time we execute particular action + * from EDT we have no chance of performing any other actions from EDT simultaneously (e.g. we may want to show progress bar + * that reflects current formatting state but the progress bar can' bet updated if formatting is performed during a single long + * method call). So, we can interleave formatting iterations with GUI state updates. + * + * @param model target formatting model + * @param sequentially flag that indicates what kind of processing should be used + */ + public void format(FormattingModel model, boolean sequentially) { + if (sequentially) { + AdjustWhiteSpacesState adjustState = new AdjustWhiteSpacesState(); + adjustState.setNext(new ApplyChangesState(model)); + myCurrentState.setNext(adjustState); + } + else { + formatWithoutRealModifications(sequentially); + performModifications(model, sequentially); + } + } + + /** + * Asks current processor to perform processing iteration + * + * @return true if the processing is finished; false otherwise + * @see #format(FormattingModel, boolean) + */ + public boolean iteration() { + if (myCurrentState.isDone()) { + return true; + } + myCurrentState.iteration(); + return myCurrentState.isDone(); } - @SuppressWarnings({"WhileLoopSpinsOnField"}) public void formatWithoutRealModifications() { - while (true) { - myAlignAgain.clear(); - myCurrentBlock = myFirstTokenBlock; - while (myCurrentBlock != null) { - processToken(); - } - if (myAlignAgain.isEmpty()) return; - reset(); + formatWithoutRealModifications(false); + } + + @SuppressWarnings({"WhileLoopSpinsOnField"}) + public void formatWithoutRealModifications(boolean sequentially) { + myCurrentState.setNext(new AdjustWhiteSpacesState()); + + if (!sequentially) { + return; + } + + while (myCurrentState.getStateId() == FormattingStateId.PROCESSING_BLOCKS && !myCurrentState.isDone()) { + myCurrentState.iteration(); } } @@ -181,71 +232,26 @@ class FormatProcessor { } public void performModifications(FormattingModel model) { + performModifications(model, false); + } + + public void performModifications(FormattingModel model, boolean sequentially) { assert !myDisposed; - final List blocksToModify = collectBlocksToModify(); - - // call doModifications static method to ensure no access to state - // thus we may clear formatting state - reset(); - - myInfos = null; - myRootBlockWrapper = null; - myTextRangeToWrapper = null; - myPreviousDependencies = null; - myLastWhiteSpace = null; - myFirstTokenBlock = null; - myLastTokenBlock = null; - myDisposed = true; - - //for GeneralCodeFormatterTest - if (myJavaIndentOptions == null) { - myJavaIndentOptions = mySettings.getIndentOptions(StdFileTypes.JAVA); + myCurrentState.setNext(new ApplyChangesState(model)); + + if (!sequentially) { + return; } - doModify(blocksToModify, model, myIndentOption, myJavaIndentOptions); + while (myCurrentState.getStateId() == FormattingStateId.APPLYING_CHANGES && !myCurrentState.isDone()) { + myCurrentState.iteration(); + } } public void setJavaIndentOptions(final CodeStyleSettings.IndentOptions javaIndentOptions) { myJavaIndentOptions = javaIndentOptions; } - private static void doModify(final List blocksToModify, final FormattingModel model, - CodeStyleSettings.IndentOptions indentOption, CodeStyleSettings.IndentOptions javaOptions) { - final int blocksToModifyCount = blocksToModify.size(); - DocumentEx updatedDocument = null; - - try { - final boolean bulkReformat = blocksToModifyCount > 50; - updatedDocument = bulkReformat ? getAffectedDocument(model) : null; - if (updatedDocument != null) { - updatedDocument.setInBulkUpdate(true); - } - - if (blocksToModifyCount > BULK_REPLACE_OPTIMIZATION_CRITERIA) { - if (applyChangesAtBulkMode(blocksToModify, model, indentOption)) { - return; - } - } - - int shift = 0; - for (int i = 0; i < blocksToModifyCount; ++i) { - final LeafBlockWrapper block = blocksToModify.get(i); - shift = replaceWhiteSpace(model, block, shift, block.getWhiteSpace().generateWhiteSpace(indentOption), javaOptions); - - // block could be gc'd - block.getParent().dispose(); - block.dispose(); - blocksToModify.set(i, null); - } - } - finally { - if (updatedDocument != null) { - updatedDocument.setInBulkUpdate(false); - } - model.commitChanges(); - } - } - /** * Decides whether applying formatter changes should be applied incrementally one-by-one or merge result should be * constructed locally and the whole document text should be replaced. Performs such single bulk change if necessary. @@ -256,6 +262,7 @@ class FormatProcessor { * @return true if given changes are applied to the document (i.e. no further processing is required); * false otherwise */ + @SuppressWarnings({"deprecation"}) private static boolean applyChangesAtBulkMode(final List blocksToModify, final FormattingModel model, CodeStyleSettings.IndentOptions indentOption) { @@ -326,6 +333,7 @@ class FormatProcessor { return shift; } + @NotNull private List collectBlocksToModify() { List blocksToModify = new ArrayList(); @@ -449,10 +457,8 @@ class FormatProcessor { boolean wrapIsPresent = whiteSpace.containsLineFeeds(); final ArrayList wraps = myCurrentBlock.getWraps(); - final int wrapsCount = wraps.size(); - - for (int i = 0; i < wrapsCount; ++i) { - wraps.get(i).processNextEntry(myCurrentBlock.getStartOffset()); + for (WrapImpl wrap : wraps) { + wrap.processNextEntry(myCurrentBlock.getStartOffset()); } final WrapImpl wrap = getWrapToBeUsed(wraps); @@ -489,8 +495,7 @@ class FormatProcessor { myWrapCandidate = null; } else { - for (int i = 0; i < wrapsCount; ++i) { - final WrapImpl wrap1 = wraps.get(i); + for (final WrapImpl wrap1 : wraps) { if (isCandidateToBeWrapped(wrap1) && canReplaceWrapCandidate(wrap1)) { myWrapCandidate = myCurrentBlock; } @@ -870,7 +875,6 @@ class FormatProcessor { } if (myWrapCandidate == myCurrentBlock) return wraps.get(0); - final int wrapsCount = wraps.size(); for (final WrapImpl wrap : wraps) { if (!isSuitableInTheCurrentPosition(wrap)) continue; if (wrap.isIsActive()) return wrap; @@ -1265,6 +1269,9 @@ class FormatProcessor { processToken(); if (myCurrentBlock == null) { myCurrentBlock = myLastTokenBlock; + if (myCurrentBlock != null) { + myProgressIndicator.afterProcessingBlock(myCurrentBlock); + } break; } } @@ -1302,6 +1309,218 @@ class FormatProcessor { } } } + + private abstract class State { + private final FormattingStateId myStateId; + + private State myNextState; + private boolean myDone; + protected State(FormattingStateId stateId) { + myStateId = stateId; + } + + public void iteration() { + if (!isDone()) { + doIteration(); + } + shiftStateIfNecessary(); + } + + public boolean isDone() { + return myDone; + } + + protected void setDone(boolean done) { + myDone = done; + } + + public void setNext(@NotNull State state) { + if (getStateId() == state.getStateId() || (myNextState != null && myNextState.getStateId() == state.getStateId())) { + return; + } + myNextState = state; + shiftStateIfNecessary(); + } + + public FormattingStateId getStateId() { + return myStateId; + } + + protected abstract void doIteration(); + protected abstract void prepare(); + + private void shiftStateIfNecessary() { + if (isDone() && myNextState != null) { + myCurrentState = myNextState; + myNextState = null; + myCurrentState.prepare(); + } + } + } + + private class WrapBlocksState extends State { + + private final InitialInfoBuilder myWrapper; + private final FormattingDocumentModel myModel; + + WrapBlocksState(@NotNull Block root, + @NotNull FormattingDocumentModel model, + @Nullable final FormatTextRanges affectedRanges, + int interestingOffset) + { + super(FormattingStateId.WRAPPING_BLOCKS); + myModel = model; + myWrapper = InitialInfoBuilder.prepareToBuildBlocksSequentially( + root, model, affectedRanges, myIndentOption, interestingOffset, myProgressIndicator + ); + } + + @Override + protected void prepare() { + } + + @Override + public void doIteration() { + if (isDone()) { + return; + } + + setDone(myWrapper.iteration()); + if (!isDone()) { + return; + } + + myInfos = myWrapper.getBlockToInfoMap(); + myRootBlockWrapper = myWrapper.getRootBlockWrapper(); + myFirstTokenBlock = myWrapper.getFirstTokenBlock(); + myLastTokenBlock = myWrapper.getLastTokenBlock(); + myCurrentBlock = myFirstTokenBlock; + myTextRangeToWrapper = buildTextRangeToInfoMap(myFirstTokenBlock); + myLastWhiteSpace = new WhiteSpace(getLastBlock().getEndOffset(), false); + myLastWhiteSpace.append(myModel.getTextLength(), myModel, myIndentOption); + } + } + + private class AdjustWhiteSpacesState extends State { + + AdjustWhiteSpacesState() { + super(FormattingStateId.PROCESSING_BLOCKS); + } + + @Override + protected void prepare() { + } + + @Override + protected void doIteration() { + LeafBlockWrapper blockToProcess = myCurrentBlock; + processToken(); + if (blockToProcess != null) { + myProgressIndicator.afterProcessingBlock(blockToProcess); + } + + if (myCurrentBlock != null) { + return; + } + + if (myAlignAgain.isEmpty()) { + setDone(true); + } + else { + myAlignAgain.clear(); + myCurrentBlock = myFirstTokenBlock; + } + } + } + + private class ApplyChangesState extends State { + + private final FormattingModel myModel; + private List myBlocksToModify; + private int myShift; + private int myIndex; + private boolean myResetBulkUpdateState; + + private ApplyChangesState(FormattingModel model) { + super(FormattingStateId.APPLYING_CHANGES); + myModel = model; + } + + @Override + protected void prepare() { + myBlocksToModify = collectBlocksToModify(); + // call doModifications static method to ensure no access to state + // thus we may clear formatting state + reset(); + + myInfos = null; + myRootBlockWrapper = null; + myTextRangeToWrapper = null; + myPreviousDependencies = null; + myLastWhiteSpace = null; + myFirstTokenBlock = null; + myLastTokenBlock = null; + myDisposed = true; + + if (myBlocksToModify.isEmpty()) { + setDone(true); + return; + } + + //for GeneralCodeFormatterTest + if (myJavaIndentOptions == null) { + myJavaIndentOptions = mySettings.getIndentOptions(StdFileTypes.JAVA); + } + + myProgressIndicator.beforeApplyingFormatChanges(myBlocksToModify); + + final int blocksToModifyCount = myBlocksToModify.size(); + final boolean bulkReformat = blocksToModifyCount > 50; + DocumentEx updatedDocument = bulkReformat ? getAffectedDocument(myModel) : null; + if (updatedDocument != null) { + updatedDocument.setInBulkUpdate(true); + myResetBulkUpdateState = true; + } + if (blocksToModifyCount > BULK_REPLACE_OPTIMIZATION_CRITERIA && applyChangesAtBulkMode(myBlocksToModify, myModel, myIndentOption)) { + setDone(true); + } + } + + @Override + protected void doIteration() { + LeafBlockWrapper blockWrapper = myBlocksToModify.get(myIndex); + myShift = replaceWhiteSpace( + myModel, blockWrapper, myShift, blockWrapper.getWhiteSpace().generateWhiteSpace(myIndentOption), myJavaIndentOptions + ); + myProgressIndicator.afterApplyingChange(blockWrapper); + // block could be gc'd + blockWrapper.getParent().dispose(); + blockWrapper.dispose(); + myBlocksToModify.set(myIndex, null); + myIndex++; + + if (myIndex >= myBlocksToModify.size()) { + setDone(true); + } + } + + @Override + protected void setDone(boolean done) { + super.setDone(done); + + if (myResetBulkUpdateState) { + DocumentEx document = getAffectedDocument(myModel); + if (document != null) { + document.setInBulkUpdate(false); + myResetBulkUpdateState = false; + } + } + + if (done) { + myModel.commitChanges(); + } + } + } } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java b/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java index b081bcd8ac57..1ac8053de72d 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatterEx.java @@ -18,10 +18,11 @@ package com.intellij.formatting; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.util.TextRange; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public abstract class FormatterEx{ @@ -113,6 +114,8 @@ public abstract class FormatterEx{ CodeStyleSettings.IndentOptions indentOptions, TextRange affectedRange); + public abstract void setProgressIndicator(@NotNull FormattingProgressIndicatorImpl progressIndicator); + public interface IndentInfoStorage { void saveIndentInfo(IndentInfo info, int startOffset); diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java index 57d279aa0fb6..db50bd3685fc 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java @@ -16,16 +16,20 @@ package com.intellij.formatting; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.formatter.FormattingDocumentModelImpl; import com.intellij.psi.formatter.PsiBasedFormattingModel; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.SequentialTask; import com.intellij.util.text.CharArrayUtil; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -42,6 +46,8 @@ public class FormatterImpl extends FormatterEx { private static final Logger LOG = Logger.getInstance("#com.intellij.formatting.FormatterImpl"); + private FormattingProgressIndicatorImpl myProgressIndicator; + private int myIsDisabledCount = 0; private final IndentImpl NONE_INDENT = new IndentImpl(IndentImpl.Type.NONE, false, false); private final IndentImpl myAbsoluteNoneIndent = new IndentImpl(IndentImpl.Type.NONE, true, false); @@ -82,20 +88,31 @@ public class FormatterImpl extends FormatterEx public Indent getNoneIndent() { return NONE_INDENT; } + + @Override + public void setProgressIndicator(@NotNull FormattingProgressIndicatorImpl progressIndicator) { + myProgressIndicator = progressIndicator; + } + public void format(final FormattingModel model, final CodeStyleSettings settings, final CodeStyleSettings.IndentOptions indentOptions, final CodeStyleSettings.IndentOptions javaIndentOptions, - final FormatTextRanges affectedRanges) throws IncorrectOperationException { - disableFormatting(); - try { - FormatProcessor processor = new FormatProcessor(model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, - affectedRanges); - processor.setJavaIndentOptions(javaIndentOptions); - processor.format(model); - } finally { - enableFormatting(); - } + final FormatTextRanges affectedRanges) throws IncorrectOperationException + { + SequentialTask task = new MyFormattingTask() { + @NotNull + @Override + protected FormatProcessor buildProcessor() { + FormatProcessor processor = new FormatProcessor( + model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, affectedRanges, FormattingProgressIndicator.EMPTY + ); + processor.setJavaIndentOptions(javaIndentOptions); + processor.format(model); + return processor; + } + }; + execute(task); } public Wrap createWrap(WrapType type, boolean wrapFirstElement) { @@ -125,43 +142,108 @@ public class FormatterImpl extends FormatterEx return new DependantSpacingImpl(minOffset, maxOffset, dependence, keepLineBreaks, keepBlankLines); } - public void format(FormattingModel model, - CodeStyleSettings settings, - CodeStyleSettings.IndentOptions indentOptions, - FormatTextRanges affectedRanges) throws IncorrectOperationException { - disableFormatting(); - try { - FormatProcessor processor = - new FormatProcessor(model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, affectedRanges); - processor.format(model); - } finally { - enableFormatting(); - } - + @NotNull + private FormattingProgressIndicator getProgressIndicator() { + FormattingProgressIndicator result = myProgressIndicator; + return result == null ? FormattingProgressIndicator.EMPTY : result; + } + + public void format(final FormattingModel model, + final CodeStyleSettings settings, + final CodeStyleSettings.IndentOptions indentOptions, + final FormatTextRanges affectedRanges) throws IncorrectOperationException { + SequentialTask task = new MyFormattingTask() { + @NotNull + @Override + protected FormatProcessor buildProcessor() { + FormatProcessor processor = new FormatProcessor( + model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, affectedRanges, getProgressIndicator() + ); + processor.format(model, true); + return processor; + } + }; + execute(task); } - public void formatWithoutModifications(FormattingDocumentModel model, - Block rootBlock, - CodeStyleSettings settings, - CodeStyleSettings.IndentOptions indentOptions, - TextRange affectedRange) throws IncorrectOperationException { - disableFormatting(); - try { - new FormatProcessor(model, rootBlock, settings, indentOptions, new FormatTextRanges(affectedRange, true)).formatWithoutRealModifications(); - } finally { - enableFormatting(); - } + public void formatWithoutModifications(final FormattingDocumentModel model, + final Block rootBlock, + final CodeStyleSettings settings, + final CodeStyleSettings.IndentOptions indentOptions, + final TextRange affectedRange) throws IncorrectOperationException + { + SequentialTask task = new MyFormattingTask() { + @NotNull + @Override + protected FormatProcessor buildProcessor() { + FormatProcessor result = new FormatProcessor( + model, rootBlock, settings, indentOptions, new FormatTextRanges(affectedRange, true), FormattingProgressIndicator.EMPTY + ); + result.formatWithoutRealModifications(); + return result; + } + }; + execute(task); + } + /** + * Execute given sequential formatting task. Two approaches are possible: + *

+   * 
    + *
  • + * synchronous - the task is completely executed during the current method processing; + *
  • + *
  • + * asynchronous - the task is executed at background thread under the progress dialog; + *
  • + *
+ *
+ * + * @param task task to execute + */ + private void execute(@NotNull SequentialTask task) { + disableFormatting(); + if (myProgressIndicator == null || !ApplicationManager.getApplication().isDispatchThread()) { + try { + task.prepare(); + while (!task.isDone()) { + task.iteration(); + } + } + finally { + enableFormatting(); + } + } + else { + myProgressIndicator.setTask(task); + myProgressIndicator.addCallback(FormattingProgressIndicator.EventType.SUCCESS, new Runnable() { + @Override + public void run() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + // Reset current progress indicator. + myProgressIndicator = null; + enableFormatting(); + } + }); + } + }); + ProgressManager.getInstance().run(myProgressIndicator); + } } public IndentInfo getWhiteSpaceBefore(final FormattingDocumentModel model, final Block block, final CodeStyleSettings settings, final CodeStyleSettings.IndentOptions indentOptions, - final TextRange affectedRange, final boolean mayChangeLineFeeds) { + final TextRange affectedRange, final boolean mayChangeLineFeeds) + { disableFormatting(); try { - final FormatProcessor processor = new FormatProcessor(model, block, settings, indentOptions, new FormatTextRanges(affectedRange, true)); + final FormatProcessor processor = buildProcessorAndWrapBlocks( + model, block, settings, indentOptions, new FormatTextRanges(affectedRange, true) + ); final LeafBlockWrapper blockBefore = processor.getBlockAfter(affectedRange.getStartOffset()); LOG.assertTrue(blockBefore != null); WhiteSpace whiteSpace = blockBefore.getWhiteSpace(); @@ -187,8 +269,9 @@ public class FormatterImpl extends FormatterEx try { final FormattingDocumentModel documentModel = model.getDocumentModel(); final Block block = model.getRootBlock(); - final FormatProcessor processor = new FormatProcessor(documentModel, block, settings, indentOptions, - new FormatTextRanges(rangeToAdjust, true)); + final FormatProcessor processor = buildProcessorAndWrapBlocks( + documentModel, block, settings, indentOptions, new FormatTextRanges(rangeToAdjust, true) + ); LeafBlockWrapper tokenBlock = processor.getFirstTokenBlock(); while (tokenBlock != null) { final WhiteSpace whiteSpace = tokenBlock.getWhiteSpace(); @@ -215,8 +298,9 @@ public class FormatterImpl extends FormatterEx try { final FormattingDocumentModel documentModel = model.getDocumentModel(); final Block block = model.getRootBlock(); - final FormatProcessor processor = new FormatProcessor(documentModel, block, settings, - settings.getIndentOptions(fileType), null); + final FormatProcessor processor = buildProcessorAndWrapBlocks( + documentModel, block, settings, settings.getIndentOptions(fileType), null + ); LeafBlockWrapper tokenBlock = processor.getFirstTokenBlock(); while (tokenBlock != null) { final WhiteSpace whiteSpace = tokenBlock.getWhiteSpace(); @@ -256,9 +340,9 @@ public class FormatterImpl extends FormatterEx try { final FormattingDocumentModel documentModel = model.getDocumentModel(); final Block block = model.getRootBlock(); - final FormatProcessor processor = new FormatProcessor(documentModel, block, settings, indentOptions, - new FormatTextRanges(affectedRange, true), - offset); + final FormatProcessor processor = buildProcessorAndWrapBlocks( + documentModel, block, settings, indentOptions, new FormatTextRanges(affectedRange, true), offset + ); final LeafBlockWrapper blockAfterOffset = processor.getBlockAfter(offset); @@ -276,6 +360,54 @@ public class FormatterImpl extends FormatterEx } } + /** + * Delegates to + * {@link #buildProcessorAndWrapBlocks(FormattingDocumentModel, Block, CodeStyleSettings, CodeStyleSettings.IndentOptions, FormatTextRanges, int)} + * with '-1' as an interested offset. + * + * @param docModel + * @param rootBlock + * @param settings + * @param indentOptions + * @param affectedRanges + * @return + */ + private static FormatProcessor buildProcessorAndWrapBlocks(final FormattingDocumentModel docModel, + Block rootBlock, + CodeStyleSettings settings, + CodeStyleSettings.IndentOptions indentOptions, + @Nullable FormatTextRanges affectedRanges) + { + return buildProcessorAndWrapBlocks(docModel, rootBlock, settings, indentOptions, affectedRanges, -1); + } + + /** + * Builds {@link FormatProcessor} instance and asks it to wrap all {@link Block code blocks} + * {@link FormattingModel#getRootBlock() derived from the given model}. + * + * @param docModel target model + * @param rootBlock root block to process + * @param settings code style settings to use + * @param indentOptions indent options to use + * @param affectedRanges ranges to reformat + * @param interestingOffset interesting offset; '-1' if no particular offset has a special interest + * @return format processor instance with wrapped {@link Block code blocks} + */ + @SuppressWarnings({"StatementWithEmptyBody"}) + private static FormatProcessor buildProcessorAndWrapBlocks(final FormattingDocumentModel docModel, + Block rootBlock, + CodeStyleSettings settings, + CodeStyleSettings.IndentOptions indentOptions, + @Nullable FormatTextRanges affectedRanges, + int interestingOffset) + { + FormatProcessor processor = new FormatProcessor( + docModel, rootBlock, settings, indentOptions, affectedRanges, interestingOffset, FormattingProgressIndicator.EMPTY + ); + while (!processor.iteration()) ; + return processor; + } + private static int adjustLineIndent( final int offset, final FormattingDocumentModel documentModel, @@ -323,9 +455,9 @@ public class FormatterImpl extends FormatterEx final TextRange affectedRange) { final FormattingDocumentModel documentModel = model.getDocumentModel(); final Block block = model.getRootBlock(); - final FormatProcessor processor = new FormatProcessor(documentModel, block, settings, indentOptions, - new FormatTextRanges(affectedRange, true), offset); - + final FormatProcessor processor = buildProcessorAndWrapBlocks( + documentModel, block, settings, indentOptions, new FormatTextRanges(affectedRange, true), offset + ); final LeafBlockWrapper blockAfterOffset = processor.getBlockAfter(offset); if (blockAfterOffset != null) { @@ -398,8 +530,9 @@ public class FormatterImpl extends FormatterEx @Nullable final IndentInfoStorage indentInfoStorage) { disableFormatting(); try { - final FormatProcessor processor = new FormatProcessor(model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, - new FormatTextRanges(affectedRange, true)); + final FormatProcessor processor = buildProcessorAndWrapBlocks( + model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, new FormatTextRanges(affectedRange, true) + ); LeafBlockWrapper current = processor.getFirstTokenBlock(); while (current != null) { WhiteSpace whiteSpace = current.getWhiteSpace(); @@ -462,8 +595,9 @@ public class FormatterImpl extends FormatterEx final TextRange affectedRange) { disableFormatting(); try { - final FormatProcessor processor = new FormatProcessor(model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, - new FormatTextRanges(affectedRange, true)); + final FormatProcessor processor = buildProcessorAndWrapBlocks( + model.getDocumentModel(), model.getRootBlock(), settings, indentOptions, new FormatTextRanges(affectedRange, true) + ); LeafBlockWrapper current = processor.getFirstTokenBlock(); while (current != null) { WhiteSpace whiteSpace = current.getWhiteSpace(); @@ -489,8 +623,10 @@ public class FormatterImpl extends FormatterEx final CodeStyleSettings settings, final CodeStyleSettings.IndentOptions indentOptions) { final Block block = model.getRootBlock(); - final FormatProcessor processor = new FormatProcessor(model.getDocumentModel(), block, settings, indentOptions, - new FormatTextRanges(affectedRange, true)); + + final FormatProcessor processor = buildProcessorAndWrapBlocks( + model.getDocumentModel(), block, settings, indentOptions, new FormatTextRanges(affectedRange, true) + ); LeafBlockWrapper current = processor.getFirstTokenBlock(); while (current != null) { WhiteSpace whiteSpace = current.getWhiteSpace(); @@ -601,4 +737,28 @@ public class FormatterImpl extends FormatterEx myIsDisabledCount--; } } + + private abstract static class MyFormattingTask implements SequentialTask { + + private FormatProcessor myProcessor; + private boolean myDone; + + @Override + public void prepare() { + myProcessor = buildProcessor(); + } + + @Override + public boolean isDone() { + return myDone; + } + + @Override + public boolean iteration() { + return myDone = myProcessor.iteration(); + } + + @NotNull + protected abstract FormatProcessor buildProcessor(); + } } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicator.java b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicator.java new file mode 100644 index 000000000000..4b75d3d91616 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicator.java @@ -0,0 +1,121 @@ +/* + * Copyright 2000-2011 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.formatting; + +import com.intellij.util.SequentialTask; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +/** + * Defines common interface for formatting-aware progress indicator. + * + * @author Denis Zhdanov + * @since 2/10/11 3:38 PM + */ +public interface FormattingProgressIndicator { + + enum EventType { SUCCESS, CANCEL } + + /** + * Notifies current indicator that particular {@link Block code block} is wrapped. + * + * @param wrapped wrapped code block + * @see FormattingStateId#WRAPPING_BLOCKS + */ + void afterWrappingBlock(@NotNull LeafBlockWrapper wrapped); + + /** + * Notifies current indicator that given {@link LeafBlockWrapper wrapped code block} is processed, i.e. its + * {@link AbstractBlockWrapper#getWhiteSpace() white space} is adjusted as necessary. + * + * @param block processed wrapped block which white space if adjusted + * @see FormattingStateId#PROCESSING_BLOCKS + */ + void afterProcessingBlock(@NotNull LeafBlockWrapper block); + + /** + * Notifies current indicator that changes from the given {@link LeafBlockWrapper wrapped code blocks} are about to be flushed + * to the underlying document. + * + * @param modifiedBlocks blocks with modified {@link AbstractBlockWrapper#getWhiteSpace() white spaces} which are about + * to be flushed to the underlying document + * @see FormattingStateId#APPLYING_CHANGES + */ + void beforeApplyingFormatChanges(@NotNull Collection modifiedBlocks); + + /** + * Notifies current indicator that change from the given {@link LeafBlockWrapper wrapped code block} is successfully flushed + * to the underlying document. + * + * @param block {@link LeafBlockWrapper wrapped code block} which change is successfully flushed to the underlying document + * @see FormattingStateId#APPLYING_CHANGES + */ + void afterApplyingChange(@NotNull LeafBlockWrapper block); + + /** + * Allows to define an actual formatting task to process. + *

+ * I.e. the general idea is that given indicator is provided with the task which will be executed from EDT + * {@link SequentialTask#iteration() part by part} until the task {@link SequentialTask#isDone() is finished}. + * That 'part-by-part' processing is assumed to update current indicator (call 'beforeXxx()' + * and 'afterXxx()' methods). + * + * @param task formatter task to process + */ + void setTask(@Nullable SequentialTask task); + + /** + * Allows to register callback for the target event type. + * + * @param eventType target event type + * @param callback callback to register for the given event type + * @return true if given callback is successfully registered for the given event type; + * false otherwise + */ + boolean addCallback(@NotNull EventType eventType, @NotNull Runnable callback); + + /** + * Null object for {@link FormattingProgressIndicator}. + */ + FormattingProgressIndicator EMPTY = new FormattingProgressIndicator() { + @Override + public void afterWrappingBlock(@NotNull LeafBlockWrapper wrapped) { + } + + @Override + public void afterProcessingBlock(@NotNull LeafBlockWrapper block) { + } + + @Override + public void beforeApplyingFormatChanges(@NotNull Collection modifiedBlocks) { + } + + @Override + public void afterApplyingChange(@NotNull LeafBlockWrapper block) { + } + + @Override + public void setTask(@Nullable SequentialTask task) { + } + + @Override + public boolean addCallback(@NotNull EventType eventType, @NotNull Runnable callback) { + return false; + } + }; +} diff --git a/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java new file mode 100644 index 000000000000..8ca214e2a78a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java @@ -0,0 +1,285 @@ +/* + * Copyright 2000-2011 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.formatting; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.util.SequentialTask; +import com.intellij.util.containers.HashSet; +import gnu.trove.TObjectIntHashMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Formatting progressable task. + * + * @author Denis Zhdanov + * @since 2/10/11 3:00 PM + */ +public class FormattingProgressIndicatorImpl extends Task.Modal implements FormattingProgressIndicator { + + private static final Logger LOG = Logger.getInstance("#" + FormattingProgressIndicatorImpl.class.getName()); + + /** + * We want to perform formatting by big chunks at EDT. However, there is a possible case that particular formatting iteration + * is executed in short amount of time. Hence, we may want to execute more than one formatting action during single EDT iteration. + * Current collection contains mappings between min amount of time allowed for particular state iteration processing from EDT. + */ + private static final TObjectIntHashMap ITERATION_MIN_TIMES_MILLIS = new TObjectIntHashMap(); + static { + ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.WRAPPING_BLOCKS, 500); + ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.PROCESSING_BLOCKS, 500); + ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.APPLYING_CHANGES, 3000); + assert ITERATION_MIN_TIMES_MILLIS.size() == FormattingStateId.values().length; + } + + /** + * Holds max allowed progress bar value (defined at ProgressWindow.MyDialog.initDialog()). + */ + private static final double MAX_PROGRESS_VALUE = 1; + private static final double TOTAL_WEIGHT; + static { + double weight = 0; + for (FormattingStateId state : FormattingStateId.values()) { + weight += state.getProgressWeight(); + } + TOTAL_WEIGHT = weight; + } + + private final Map> myCallbacks = new HashMap>(); + + @Nullable + private final VirtualFile myFile; + private final Document myDocument; + private final int myFileTextLength; + + @NotNull + private FormattingStateId myLastState = FormattingStateId.WRAPPING_BLOCKS; + private long myDocumentModificationStampBefore = -1; + private volatile boolean myRunning = true; + + private ProgressIndicator myIndicator; + private SequentialTask myTask; + private int myBlocksToModifyNumber; + private int myModifiedBlocksNumber; + + public FormattingProgressIndicatorImpl(@Nullable Project project, @NotNull PsiFile file, @NotNull Document document) { + super(project, getTitle(file), false); + myFile = file.getVirtualFile(); + myDocument = document; + myFileTextLength = file.getTextLength(); + addCallback(EventType.CANCEL, new MyCancelCallback()); + } + + @NotNull + private static String getTitle(@NotNull PsiFile file) { + VirtualFile virtualFile = file.getOriginalFile().getVirtualFile(); + if (virtualFile == null) { + return CodeInsightBundle.message("reformat.progress.common.text"); + } + else { + return CodeInsightBundle.message("reformat.progress.file.with.known.name.text", virtualFile.getName()); + } + } + + @Override + public void run(@NotNull ProgressIndicator indicator) { + try { + doRun(indicator); + } + catch (Exception e) { + LOG.info("Unexpected exception occurred during reformatting file " + myFile, e); + } + } + + @SuppressWarnings({"SSBasedInspection"}) + public void doRun(@NotNull ProgressIndicator indicator) throws InvocationTargetException, InterruptedException { + final SequentialTask task = myTask; + if (task == null) { + return; + } + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + myDocumentModificationStampBefore = myDocument.getModificationStamp(); + task.prepare(); + } + }); + + // We need to sync background thread and EDT here in order to avoid situation when event queue is full of processing requests. + final Lock lock = new ReentrantLock(); + final Condition condition = lock.newCondition(); + myIndicator = indicator; + + while (myRunning && !myTask.isDone()) { + lock.lock(); + try { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < ITERATION_MIN_TIMES_MILLIS.get(myLastState)) { + task.iteration(); + } + lock.lock(); + try { + condition.signal(); + } + finally { + lock.unlock(); + } + } + }); + condition.await(); + } + finally { + lock.unlock(); + } + } + } + + @Override + public boolean addCallback(@NotNull EventType eventType, @NotNull Runnable callback) { + return getCallbacks(eventType).add(callback); + } + + @Override + public void onSuccess() { + super.onSuccess(); + for (Runnable callback : getCallbacks(EventType.SUCCESS)) { + callback.run(); + } + } + + @Override + public void onCancel() { + super.onCancel(); + for (Runnable callback : getCallbacks(EventType.CANCEL)) { + callback.run(); + } + } + + private Collection getCallbacks(@NotNull EventType eventType) { + Collection result = myCallbacks.get(eventType); + if (result == null) { + myCallbacks.put(eventType, result = new HashSet()); + } + return result; + } + + @Override + public void afterWrappingBlock(@NotNull LeafBlockWrapper wrapped) { + update(FormattingStateId.WRAPPING_BLOCKS, MAX_PROGRESS_VALUE * wrapped.getEndOffset() / myFileTextLength); + } + + @Override + public void afterProcessingBlock(@NotNull LeafBlockWrapper block) { + update(FormattingStateId.PROCESSING_BLOCKS, MAX_PROGRESS_VALUE * block.getEndOffset() / myFileTextLength); + } + + @Override + public void beforeApplyingFormatChanges(@NotNull Collection modifiedBlocks) { + myBlocksToModifyNumber = modifiedBlocks.size(); + updateTextIfNecessary(FormattingStateId.APPLYING_CHANGES); + } + + @Override + public void afterApplyingChange(@NotNull LeafBlockWrapper block) { + if (myModifiedBlocksNumber++ >= myBlocksToModifyNumber) { + return; + } + + update(FormattingStateId.APPLYING_CHANGES, MAX_PROGRESS_VALUE * myModifiedBlocksNumber / myBlocksToModifyNumber); + } + + @Override + public void setTask(@Nullable SequentialTask task) { + myTask = task; + } + + /** + * Updates current progress state if necessary. + * + * @param state current state + * @param completionRate completion rate of the given state. Is assumed to belong to [0; 1] interval + */ + private void update(@NotNull FormattingStateId state, double completionRate) { + if (myIndicator == null) { + return; + } + + updateTextIfNecessary(state); + + myLastState = state; + double newFraction = 0; + for (FormattingStateId prevState : state.getPreviousStates()) { + newFraction += MAX_PROGRESS_VALUE * prevState.getProgressWeight() / TOTAL_WEIGHT; + } + newFraction += completionRate * state.getProgressWeight() / TOTAL_WEIGHT; + + // We don't bother about imprecise floating point arithmetic here because that is enough for progress representation. + double currentFraction = myIndicator.getFraction(); + if (newFraction - currentFraction < MAX_PROGRESS_VALUE / 100) { + return; + } + + myIndicator.setFraction(newFraction); + } + + private void updateTextIfNecessary(@NotNull FormattingStateId currentState) { + if (myLastState != currentState && myIndicator != null) { + myIndicator.setText(currentState.getDescription()); + } + } + + private class MyCancelCallback implements Runnable { + @Override + public void run() { + myRunning = false; + if (myFile == null || myDocumentModificationStampBefore < 0) { + return; + } + FileEditor editor = FileEditorManager.getInstance(myProject).getSelectedEditor(myFile); + if (editor == null) { + return; + } + + UndoManager manager = UndoManager.getInstance(myProject); + while (manager.isUndoAvailable(editor) && myDocument.getModificationStamp() != myDocumentModificationStampBefore) { + manager.undo(editor); + } + } + } +} diff --git a/platform/lang-impl/src/com/intellij/formatting/FormattingStateId.java b/platform/lang-impl/src/com/intellij/formatting/FormattingStateId.java new file mode 100644 index 000000000000..5d4aa1c801d2 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/formatting/FormattingStateId.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2011 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.formatting; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import org.jetbrains.annotations.NotNull; + +import java.util.EnumSet; +import java.util.Set; + +/** + * Enumerates formatting processing states. + * + * @author Denis Zhdanov + * @since 2/10/11 2:50 PM + */ +public enum FormattingStateId { + + /** + * Corresponds to {@link InitialInfoBuilder#buildFrom(Block, int, CompositeBlockWrapper, WrapImpl, Block, boolean)}. + *

+ * I.e. the first thing formatter does retrieval of all {@link Block code blocks} from target {@link FormattingModel model} + * and wrapping them in order to be able to store information about modified white spaces. That processing may trigger + * blocks construction because most of our formatting models do that lazily, i.e. they define the + * {@link FormattingModel#getRootBlock() root block} and build its sub-blocks only on the {@link Block#getSubBlocks() first request}. + */ + WRAPPING_BLOCKS(2), + + /** + * This element corresponds to the state when formatter sequentially processes {@link AbstractBlockWrapper wrapped code blocks} + * and modifies their {@link WhiteSpace white spaces} according to the current {@link CodeStyleSettings code style settings}. + */ + PROCESSING_BLOCKS(1), + + /** + * This element corresponds to formatting phase when all {@link AbstractBlockWrapper wrapped code blocks} are processed and it's + * time to apply the changes to the underlying document. + */ + APPLYING_CHANGES(10); + + private final String myDescription; + private final double myWeight; + + FormattingStateId(double weight) { + myWeight = weight; + myDescription = CodeInsightBundle.message("progress.reformat.stage." + toString().replace('_', '.').toLowerCase()); + } + + /** + * @return human-readable textual description of the current state id + */ + public String getDescription() { + return myDescription; + } + + /** + * @return 'weight' of the current state. Basically, it's assumed that every processing iteration of the state + * with greater weight is executed longer that processing iteration of the state with the lower weight + */ + public double getProgressWeight() { + return myWeight; + } + + /** + * @return collection of formatting states that are assumed to be executed prior to the current one + */ + @NotNull + public Set getPreviousStates() { + Set result = EnumSet.noneOf(FormattingStateId.class); + for (FormattingStateId state : values()) { + if (state == this) { + break; + } + result.add(state); + } + return result; + } +} diff --git a/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java b/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java index 962be9631800..654affcf01f1 100644 --- a/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java +++ b/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java @@ -24,9 +24,12 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.formatter.FormattingDocumentModelImpl; import com.intellij.psi.formatter.ReadOnlyBlockInformationProvider; import com.intellij.psi.impl.DebugUtil; +import com.intellij.util.containers.Stack; import gnu.trove.THashMap; import org.apache.commons.collections.Unmodifiable; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -39,47 +42,75 @@ import java.util.Map; class InitialInfoBuilder { private static final Logger LOG = Logger.getInstance("#com.intellij.formatting.InitialInfoBuilder"); - private WhiteSpace myCurrentWhiteSpace; - private final FormattingDocumentModel myModel; - private final FormatTextRanges myAffectedRanges; - private final int myPositionOfInterest; private final Map myResult = new THashMap(); - private CompositeBlockWrapper myRootBlockWrapper; - private LeafBlockWrapper myPreviousBlock; - private LeafBlockWrapper myFirstTokenBlock; - private LeafBlockWrapper myLastTokenBlock; - private SpacingImpl myCurrentSpaceProperty; + + private final FormattingDocumentModel myModel; + private final FormatTextRanges myAffectedRanges; + private final int myPositionOfInterest; + @NotNull + private final FormattingProgressIndicator myProgressIndicator; private final CodeStyleSettings.IndentOptions myOptions; + + private final Stack myStates = new Stack(); + + private WhiteSpace myCurrentWhiteSpace; + private CompositeBlockWrapper myRootBlockWrapper; + private LeafBlockWrapper myPreviousBlock; + private LeafBlockWrapper myFirstTokenBlock; + private LeafBlockWrapper myLastTokenBlock; + private SpacingImpl myCurrentSpaceProperty; private ReadOnlyBlockInformationProvider myReadOnlyBlockInformationProvider; private InitialInfoBuilder(final FormattingDocumentModel model, final FormatTextRanges affectedRanges, final CodeStyleSettings.IndentOptions options, - final int positionOfInterest - ) { + final int positionOfInterest, + @NotNull FormattingProgressIndicator progressIndicator) + { myModel = model; myAffectedRanges = affectedRanges; + myProgressIndicator = progressIndicator; myCurrentWhiteSpace = new WhiteSpace(0, true); myOptions = options; myPositionOfInterest = positionOfInterest; } - public static InitialInfoBuilder buildBlocks(Block root, - FormattingDocumentModel model, - final FormatTextRanges affectedRanges, - final CodeStyleSettings.IndentOptions options, - int interestingOffset) { - final InitialInfoBuilder builder = new InitialInfoBuilder(model, affectedRanges, options, interestingOffset); - final AbstractBlockWrapper wrapper = builder.buildFrom(root, 0, null, null, null, true); - wrapper.setIndent((IndentImpl)Indent.getNoneIndent()); + public static InitialInfoBuilder prepareToBuildBlocksSequentially(Block root, + FormattingDocumentModel model, + final FormatTextRanges affectedRanges, + final CodeStyleSettings.IndentOptions options, + int interestingOffset, + @NotNull FormattingProgressIndicator progressIndicator) + { + InitialInfoBuilder builder = new InitialInfoBuilder(model, affectedRanges, options, interestingOffset, progressIndicator); + builder.buildFrom(root, 0, null, null, null, true); return builder; } + /** + * Asks current builder to wrap one more remaining {@link Block code block} (if any). + * + * @return true if all blocks are wrapped; false otherwise + */ + public boolean iteration() { + if (myStates.isEmpty()) { + return true; + } + + State state = myStates.peek(); + doIteration(state); + if (myStates.isEmpty()) { + state.wrappedBlock.setIndent((IndentImpl)Indent.getNoneIndent()); + return true; + } + return false; + } + /** * Wraps given root block and all of its descendants and returns root block wrapper. *

* This method performs necessary infrastructure actions and delegates actual processing to - * {@link #processCompositeBlock(Block, CompositeBlockWrapper, int, WrapImpl, boolean)} and + * {@link #buildCompositeBlock(Block, CompositeBlockWrapper, int, WrapImpl, boolean)} and * {@link #processSimpleBlock(Block, CompositeBlockWrapper, boolean, int, Block)}. * * @param rootBlock block to wrap @@ -147,67 +178,71 @@ class InitialInfoBuilder { } return wrapper; } - return processCompositeBlock(rootBlock, parent, index, currentWrapParent, rootBlockIsRightBlock); + return buildCompositeBlock(rootBlock, parent, index, currentWrapParent, rootBlockIsRightBlock); } finally { myReadOnlyBlockInformationProvider = previousProvider; } } - private AbstractBlockWrapper processCompositeBlock(final Block rootBlock, - final CompositeBlockWrapper parent, - final int index, - final WrapImpl currentWrapParent, - boolean rootBlockIsRightBlock - ) { - final CompositeBlockWrapper info = new CompositeBlockWrapper(rootBlock, myCurrentWhiteSpace, parent); + private CompositeBlockWrapper buildCompositeBlock(final Block rootBlock, + final CompositeBlockWrapper parent, + final int index, + final WrapImpl currentWrapParent, + boolean rootBlockIsRightBlock) + { + final CompositeBlockWrapper wrappedRootBlock = new CompositeBlockWrapper(rootBlock, myCurrentWhiteSpace, parent); if (index == 0) { - info.arrangeParentTextRange(); + wrappedRootBlock.arrangeParentTextRange(); } - if (myRootBlockWrapper == null) myRootBlockWrapper = info; + if (myRootBlockWrapper == null) myRootBlockWrapper = wrappedRootBlock; boolean blocksMayBeOfInterest = false; if (myPositionOfInterest != -1) { - myResult.put(info, rootBlock); + myResult.put(wrappedRootBlock, rootBlock); blocksMayBeOfInterest = true; } - - Block previous = null; - List subBlocks = rootBlock.getSubBlocks(); - final int subBlocksCount = subBlocks.size(); - List list = new ArrayList(subBlocksCount); final boolean blocksAreReadOnly = rootBlock instanceof ReadOnlyBlockContainer || blocksMayBeOfInterest; - - for (int i = 0; i < subBlocksCount; i++) { - final Block block = subBlocks.get(i); - if (previous != null) { - myCurrentSpaceProperty = (SpacingImpl)rootBlock.getSpacing(previous, block); - } - - boolean childBlockIsRightBlock = false; - - if (i == subBlocksCount - 1 && rootBlockIsRightBlock) { - childBlockIsRightBlock = true; - } - - final AbstractBlockWrapper wrapper = buildFrom(block, i, info, currentWrapParent, rootBlock, childBlockIsRightBlock); - list.add(wrapper); - - if (wrapper.getIndent() == null) { - wrapper.setIndent((IndentImpl)block.getIndent()); - } - previous = block; - - if (!blocksAreReadOnly && !(subBlocks instanceof Unmodifiable) && !(subBlocks instanceof ImmutableCollection)) { - subBlocks.set(i, null); // to prevent extra strong refs during model building - } - } - setDefaultIndents(list); - info.setChildren(list); - return info; + + State state = new State(rootBlock, wrappedRootBlock, currentWrapParent, blocksAreReadOnly, rootBlockIsRightBlock); + myStates.push(state); + return wrappedRootBlock; } + private void doIteration(@NotNull State state) { + List subBlocks = state.parentBlock.getSubBlocks(); + final int subBlocksCount = subBlocks.size(); + int childBlockIndex = state.getIndexOfChildBlockToProcess(); + final Block block = subBlocks.get(childBlockIndex); + if (state.previousBlock != null) { + myCurrentSpaceProperty = (SpacingImpl)state.parentBlock.getSpacing(state.previousBlock, block); + } + + boolean childBlockIsRightBlock = false; + + if (childBlockIndex == subBlocksCount - 1 && state.parentBlockIsRightBlock) { + childBlockIsRightBlock = true; + } + + final AbstractBlockWrapper wrapper = buildFrom( + block, childBlockIndex, state.wrappedBlock, state.parentBlockWrap, state.parentBlock, childBlockIsRightBlock + ); + + if (wrapper.getIndent() == null) { + wrapper.setIndent((IndentImpl)block.getIndent()); + } + if (!state.readOnly && !(subBlocks instanceof Unmodifiable) && !(subBlocks instanceof ImmutableCollection)) { + subBlocks.set(childBlockIndex, null); // to prevent extra strong refs during model building + } + + if (state.childBlockProcessed(block, wrapper)) { + while (!myStates.isEmpty() && myStates.peek().isProcessed()) { + myStates.pop(); + } + } + } + private void setDefaultIndents(final List list) { if (!list.isEmpty()) { for (AbstractBlockWrapper wrapper : list) { @@ -222,9 +257,19 @@ class InitialInfoBuilder { final CompositeBlockWrapper parent, final boolean readOnly, final int index, - Block parentBlock + Block parentBlock) + { + LeafBlockWrapper result = doProcessSimpleBlock(rootBlock, parent, readOnly, index, parentBlock); + myProgressIndicator.afterWrappingBlock(result); + return result; + } - ) { + private LeafBlockWrapper doProcessSimpleBlock(final Block rootBlock, + final CompositeBlockWrapper parent, + final boolean readOnly, + final int index, + Block parentBlock) + { final LeafBlockWrapper info = new LeafBlockWrapper(rootBlock, parent, myCurrentWhiteSpace, myModel, myOptions, myPreviousBlock, readOnly); if (index == 0) { @@ -334,4 +379,70 @@ class InitialInfoBuilder { LOG.error(buffer); } + + /** + * We want to wrap {@link Block code blocks} sequentially, hence, need to store a processing state and continure from the point + * where we stopped the processing last time. + *

+ * Current class defines common contract for the state required for such a processing. + */ + private class State { + + public final Block parentBlock; + public final WrapImpl parentBlockWrap; + public final CompositeBlockWrapper wrappedBlock; + public final boolean readOnly; + public final boolean parentBlockIsRightBlock; + + public Block previousBlock; + + private final List myWrappedChildren = new ArrayList(); + + State(@NotNull Block parentBlock, @NotNull CompositeBlockWrapper wrappedBlock, @Nullable WrapImpl parentBlockWrap, + boolean readOnly, boolean parentBlockIsRightBlock) + { + this.parentBlock = parentBlock; + this.wrappedBlock = wrappedBlock; + this.parentBlockWrap = parentBlockWrap; + this.readOnly = readOnly; + this.parentBlockIsRightBlock = parentBlockIsRightBlock; + } + + /** + * @return index of the first non-processed {@link Block#getSubBlocks() child block} of the {@link #parentBlock target block} + */ + public int getIndexOfChildBlockToProcess() { + return myWrappedChildren.size(); + } + + /** + * Notifies current state that child block is processed. + * + * @return true if all child blocks of the block denoted by the current state are processed; + * false otherwise + */ + public boolean childBlockProcessed(@NotNull Block child, @NotNull AbstractBlockWrapper wrappedChild) { + myWrappedChildren.add(wrappedChild); + previousBlock = child; + + int subBlocksNumber = parentBlock.getSubBlocks().size(); + if (myWrappedChildren.size() > subBlocksNumber) { + return true; + } + else if (myWrappedChildren.size() == subBlocksNumber) { + setDefaultIndents(myWrappedChildren); + wrappedBlock.setChildren(myWrappedChildren); + return true; + } + return false; + } + + /** + * @return true if current state is processed (basically, if all {@link Block#getSubBlocks() child blocks}) + * of the {@link #parentBlock target block} are processed; false otherwise + */ + public boolean isProcessed() { + return myWrappedChildren.size() == parentBlock.getSubBlocks().size(); + } + } } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java index a6d8152bc3ff..4708ab4c5307 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java @@ -187,7 +187,9 @@ public class CodeFormatterFacade { document, project, mySettings, file.getFileType(), file); - FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(file.getFileType()), ranges); + FormatterEx formatter = FormatterEx.getInstanceEx(); + formatter.setProgressIndicator(new FormattingProgressIndicatorImpl(project, file, document)); + formatter.format(model, mySettings, mySettings.getIndentOptions(file.getFileType()), ranges); for (FormatTextRanges.FormatTextRange range : textRanges) { TextRange textRange = range.getTextRange(); wrapLongLinesIfNecessary(file, document, textRange.getStartOffset(), textRange.getEndOffset()); diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index 4a8682c16c7d..0b34d680a92a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -54,19 +54,19 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa private static final int UPDATE_INTERVAL = 50; //msec. 20 frames per second. private MyDialog myDialog; - private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); + private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private final Alarm myInstallFunAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private final Alarm myShowWindowAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private final Project myProject; private final boolean myShouldShowCancel; - private String myCancelText; + private String myCancelText; private String myTitle = null; private boolean myStoppedAlready = false; protected final FocusTrackback myFocusTrackback; - private boolean myStarted = false; + private boolean myStarted = false; private boolean myBackgrounded = false; private boolean myWasShown; private String myProcessId = ""; @@ -84,7 +84,11 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa this(shouldShowCancel, shouldShowBackground, project, null, cancelText); } - public ProgressWindow(boolean shouldShowCancel, boolean shouldShowBackground, @Nullable Project project, JComponent parentComponent, String cancelText) { + public ProgressWindow(boolean shouldShowCancel, + boolean shouldShowBackground, + @Nullable Project project, + JComponent parentComponent, + String cancelText) { myProject = project; myShouldShowCancel = shouldShowCancel; myCancelText = cancelText; @@ -125,35 +129,40 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa } protected void prepareShowDialog() { - SwingUtilities.invokeLater(new Runnable() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override public void run() { - myShowWindowAlarm.addRequest(new Runnable() { - public void run() { + // We know at least about one use-case the requires special treatment here: many short (in terms of time) progress tasks are + // executed in a small amount of time. Problem: UI blinks and looks ugly if we show progress dialog that disappears shortly + // for each of them. Solution is to postpone the tasks of showing progress dialog. Hence, it will not be shown at all + // if the task is already finished when the time comes. + Timer timer = new Timer(300, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { if (isRunning()) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (myDialog != null) { - final DialogWrapper popup = myDialog.myPopup; - if (popup != null) { - myFocusTrackback.registerFocusComponent(new FocusTrackback.ComponentQuery() { - public Component getComponent() { - return popup.getPreferredFocusedComponent(); - } - }); - if (popup.isShowing()) { - myWasShown = true; - } + if (myDialog != null) { + final DialogWrapper popup = myDialog.myPopup; + if (popup != null) { + myFocusTrackback.registerFocusComponent(new FocusTrackback.ComponentQuery() { + @SuppressWarnings({"ConstantConditions"}) + public Component getComponent() { + return popup.getPreferredFocusedComponent(); } + }); + if (popup.isShowing()) { + myWasShown = true; } } - }); + } showDialog(); } else { Disposer.dispose(ProgressWindow.this); } } - }, 300, getModalityState()); + }); + timer.setRepeats(false); + timer.start(); } }); } @@ -204,7 +213,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa if (!ApplicationManager.getApplication().isHeadlessEnvironment()) { Runnable installer = new Runnable() { public void run() { - if (isRunning() && !isCanceled() && getFraction() < 0.15 && myDialog!=null) { + if (isRunning() && !isCanceled() && getFraction() < 0.15 && myDialog != null) { final JComponent cmp = ProgressManager.getInstance().getProvidedFunComponent(myProject, getProcessId()); if (cmp != null) { setFunComponent(cmp); @@ -237,7 +246,8 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa myDialog.hide(); if (myDialog.wasShown()) { myFocusTrackback.restoreFocus(); - } else { + } + else { myFocusTrackback.consume(); } } @@ -378,18 +388,18 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa private JProgressBar myProgressBar; private boolean myRepaintedFlag = true; - private JPanel myFunPanel; - private TitlePanel myTitlePanel; - private DialogWrapper myPopup; - private final Window myParentWindow; - private Point myLastClicked; + private JPanel myFunPanel; + private TitlePanel myTitlePanel; + private DialogWrapper myPopup; + private final Window myParentWindow; + private Point myLastClicked; public MyDialog(boolean shouldShowBackground, Project project, String cancelText) { Window parentWindow = WindowManager.getInstance().suggestParentWindow(project); if (parentWindow == null) { parentWindow = WindowManagerEx.getInstanceEx().getMostRecentFocusedWindow(); } - myParentWindow =parentWindow; + myParentWindow = parentWindow; initDialog(shouldShowBackground, cancelText); } @@ -448,7 +458,6 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa } } }); - } public void dispose() { @@ -470,7 +479,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa }); } - public void changeCancelButtonText(String text){ + public void changeCancelButtonText(String text) { myCancelButton.setText(text); } @@ -550,7 +559,9 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa myPopup.close(DialogWrapper.CANCEL_EXIT_CODE); } - myPopup = myParentWindow.isShowing() ? new MyDialogWrapper(myParentWindow, myShouldShowCancel) : new MyDialogWrapper(myProject, myShouldShowCancel); + myPopup = myParentWindow.isShowing() + ? new MyDialogWrapper(myParentWindow, myShouldShowCancel) + : new MyDialogWrapper(myProject, myShouldShowCancel); myPopup.setUndecorated(true); SwingUtilities.invokeLater(new Runnable() { @@ -606,7 +617,8 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa catch (GlassPaneDialogWrapperPeer.GlasspanePeerUnavailableException e) { return super.createPeer(parent, canBeParent); } - } else { + } + else { return super.createPeer(parent, canBeParent); } } @@ -620,7 +632,8 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa catch (GlassPaneDialogWrapperPeer.GlasspanePeerUnavailableException e) { return super.createPeer(canBeParent, toolkitModalIfPossible); } - } else { + } + else { return super.createPeer(canBeParent, toolkitModalIfPossible); } } @@ -634,7 +647,8 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa catch (GlassPaneDialogWrapperPeer.GlasspanePeerUnavailableException e) { return super.createPeer(project, canBeParent); } - } else { + } + else { return super.createPeer(project, canBeParent); } } @@ -659,7 +673,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa } @Nullable - protected Border createContentPaneBorder() { + protected Border createContentPaneBorder() { return null; } } @@ -670,7 +684,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa myDialog.setShouldShowBackground(backgroundHandler != null); } - public void setCancelButtonText(String text){ + public void setCancelButtonText(String text) { if (myDialog != null) { myDialog.changeCancelButtonText(text); } @@ -691,7 +705,8 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa if (wnd != null) { // Can be null if just hidden wnd.pack(); } - } else if (myDialog.myPopup != null) { + } + else if (myDialog.myPopup != null) { myDialog.myPopup.validate(); } } diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index d5bb8acb132e..544a4802fd9c 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -12,10 +12,15 @@ reformat.option.selected.text=&Selected text reformat.option.all.files.in.directory=&All files in directory {0} reformat.option.include.subdirectories=&Include subdirectories reformat.option.optimize.imports=&Optimize imports +reformat.progress.file.with.known.name.text=Reformatting {0} +reformat.progress.common.text=Reformatting code... process.optimize.imports=Optimize Imports progress.text.optimizing.imports=Optimizing imports... +progress.reformat.code.prepare=Preparing to reformat +progress.reformat.stage.wrapping.blocks=Preparing... +progress.reformat.stage.processing.blocks=Calculating changes... +progress.reformat.stage.applying.changes=Storing changes... process.reformat.code=Reformat Code -progress.text.reformatting.code=Reformatting code... dialog.reformat.files.title=Reformat Files dialog.reformat.files.optimize.imports.checkbox=&Optimize imports dialog.reformat.files.reformat.selected.files.label=Reformat selected files? From b78167008bdbb800a1df22302439c2049526496a Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 17 Feb 2011 11:20:15 +0300 Subject: [PATCH 27/90] IDEA-65342 Join Lines eats first parameter 1. Made formatting don't setup additional postponed formatting for the changed elements; 2. Corresponding test is added; --- .../DocumentBasedFormattingModel.java | 9 ++++- .../impl/source/codeStyle/CodeEditUtil.java | 36 ++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/DocumentBasedFormattingModel.java b/platform/lang-impl/src/com/intellij/psi/formatter/DocumentBasedFormattingModel.java index ca0295ebca2d..8d01f291fc81 100644 --- a/platform/lang-impl/src/com/intellij/psi/formatter/DocumentBasedFormattingModel.java +++ b/platform/lang-impl/src/com/intellij/psi/formatter/DocumentBasedFormattingModel.java @@ -27,6 +27,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -137,7 +138,13 @@ public class DocumentBasedFormattingModel implements FormattingModel { } public void commitChanges() { - PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + CodeEditUtil.allowToMarkNodesForPostponedFormatting(false); + try { + PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + } + finally { + CodeEditUtil.allowToMarkNodesForPostponedFormatting(true); + } } private int shiftIndentInside(final TextRange elementRange, final int shift) { diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java index b4fd690afdd1..0237d6756ade 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeEditUtil.java @@ -47,6 +47,12 @@ public class CodeEditUtil { private static final Key INDENT_INFO = new Key("INDENT_INFO"); private static final Key REFORMAT_BEFORE_KEY = new Key("REFORMAT_BEFORE_KEY"); private static final Key REFORMAT_KEY = new Key("REFORMAT_KEY"); + private static final ThreadLocal ALLOW_TO_MARK_NODES_TO_REFORMAT = new ThreadLocal() { + @Override + protected Boolean initialValue() { + return Boolean.TRUE; + } + }; public static final Key OUTER_OK = new Key("OUTER_OK"); @@ -430,6 +436,34 @@ public class CodeEditUtil { * @param value true if the element should be reformatted; false otherwise */ public static void markToReformat(final ASTNode node, boolean value) { - node.putCopyableUserData(REFORMAT_KEY, value ? true : null); + if (ALLOW_TO_MARK_NODES_TO_REFORMAT.get()) { + node.putCopyableUserData(REFORMAT_KEY, value ? true : null); + } + } + + /** + * We allow to mark particular {@link ASTNode AST nodes} to be reformatted later (e.g. we may want method definition and calls + * to be reformatted when we perform 'change method signature' refactoring. Hence, we mark corresponding expressions + * to be reformatted). + *

+ * For convenience that is made automatically on AST/PSI level, i.e. every time target element change it automatically marks itself + * to be reformatted. + *

+ * However, there is a possible case that particular element is changed because of formatting, hence, there is no need to mark + * itself for postponed formatting one more time. This method allows to configure allowance of reformat markers processing + * for the calling thread. I.e. this method may be called with 'false' as an argument, hence, all further attempts + * to {@link #markToReformat(ASTNode, boolean) mark node for postponed formatting} will have no effect until current method is + * called with 'true' as an argument. Hence, following usage scenario is expected: + *

    + *
  1. this method is called with 'false' argument;
  2. + *
  3. formatting is performed at dedicated 'try' block;
  4. + *
  5. this method is called with 'false' argument from 'finally' section;
  6. + *
+ * + * @param allow flag that defines if new reformat markers can be added from the current thread + * @see #markToReformat(ASTNode, boolean) + */ + public static void allowToMarkNodesForPostponedFormatting(boolean allow) { + ALLOW_TO_MARK_NODES_TO_REFORMAT.set(allow); } } From cee90781bd2cccfbea4d89965d135a2d6560bb0f Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 17 Feb 2011 11:21:05 +0300 Subject: [PATCH 28/90] IDEA-57891 Reformat file: run under modal progress 1. Added ability to stop formatting; 2. Corrected 'formatting under progress' processing; --- .../psi/formatter/java/JavaFormatterTest.java | 19 +++++++++-- .../src/com/intellij/util/SequentialTask.java | 5 +++ .../intellij/formatting/FormatProcessor.java | 21 ++++++++++-- .../intellij/formatting/FormatterImpl.java | 11 ++++-- .../FormattingProgressIndicatorImpl.java | 34 +++++++++++++------ .../formatting/InitialInfoBuilder.java | 11 +++--- .../openapi/progress/util/ProgressWindow.java | 24 ++++++++++++- 7 files changed, 101 insertions(+), 24 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java index 3ecf5da63e99..8a6ed27ced68 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterTest.java @@ -354,8 +354,14 @@ public class JavaFormatterTest extends AbstractJavaFormatterTest { public void testBraces() throws Exception { final CodeStyleSettings settings = getSettings(); - final String text = "class Foo {\n" + "void foo () {\n" + "if (a) {\n" + "int i = 0;\n" + "}\n" + "}\n" + "}"; - + final String text = + "class Foo {\n" + + "void foo () {\n" + + "if (a) {\n" + + "int i = 0;\n" + + "}\n" + + "}\n" + + "}"; settings.BRACE_STYLE = CodeStyleSettings.END_OF_LINE; settings.METHOD_BRACE_STYLE = CodeStyleSettings.END_OF_LINE; @@ -2199,7 +2205,14 @@ public void testSCR260() throws Exception { getSettings().BRACE_STYLE = CodeStyleSettings.NEXT_LINE_SHIFTED; doTextTest( - "public class ZZZZ \n" + " { \n" + " public ZZZZ() \n" + " { \n" + " if (a){\n" + "foo();}\n" + " } \n" + " }", + "public class ZZZZ \n" + + " { \n" + + " public ZZZZ() \n" + + " { \n" + + " if (a){\n" + + "foo();}\n" + + " } \n" + + " }", "public class ZZZZ\n" + " {\n" + " public ZZZZ()\n" + diff --git a/platform/lang-api/src/com/intellij/util/SequentialTask.java b/platform/lang-api/src/com/intellij/util/SequentialTask.java index 8ba9ff218cb5..96fc7732b123 100644 --- a/platform/lang-api/src/com/intellij/util/SequentialTask.java +++ b/platform/lang-api/src/com/intellij/util/SequentialTask.java @@ -40,4 +40,9 @@ public interface SequentialTask { * @return true if the processing is done; false otherwise */ boolean iteration(); + + /** + * Asks current task to stop the processing (if any). + */ + void stop(); } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java index 02e449313a74..f59a387a9fb4 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java @@ -204,6 +204,13 @@ class FormatProcessor { return myCurrentState.isDone(); } + /** + * Asks current processor to stop any active sequential processing if any. + */ + public void stopSequentialProcessing() { + myCurrentState.stop(); + } + public void formatWithoutRealModifications() { formatWithoutRealModifications(false); } @@ -212,7 +219,7 @@ class FormatProcessor { public void formatWithoutRealModifications(boolean sequentially) { myCurrentState.setNext(new AdjustWhiteSpacesState()); - if (!sequentially) { + if (sequentially) { return; } @@ -1347,10 +1354,13 @@ class FormatProcessor { public FormattingStateId getStateId() { return myStateId; } + + public void stop() { + } protected abstract void doIteration(); protected abstract void prepare(); - + private void shiftStateIfNecessary() { if (isDone() && myNextState != null) { myCurrentState = myNextState; @@ -1522,5 +1532,12 @@ class FormatProcessor { myModel.commitChanges(); } } + + @Override + public void stop() { + if (myIndex > 0) { + myModel.commitChanges(); + } + } } } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java index db50bd3685fc..052a2ca8a559 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java @@ -16,6 +16,7 @@ package com.intellij.formatting; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; @@ -203,7 +204,8 @@ public class FormatterImpl extends FormatterEx */ private void execute(@NotNull SequentialTask task) { disableFormatting(); - if (myProgressIndicator == null || !ApplicationManager.getApplication().isDispatchThread()) { + Application application = ApplicationManager.getApplication(); + if (myProgressIndicator == null || !application.isDispatchThread() || application.isUnitTestMode()) { try { task.prepare(); while (!task.isDone()) { @@ -757,7 +759,12 @@ public class FormatterImpl extends FormatterEx public boolean iteration() { return myDone = myProcessor.iteration(); } - + + @Override + public void stop() { + myProcessor.stopSequentialProcessing(); + } + @NotNull protected abstract FormatProcessor buildProcessor(); } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java index 8ca214e2a78a..6916a1dcedcb 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java @@ -16,6 +16,7 @@ package com.intellij.formatting; import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.ide.IdeBundle; import com.intellij.openapi.command.undo.UndoManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -28,6 +29,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.util.SequentialTask; import com.intellij.util.containers.HashSet; +import com.intellij.util.ui.UIUtil; import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -60,7 +62,7 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma static { ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.WRAPPING_BLOCKS, 500); ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.PROCESSING_BLOCKS, 500); - ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.APPLYING_CHANGES, 3000); + ITERATION_MIN_TIMES_MILLIS.put(FormattingStateId.APPLYING_CHANGES, 1000); assert ITERATION_MIN_TIMES_MILLIS.size() == FormattingStateId.values().length; } @@ -95,7 +97,7 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma private int myModifiedBlocksNumber; public FormattingProgressIndicatorImpl(@Nullable Project project, @NotNull PsiFile file, @NotNull Document document) { - super(project, getTitle(file), false); + super(project, getTitle(file), true); myFile = file.getVirtualFile(); myDocument = document; myFileTextLength = file.getTextLength(); @@ -121,6 +123,11 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma catch (Exception e) { LOG.info("Unexpected exception occurred during reformatting file " + myFile, e); } + finally { + if (myIndicator != null) { + myIndicator.stop(); + } + } } @SuppressWarnings({"SSBasedInspection"}) @@ -130,7 +137,7 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma return; } - SwingUtilities.invokeAndWait(new Runnable() { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { myDocumentModificationStampBefore = myDocument.getModificationStamp(); @@ -143,26 +150,32 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma final Condition condition = lock.newCondition(); myIndicator = indicator; - while (myRunning && !myTask.isDone()) { + while (myRunning && !task.isDone()) { + if (indicator.isCanceled()) { + task.stop(); + break; + } lock.lock(); try { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { - long start = System.currentTimeMillis(); - while (System.currentTimeMillis() - start < ITERATION_MIN_TIMES_MILLIS.get(myLastState)) { - task.iteration(); - } lock.lock(); try { - condition.signal(); + long start = System.currentTimeMillis(); + while (!task.isDone() && System.currentTimeMillis() - start < ITERATION_MIN_TIMES_MILLIS.get(myLastState)) { + task.iteration(); + } } finally { + condition.signal(); lock.unlock(); } } }); - condition.await(); + if (!task.isDone()) { + condition.await(); + } } finally { lock.unlock(); @@ -213,6 +226,7 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma public void beforeApplyingFormatChanges(@NotNull Collection modifiedBlocks) { myBlocksToModifyNumber = modifiedBlocks.size(); updateTextIfNecessary(FormattingStateId.APPLYING_CHANGES); + setCancelText(IdeBundle.message("action.stop")); } @Override diff --git a/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java b/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java index 654affcf01f1..48ddfa3c3e24 100644 --- a/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java +++ b/platform/lang-impl/src/com/intellij/formatting/InitialInfoBuilder.java @@ -99,11 +99,7 @@ class InitialInfoBuilder { State state = myStates.peek(); doIteration(state); - if (myStates.isEmpty()) { - state.wrappedBlock.setIndent((IndentImpl)Indent.getNoneIndent()); - return true; - } - return false; + return myStates.isEmpty(); } /** @@ -196,7 +192,10 @@ class InitialInfoBuilder { wrappedRootBlock.arrangeParentTextRange(); } - if (myRootBlockWrapper == null) myRootBlockWrapper = wrappedRootBlock; + if (myRootBlockWrapper == null) { + myRootBlockWrapper = wrappedRootBlock; + myRootBlockWrapper.setIndent((IndentImpl)Indent.getNoneIndent()); + } boolean blocksMayBeOfInterest = false; if (myPositionOfInterest != -1) { diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index 0b34d680a92a..d2a297431da3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -51,6 +51,13 @@ import java.io.File; public class ProgressWindow extends BlockingProgressIndicator implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressWindow"); + /** + * This constant defines default delay for showing progress dialog (in millis). + * + * @see #setDelayInMillis(int) + */ + public static final int DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS = 300; + private static final int UPDATE_INTERVAL = 50; //msec. 20 frames per second. private MyDialog myDialog; @@ -71,6 +78,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa private boolean myWasShown; private String myProcessId = ""; @Nullable private volatile Runnable myBackgroundHandler; + private int myDelayInMillis = DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS; public ProgressWindow(boolean shouldShowCancel, Project project) { this(shouldShowCancel, false, project); @@ -124,6 +132,20 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa myStarted = true; } + /** + * There is a possible case that many short (in terms of time) progress tasks are executed in a small amount of time. + * Problem: UI blinks and looks ugly if we show progress dialog for every such task (every dialog disappears shortly). + * Solution is to postpone showing progress dialog in assumption that the task may be already finished when it's + * time to show the dialog. + *

+ * Default value is {@link #DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS} + * + * @param delayInMillis new delay time in milliseconds + */ + public void setDelayInMillis(int delayInMillis) { + myDelayInMillis = delayInMillis; + } + private synchronized boolean isStarted() { return myStarted; } @@ -136,7 +158,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa // executed in a small amount of time. Problem: UI blinks and looks ugly if we show progress dialog that disappears shortly // for each of them. Solution is to postpone the tasks of showing progress dialog. Hence, it will not be shown at all // if the task is already finished when the time comes. - Timer timer = new Timer(300, new ActionListener() { + Timer timer = new Timer(myDelayInMillis, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (isRunning()) { From ab784c95c28a66d19dfc952998238bd9812b5458 Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 16 Feb 2011 12:37:09 +0100 Subject: [PATCH 29/90] unchecked generics array creation: in new expressions; detect generic signature in anonymous class creation --- .../impl/analysis/GenericsHighlightUtil.java | 49 +++++++++--- .../impl/analysis/HighlightVisitorImpl.java | 1 + .../UncheckedGenericsArrayCreation.java | 76 +++++++++++++++++++ 3 files changed, 115 insertions(+), 11 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index fae7d6f3c6db..efc3b9807f10 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -1113,7 +1113,7 @@ public class GenericsHighlightUtil { } @Nullable - public static HighlightInfo checkUncheckedGenericsArrayCreation(PsiReferenceExpression referenceExpression, PsiElement resolved){ + public static HighlightInfo checkUncheckedGenericsArrayCreation(PsiJavaCodeReferenceElement referenceExpression, PsiElement resolved){ if (isUncheckedWarning(referenceExpression, resolved, false)) { final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.WARNING, referenceExpression, "Unchecked generics array creation for varargs parameter"); @@ -1123,7 +1123,7 @@ public class GenericsHighlightUtil { return null; } - public static boolean isUncheckedWarning(PsiReferenceExpression expression, PsiElement resolve, boolean ignoreSuppressed) { + public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, PsiElement resolve, boolean ignoreSuppressed) { if (resolve instanceof PsiMethod) { final PsiMethod psiMethod = (PsiMethod)resolve; @@ -1140,12 +1140,31 @@ public class GenericsHighlightUtil { final PsiType componentType = ((PsiEllipsisType)varargParameter.getType()).getComponentType(); if (!isReifiableType(componentType)) { final PsiElement parent = expression.getParent(); - if (parent instanceof PsiMethodCallExpression) { - final PsiExpression[] args = ((PsiMethodCallExpression)parent).getArgumentList().getExpressions(); - for (int i = parametersCount - 1; i < args.length; i++) { - if (!isReifiableType(args[i].getType())){ - return true; + if (parent instanceof PsiCall) { + final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList(); + if (argumentList != null) { + final PsiExpression[] args = argumentList.getExpressions(); + if (args.length == parametersCount) { + final PsiExpression lastArg = args[args.length - 1]; + if (lastArg instanceof PsiReferenceExpression) { + final PsiElement lastArgsResolve = ((PsiReferenceExpression)lastArg).resolve(); + if (lastArgsResolve instanceof PsiParameter) { + if (((PsiParameter)lastArgsResolve).getType() instanceof PsiArrayType) { + return false; + } + } + } else if (lastArg instanceof PsiMethodCallExpression) { + if (lastArg.getType() instanceof PsiArrayType) { + return false; + } + } } + for (int i = parametersCount - 1; i < args.length; i++) { + if (!isReifiableType(args[i].getType())){ + return true; + } + } + return args.length < parametersCount; } } } @@ -1169,14 +1188,22 @@ public class GenericsHighlightUtil { } if (type instanceof PsiClassType) { - final PsiClassType classType = (PsiClassType)type; + final PsiClassType classType = (PsiClassType)PsiUtil.convertAnonymousToBaseType(type); if (classType.isRaw()) { return true; } - if (!classType.hasParameters()) { - return true; + PsiType[] parameters = classType.getParameters(); + + for (PsiType parameter : parameters) { + if (parameter instanceof PsiWildcardType && ((PsiWildcardType)parameter).getBound() == null) { + return true; + } } - return !classType.hasNonTrivialParameters(); + final PsiClass resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolve(); + if (resolved instanceof PsiTypeParameter) { + return false; + } + return parameters.length == 0; } return false; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index a0e24bba2741..57b3c20c7d1a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -686,6 +686,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression)); if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType())); + if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedGenericsArrayCreation(expression.getClassOrAnonymousClassReference(), expression.resolveConstructor())); if (!myHolder.hasErrorResults()) registerConstructorCall(expression); if (!myHolder.hasErrorResults()) visitExpression(expression); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java index 52dcb04f60ca..ab08ae041339 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java @@ -42,4 +42,80 @@ public class Test { final ArrayList list = new ArrayList(); asList(list); } + + public static void join(V[] list) { + Arrays.asList(list); + } +} + +class NoWarngs { + static final SemKey FILE_DESCRIPTION_KEY = SemKey.createKey("FILE_DESCRIPTION_KEY"); + + void f() { + OCM o = + new OCM<>("", true, new Condition(){ + @Override + public boolean val(String s) { + return false; + } + }, Condition.TRUE); + System.out.println(o); + } +} + +class SemKey { + private final String myDebugName; + private final SemKey[] mySupers; + + private SemKey(String debugName, SemKey... supers) { + myDebugName = debugName; + System.out.println(myDebugName); + mySupers = supers; + System.out.println(mySupers); + } + + public static SemKey createKey(String debugName, SemKey... supers) { + return new SemKey(debugName, supers); + } + + public SemKey subKey(String debugName, SemKey... otherSupers) { + if (otherSupers.length == 0) { + return new SemKey(debugName, this); + } + return new SemKey(debugName, append(otherSupers, this)); + } + + public static T[] append(final T[] src, final T element) { + return append(src, element, (Class)src.getClass().getComponentType()); + } + + public static T[] append(T[] src, final T element, Class componentType) { + int length = src.length; + T[] result = (T[])java.lang.reflect.Array.newInstance(componentType, length + 1); + System.arraycopy(src, 0, result, 0, length); + result[length] = element; + return result; + } +} + +interface Condition { + boolean val(T t); + + Condition TRUE = new Condition() { + @Override + public boolean val(Object o) { + return true; + } + }; +} +class OCM { + OCM(T s, boolean b, Condition... c) { + System.out.println(s); + System.out.println(b); + System.out.println(c); + } + + OCM(T s, Condition... c) { + this(s, false, c); + } } \ No newline at end of file From b002ef196e350cb7dc977c41dbd02289969e296c Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 16 Feb 2011 12:42:33 +0100 Subject: [PATCH 30/90] disable unchecked generics array creation in varargs when corresponding fake inspection is disabled --- .../codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index efc3b9807f10..5f90a72fb958 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -1114,6 +1114,8 @@ public class GenericsHighlightUtil { @Nullable public static HighlightInfo checkUncheckedGenericsArrayCreation(PsiJavaCodeReferenceElement referenceExpression, PsiElement resolved){ + final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME); + if (!InspectionProjectProfileManager.getInstance(referenceExpression.getProject()).getInspectionProfile().isToolEnabled(key, referenceExpression)) return null; if (isUncheckedWarning(referenceExpression, resolved, false)) { final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.WARNING, referenceExpression, "Unchecked generics array creation for varargs parameter"); From 84e7a9ae7a353f84965f6fb79b96dfb6ca631cdc Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 16 Feb 2011 20:44:49 +0100 Subject: [PATCH 31/90] unchecked warnings as fair inspection --- .../impl/analysis/GenericsHighlightUtil.java | 200 +---------- .../impl/analysis/HighlightMethodUtil.java | 21 +- .../daemon/impl/analysis/HighlightUtil.java | 5 +- .../impl/analysis/HighlightVisitorImpl.java | 4 - .../daemon/impl/quickfix/GenerifyFileFix.java | 24 +- .../impl/quickfix/VariableArrayTypeFix.java | 11 +- .../daemon/impl/quickfix/VariableTypeFix.java | 11 +- ...ntUncheckedSuppressWarningsInspection.java | 25 +- .../UncheckedWarningLocalInspection.java | 323 +++++++++++++++++- .../UncheckedGenericsArrayCreation.java | 6 +- .../IntersectionTypes.java | 6 +- .../redundantUncheckedVarargs/before3.java | 2 +- .../daemon/LightAdvHighlightingJdk7Test.java | 3 +- 13 files changed, 393 insertions(+), 248 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index 5f90a72fb958..8fddf2096830 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -16,29 +16,18 @@ package com.intellij.codeInsight.daemon.impl.analysis; import com.intellij.codeInsight.AnnotationUtil; -import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.daemon.impl.HighlightInfoType; -import com.intellij.codeInsight.daemon.impl.JavaHightlightInfoTypes; -import com.intellij.codeInsight.daemon.impl.actions.SuppressFix; import com.intellij.codeInsight.daemon.impl.quickfix.*; -import com.intellij.codeInsight.intention.EmptyIntentionAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.intention.QuickFixFactory; -import com.intellij.codeInspection.InspectionProfile; -import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.codeInspection.SuppressManager; -import com.intellij.codeInspection.ex.InspectionManagerEx; -import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; -import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.pom.java.LanguageLevel; -import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; @@ -48,7 +37,6 @@ import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -529,21 +517,7 @@ public class GenericsHighlightUtil { return null; } - //precondition: TypeConversionUtil.isAssignable(lType, rType) || expressionAssignable - public static HighlightInfo checkRawToGenericAssignment(PsiType lType, PsiType rType, @NotNull final PsiElement elementToHighlight) { - if (!PsiUtil.isLanguageLevel5OrHigher(elementToHighlight)) return null; - final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME); - if (!InspectionProjectProfileManager.getInstance(elementToHighlight.getProject()).getInspectionProfile().isToolEnabled(key, - elementToHighlight)) return null; - if (!isRawToGeneric(lType, rType)) return null; - String description = JavaErrorMessages.message("generics.unchecked.assignment", - HighlightUtil.formatType(rType), - HighlightUtil.formatType(lType)); - - return createUncheckedWarning(elementToHighlight, key, description, elementToHighlight); - } - - private static boolean isRawToGeneric(PsiType lType, PsiType rType) { + public static boolean isRawToGeneric(PsiType lType, PsiType rType) { if (lType instanceof PsiPrimitiveType || rType instanceof PsiPrimitiveType) return false; if (lType.equals(rType)) return false; if (lType instanceof PsiArrayType && rType instanceof PsiArrayType) { @@ -628,27 +602,7 @@ public class GenericsHighlightUtil { return false; } - public static HighlightInfo checkUncheckedTypeCast(PsiTypeCastExpression typeCast) { - if (!PsiUtil.isLanguageLevel5OrHigher(typeCast)) return null; - final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME); - if (!InspectionProjectProfileManager.getInstance(typeCast.getProject()).getInspectionProfile().isToolEnabled(key, typeCast)) return null; - final PsiTypeElement typeElement = typeCast.getCastType(); - if (typeElement == null) return null; - final PsiType castType = typeElement.getType(); - final PsiExpression expression = typeCast.getOperand(); - if (expression == null) return null; - final PsiType exprType = expression.getType(); - if (exprType == null) return null; - if (isUncheckedCast(castType, exprType)) { - String description = JavaErrorMessages.message("generics.unchecked.cast", - HighlightUtil.formatType(exprType), - HighlightUtil.formatType(castType)); - return createUncheckedWarning(expression, key, description, typeCast); - } - return null; - } - - private static boolean isUncheckedCast(PsiType castType, PsiType operandType) { + public static boolean isUncheckedCast(PsiType castType, PsiType operandType) { if (TypeConversionUtil.isAssignable(castType, operandType, false)) return false; castType = castType.getDeepComponentType(); @@ -727,74 +681,7 @@ public class GenericsHighlightUtil { ((PsiClassType)rTypeArg).resolve() instanceof PsiTypeParameter; } - public static HighlightInfo checkUncheckedCall(JavaResolveResult resolveResult, PsiCall call) { - if (!PsiUtil.isLanguageLevel5OrHigher(call)) return null; - final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME); - if (!InspectionProjectProfileManager.getInstance(call.getProject()).getInspectionProfile().isToolEnabled(key, call)) return null; - - final PsiMethod method = (PsiMethod)resolveResult.getElement(); - if (method == null) return null; - final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); - final PsiParameter[] parameters = method.getParameterList().getParameters(); - for (final PsiParameter parameter : parameters) { - final PsiType parameterType = parameter.getType(); - if (parameterType.accept(new PsiTypeVisitor() { - public Boolean visitPrimitiveType(PsiPrimitiveType primitiveType) { - return Boolean.FALSE; - } - - public Boolean visitArrayType(PsiArrayType arrayType) { - return arrayType.getComponentType().accept(this); - } - - public Boolean visitClassType(PsiClassType classType) { - PsiClass psiClass = classType.resolve(); - if (psiClass instanceof PsiTypeParameter) { - return substitutor.substitute((PsiTypeParameter)psiClass) == null ? Boolean.TRUE : Boolean.FALSE; - } - PsiType[] parameters = classType.getParameters(); - for (PsiType parameter : parameters) { - if (parameter.accept(this).booleanValue()) return Boolean.TRUE; - - } - return Boolean.FALSE; - } - - public Boolean visitWildcardType(PsiWildcardType wildcardType) { - PsiType bound = wildcardType.getBound(); - if (bound != null) return bound.accept(this); - return Boolean.FALSE; - } - - public Boolean visitEllipsisType(PsiEllipsisType ellipsisType) { - return ellipsisType.getComponentType().accept(this); - } - }).booleanValue()) { - final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); - PsiType type = elementFactory.createType(method.getContainingClass(), substitutor); - String description = JavaErrorMessages.message("generics.unchecked.call.to.member.of.raw.type", - HighlightUtil.formatMethod(method), - HighlightUtil.formatType(type)); - PsiElement element = call instanceof PsiMethodCallExpression - ? ((PsiMethodCallExpression)call).getMethodExpression() - : call; - return createUncheckedWarning(call, key, description, element); - } - } - return null; - } - - private static HighlightInfo createUncheckedWarning(PsiElement context, HighlightDisplayKey key, String description, PsiElement elementToHighlight) { - final InspectionProfile inspectionProfile = - InspectionProjectProfileManager.getInstance(context.getProject()).getInspectionProfile(); - final LocalInspectionTool tool = - ((LocalInspectionToolWrapper)inspectionProfile.getInspectionTool(UncheckedWarningLocalInspection.SHORT_NAME, elementToHighlight)).getTool(); - if (InspectionManagerEx.inspectionResultSuppressed(context, tool)) return null; - HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(JavaHightlightInfoTypes.UNCHECKED_WARNING, elementToHighlight, description); - QuickFixAction.registerQuickFixAction(highlightInfo, new GenerifyFileFix(elementToHighlight.getContainingFile()), key); - return highlightInfo; - } - + @Nullable public static HighlightInfo checkForeachLoopParameterType(PsiForeachStatement statement) { final PsiParameter parameter = statement.getIterationParameter(); final PsiExpression expression = statement.getIteratedValue(); @@ -811,14 +698,12 @@ public class GenericsHighlightUtil { HighlightInfo highlightInfo = HighlightUtil.checkAssignability(parameterType, itemType, null, new TextRange(start, end)); if (highlightInfo != null) { HighlightUtil.registerChangeVariableTypeFixes(parameter, itemType, highlightInfo); - } else { - highlightInfo = checkRawToGenericAssignment(parameterType, itemType, statement.getIterationParameter()); } return highlightInfo; } @Nullable - private static PsiType getCollectionItemType(PsiExpression expression) { + public static PsiType getCollectionItemType(PsiExpression expression) { final PsiType type = expression.getType(); if (type == null) return null; if (type instanceof PsiArrayType) { @@ -1112,27 +997,11 @@ public class GenericsHighlightUtil { } } - @Nullable - public static HighlightInfo checkUncheckedGenericsArrayCreation(PsiJavaCodeReferenceElement referenceExpression, PsiElement resolved){ - final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME); - if (!InspectionProjectProfileManager.getInstance(referenceExpression.getProject()).getInspectionProfile().isToolEnabled(key, referenceExpression)) return null; - if (isUncheckedWarning(referenceExpression, resolved, false)) { - final HighlightInfo highlightInfo = - HighlightInfo.createHighlightInfo(HighlightInfoType.WARNING, referenceExpression, "Unchecked generics array creation for varargs parameter"); - QuickFixAction.registerQuickFixAction(highlightInfo, new SuppressFix("unchecked")); - return highlightInfo; - } - return null; - } - - public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, PsiElement resolve, boolean ignoreSuppressed) { + public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, PsiElement resolve) { if (resolve instanceof PsiMethod) { final PsiMethod psiMethod = (PsiMethod)resolve; final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(expression); - if (!ignoreSuppressed) { - if (SuppressManager.getInstance().isSuppressedFor(expression, "unchecked")) return false; - } if (psiMethod.isVarArgs()) { if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_7) || !AnnotationUtil.isAnnotated(psiMethod, "java.lang.SafeVarargs", false)) { @@ -1282,29 +1151,6 @@ public class GenericsHighlightUtil { return list; } - public static HighlightInfo checkGenericCallWithRawArguments(JavaResolveResult resolveResult, PsiCallExpression callExpression) { - final PsiMethod method = (PsiMethod)resolveResult.getElement(); - if (method == null) return null; - final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); - final PsiExpressionList argumentList = callExpression.getArgumentList(); - if (argumentList == null) return null; - final PsiExpression[] expressions = argumentList.getExpressions(); - final PsiParameter[] parameters = method.getParameterList().getParameters(); - if (parameters.length != 0) { - for (int i = 0; i < expressions.length; i++) { - PsiParameter parameter = parameters[Math.min(i, parameters.length - 1)]; - final PsiExpression expression = expressions[i]; - final PsiType parameterType = substitutor.substitute(parameter.getType()); - final PsiType expressionType = substitutor.substitute(expression.getType()); - if (expressionType != null) { - final HighlightInfo highlightInfo = checkRawToGenericAssignment(parameterType, expressionType, expression); - if (highlightInfo != null) return highlightInfo; - } - } - } - return null; - } - public static HighlightInfo checkParametersOnRaw(PsiReferenceParameterList refParamList) { if (refParamList.getTypeArguments().length == 0) return null; JavaResolveResult resolveResult = null; @@ -1363,42 +1209,6 @@ public class GenericsHighlightUtil { return null; } - public static HighlightInfo checkUncheckedOverriding (PsiMethod overrider, final List superMethodSignatures) { - if (!PsiUtil.isLanguageLevel5OrHigher(overrider)) return null; - final HighlightDisplayKey key = HighlightDisplayKey.find(UncheckedWarningLocalInspection.SHORT_NAME); - final InspectionProfile inspectionProfile = - InspectionProjectProfileManager.getInstance(overrider.getProject()).getInspectionProfile(); - if (!inspectionProfile.isToolEnabled(key, overrider)) return null; - final LocalInspectionTool tool = - ((LocalInspectionToolWrapper)inspectionProfile.getInspectionTool(UncheckedWarningLocalInspection.SHORT_NAME, overrider)).getTool(); - if (InspectionManagerEx.inspectionResultSuppressed(overrider, tool)) return null; - final MethodSignature signature = overrider.getSignature(PsiSubstitutor.EMPTY); - for (MethodSignatureBackedByPsiMethod superSignature : superMethodSignatures) { - PsiMethod baseMethod = superSignature.getMethod(); - PsiSubstitutor substitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(signature, superSignature); - if (substitutor == null) substitutor = superSignature.getSubstitutor(); - if (PsiUtil.isRawSubstitutor(baseMethod, superSignature.getSubstitutor())) continue; - final PsiType baseReturnType = substitutor.substitute(baseMethod.getReturnType()); - final PsiType overriderReturnType = overrider.getReturnType(); - if (baseReturnType == null || overriderReturnType == null) return null; - if (isRawToGeneric(baseReturnType, overriderReturnType)) { - final String message = JavaErrorMessages.message("unchecked.overriding.incompatible.return.type", - HighlightUtil.formatType(overriderReturnType), - HighlightUtil.formatType(baseReturnType)); - - final PsiTypeElement returnTypeElement = overrider.getReturnTypeElement(); - LOG.assertTrue(returnTypeElement != null); - final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(JavaHightlightInfoTypes.UNCHECKED_WARNING, returnTypeElement, message); - QuickFixAction.registerQuickFixAction(highlightInfo, - new EmptyIntentionAction(JavaErrorMessages.message("unchecked.overriding")), - key); - - return highlightInfo; - } - } - return null; - } - public static HighlightInfo checkEnumMustNotBeLocal(final PsiClass aClass) { if (!aClass.isEnum()) return null; PsiElement parent = aClass.getParent(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java index a68745e64ce9..a1609e04d8be 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java @@ -317,13 +317,6 @@ public class HighlightMethodUtil { if (element instanceof PsiMethod && resolveResult.isValidResult()) { TextRange fixRange = getFixRange(methodCall); highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange); - - if (highlightInfo == null) { - highlightInfo = GenericsHighlightUtil.checkUncheckedCall(resolveResult, methodCall); - } - if (highlightInfo == null) { - highlightInfo = GenericsHighlightUtil.checkGenericCallWithRawArguments(resolveResult, methodCall); - } } else { PsiMethod resolvedMethod = null; @@ -1271,11 +1264,7 @@ public class HighlightMethodUtil { ChangeStringLiteralToCharInMethodCallFix.registerFixes(constructors, constructorCall, info); } else { - HighlightInfo highlightInfo = GenericsHighlightUtil.checkUncheckedCall(result, constructorCall); - if (highlightInfo != null) { - holder.add(highlightInfo); - return; - } + HighlightInfo highlightInfo; if (constructorCall instanceof PsiNewExpression) { highlightInfo = GenericsHighlightUtil.checkReferenceTypeArgumentList(constructor, ((PsiNewExpression)constructorCall).getTypeArgumentList(), @@ -1284,13 +1273,7 @@ public class HighlightMethodUtil { holder.add(highlightInfo); return; } - highlightInfo = GenericsHighlightUtil.checkGenericCallWithRawArguments(result, (PsiCallExpression)constructorCall); - if (highlightInfo != null) { - holder.add(highlightInfo); - } - //if (PsiUtil.isLanguageLevel7OrHigher(constructorCall)) { - // // todo[anna] check if not diamond - apply corresponding fix - //} + } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 9002d4678cd5..0dc9884a9207 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -459,8 +459,7 @@ public class HighlightUtil { if (rType == null || lType == null || TypeConversionUtil.isAssignable(lType, rType)) return null; } else if (TypeConversionUtil.areTypesAssignmentCompatible(lType, expression)) { - if (lType == null || rType == null) return null; - return GenericsHighlightUtil.checkRawToGenericAssignment(lType, rType, expression); + return null; } if (rType == null) { rType = expression.getType(); @@ -1131,7 +1130,7 @@ public class HighlightUtil { return null; } - private static PsiType sameType(PsiExpression[] expressions) { + public static PsiType sameType(PsiExpression[] expressions) { PsiType type = null; for (PsiExpression expression : expressions) { final PsiType currentType; diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 57b3c20c7d1a..e4e7d8ebf7c3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -635,7 +635,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodIncompatibleThrows(methodSignature, superMethodSignatures, true, method.getContainingClass())); if (!method.hasModifierProperty(PsiModifier.STATIC)) { if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodWeakerPrivileges(methodSignature, superMethodSignatures, true)); - if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedOverriding(method, superMethodSignatures)); if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkMethodOverridesFinal(methodSignature, superMethodSignatures)); } } @@ -686,7 +685,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumInstantiation(expression)); if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkGenericArrayCreation(expression, expression.getType())); - if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedGenericsArrayCreation(expression.getClassOrAnonymousClassReference(), expression.resolveConstructor())); if (!myHolder.hasErrorResults()) registerConstructorCall(expression); if (!myHolder.hasErrorResults()) visitExpression(expression); @@ -837,7 +835,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh if (!myHolder.hasErrorResults()) myHolder.add(HighlightMethodUtil.checkConstructorCallMustBeFirstStatement(expression)); if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkAccessStaticFieldFromEnumConstructor(expression, result)); if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkClassReferenceAfterQualifier(expression, resolved)); - if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedGenericsArrayCreation(expression, resolved)); } @Override public void visitReferenceList(PsiReferenceList list) { @@ -918,7 +915,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh @Override public void visitTypeCastExpression(PsiTypeCastExpression typeCast) { super.visitTypeCastExpression(typeCast); if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast)); - if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkUncheckedTypeCast(typeCast)); } @Override public void visitTypeParameterList(PsiTypeParameterList list) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java index 3276949bb404..11ed68014b75 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GenerifyFileFix.java @@ -18,14 +18,19 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.CodeInsightUtilBase; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.refactoring.actions.TypeCookAction; import org.jetbrains.annotations.NotNull; -public class GenerifyFileFix implements IntentionAction { +public class GenerifyFileFix implements IntentionAction, LocalQuickFix { private final PsiFile myFile; public GenerifyFileFix(PsiFile file) { @@ -37,11 +42,28 @@ public class GenerifyFileFix implements IntentionAction { return QuickFixBundle.message("generify.text", myFile.getName()); } + @NotNull + @Override + public String getName() { + return getText(); + } + @NotNull public String getFamilyName() { return QuickFixBundle.message("generify.family"); } + @Override + public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { + if (isAvailable(project, null, null)) { + new WriteCommandAction(project) { + protected void run(Result result) throws Throwable { + invoke(project, FileEditorManager.getInstance(project).getSelectedTextEditor(), descriptor.getPsiElement().getContainingFile()); + } + }.execute(); + } + } + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return myFile.isValid() && PsiManager.getInstance(project).isInProject(myFile); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java index 4059dafa7a74..4ee0823b3a1c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.IntentionAndQuickFixAction; import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -29,7 +30,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class VariableArrayTypeFix implements IntentionAction { +public class VariableArrayTypeFix extends IntentionAndQuickFixAction { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.VariableArrayTypeFix"); private final PsiVariable myVariable; @@ -93,12 +94,15 @@ public class VariableArrayTypeFix implements IntentionAction { } @NotNull - public String getText() { + @Override + public String getName() { return myTargetType.equals(myVariable.getType()) && myNewExpression != null ? QuickFixBundle.message("change.new.operator.type.text", getNewText(), myTargetType.getCanonicalText(), "") : QuickFixBundle.message("fix.variable.type.text", myVariable.getName(), myTargetType.getCanonicalText()); } + + @NotNull public String getFamilyName() { return myTargetType.equals(myVariable.getType()) && myNewExpression != null ? @@ -113,7 +117,8 @@ public class VariableArrayTypeFix implements IntentionAction { && myInitializer.isValid(); } - public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException { + @Override + public void applyFix(Project project, PsiFile file, @Nullable Editor editor) { if (!CodeInsightUtilBase.prepareFileForWrite(myVariable.getContainingFile())) return; try { final PsiElementFactory factory = JavaPsiFacade.getInstance(file.getProject()).getElementFactory(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java index 934505dbf443..9d570812deaf 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.IntentionAndQuickFixAction; import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -27,8 +28,9 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class VariableTypeFix implements IntentionAction { +public class VariableTypeFix extends IntentionAndQuickFixAction { static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.VariableTypeFix"); private final PsiVariable myVariable; @@ -39,8 +41,10 @@ public class VariableTypeFix implements IntentionAction { myReturnType = toReturn != null ? GenericsUtil.getVariableTypeByExpressionType(toReturn) : null; } + @NotNull - public String getText() { + @Override + public String getName() { return QuickFixBundle.message("fix.variable.type.text", getVariable().getName(), getReturnType().getCanonicalText()); @@ -61,7 +65,8 @@ public class VariableTypeFix implements IntentionAction { && !TypeConversionUtil.isVoidType(getReturnType()); } - public void invoke(@NotNull Project project, Editor editor, PsiFile file) { + @Override + public void applyFix(Project project, PsiFile file, @Nullable Editor editor) { if (!CodeInsightUtilBase.prepareFileForWrite(getVariable().getContainingFile())) return; try { getVariable().normalizeDeclaration(); diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantUncheckedSuppressWarningsInspection.java b/java/java-impl/src/com/intellij/codeInspection/RedundantUncheckedSuppressWarningsInspection.java index 11fe84b84ac5..a63a9b6f99ca 100644 --- a/java/java-impl/src/com/intellij/codeInspection/RedundantUncheckedSuppressWarningsInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/RedundantUncheckedSuppressWarningsInspection.java @@ -17,7 +17,9 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.daemon.GroupNames; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil; +import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; @@ -105,8 +107,8 @@ public class RedundantUncheckedSuppressWarningsInspection extends BaseJavaLocalI } private static void checkIfSafeToRemoveWarning(PsiElement suppressElement, PsiElement placeToCheckWarningsIn, ProblemsHolder holder) { - final HashSet warningsElements = new HashSet(); - collectUncheckedWarnings(placeToCheckWarningsIn, true, warningsElements); + final HashSet warningsElements = new HashSet(); + collectUncheckedWarnings(placeToCheckWarningsIn, warningsElements); if (warningsElements.isEmpty()) { final int uncheckedIdx = suppressElement.getText().indexOf(RemoveUncheckedWarningFix.UNCHECKED); holder.registerProblem(suppressElement, @@ -115,14 +117,19 @@ public class RedundantUncheckedSuppressWarningsInspection extends BaseJavaLocalI } } - public static void collectUncheckedWarnings(final PsiElement place, final boolean ignoreSuppressed, final Collection warningsElements) { - place.accept(new JavaRecursiveElementVisitor() { - @Override - public void visitReferenceExpression(PsiReferenceExpression expression) { - super.visitReferenceExpression(expression); - if (GenericsHighlightUtil.isUncheckedWarning(expression, expression.resolve(), ignoreSuppressed)) { - warningsElements.add(expression); + public static void collectUncheckedWarnings(final PsiElement place, final Collection warningsElements) { + final UncheckedWarningLocalInspection.UncheckedWarningsVisitor visitor = + new UncheckedWarningLocalInspection.UncheckedWarningsVisitor(false) { + @Override + protected void registerProblem(String message, PsiElement psiElement, LocalQuickFix... quickFix) { + warningsElements.add(psiElement); } + }; + place.accept(new JavaRecursiveElementVisitor(){ + @Override + public void visitElement(PsiElement element) { + super.visitElement(element); + element.accept(visitor); } }); } diff --git a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java index 6d6657fad91c..7cb7f5eed2ea 100644 --- a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java @@ -16,20 +16,38 @@ package com.intellij.codeInspection.uncheckedWarnings; -import com.intellij.codeInspection.BaseJavaLocalInspectionTool; -import com.intellij.codeInspection.InspectionsBundle; +import com.intellij.codeInsight.daemon.JavaErrorMessages; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; +import com.intellij.codeInsight.daemon.impl.quickfix.GenerifyFileFix; +import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction; +import com.intellij.codeInsight.daemon.impl.quickfix.VariableArrayTypeFix; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.QuickFixFactory; +import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider; +import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.UnfairLocalInspectionTool; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.psi.*; +import com.intellij.psi.util.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; /** * User: anna * Date: 17-Feb-2006 */ -public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool implements UnfairLocalInspectionTool { +public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool { @NonNls public static final String SHORT_NAME = "UNCHECKED_WARNING"; public static final String DISPLAY_NAME = InspectionsBundle.message("unchecked.warning"); @NonNls public static final String ID = "unchecked"; + private static final Logger LOG = Logger.getInstance("#" + UncheckedWarningLocalInspection.class); @NotNull public String getGroupDisplayName() { @@ -56,4 +74,303 @@ public class UncheckedWarningLocalInspection extends BaseJavaLocalInspectionTool public boolean isEnabledByDefault() { return true; } + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) { + return new UncheckedWarningsVisitor(isOnTheFly){ + @Override + protected void registerProblem(String message, PsiElement psiElement, LocalQuickFix... quickFix) { + holder.registerProblem(psiElement, message, quickFix); + } + }; + } + + public static abstract class UncheckedWarningsVisitor extends JavaElementVisitor { + private final boolean myOnTheFly; + + public UncheckedWarningsVisitor(boolean onTheFly) { + myOnTheFly = onTheFly; + } + + protected abstract void registerProblem(String message, PsiElement psiElement, LocalQuickFix... quickFix); + + + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return; + if (GenericsHighlightUtil.isUncheckedWarning(expression, expression.resolve())) { + registerProblem("Unchecked generics array creation for varargs parameter", expression, null); + } + } + + @Override + public void visitNewExpression(PsiNewExpression expression) { + super.visitNewExpression(expression); + if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return; + final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference(); + if (GenericsHighlightUtil.isUncheckedWarning(classReference, expression.resolveConstructor())) { + registerProblem("Unchecked generics array creation for varargs parameter", classReference, null); + } + } + + @Override + public void visitTypeCastExpression(PsiTypeCastExpression expression) { + super.visitTypeCastExpression(expression); + if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return; + final PsiTypeElement typeElement = expression.getCastType(); + if (typeElement == null) return; + final PsiType castType = typeElement.getType(); + final PsiExpression operand = expression.getOperand(); + if (operand == null) return; + final PsiType exprType = operand.getType(); + if (exprType == null) return; + if (!TypeConversionUtil.areTypesConvertible(exprType, castType)) return; + if (GenericsHighlightUtil.isUncheckedCast(castType, exprType)) { + final String description = + JavaErrorMessages.message("generics.unchecked.cast", HighlightUtil.formatType(exprType), HighlightUtil.formatType(castType)); + registerProblem(description, expression, myOnTheFly ? new GenerifyFileFix(operand.getContainingFile()) : null); + } + } + + @Override + public void visitCallExpression(PsiCallExpression callExpression) { + super.visitCallExpression(callExpression); + if (!PsiUtil.isLanguageLevel5OrHigher(callExpression)) return; + final JavaResolveResult result = callExpression.resolveMethodGenerics(); + final String description = getUncheckedCallDescription(result); + if (description != null) { + registerProblem(description, callExpression instanceof PsiMethodCallExpression + ? ((PsiMethodCallExpression)callExpression).getMethodExpression() + : callExpression, myOnTheFly ? new GenerifyFileFix(callExpression.getContainingFile()) : null); + } + else { + final PsiSubstitutor substitutor = result.getSubstitutor(); + final PsiExpressionList argumentList = callExpression.getArgumentList(); + if (argumentList != null) { + final PsiMethod method = (PsiMethod)result.getElement(); + if (method != null) { + final PsiExpression[] expressions = argumentList.getExpressions(); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + if (parameters.length != 0) { + for (int i = 0; i < expressions.length; i++) { + PsiParameter parameter = parameters[Math.min(i, parameters.length - 1)]; + final PsiExpression expression = expressions[i]; + final PsiType parameterType = substitutor.substitute(parameter.getType()); + final PsiType expressionType = substitutor.substitute(expression.getType()); + if (expressionType != null) { + checkRawToGenericsAssignment(expression, parameterType, expressionType, true, myOnTheFly ? new GenerifyFileFix(expression.getContainingFile()) : null); + } + } + } + } + } + } + } + + @Override + public void visitVariable(PsiVariable variable) { + super.visitVariable(variable); + if (!PsiUtil.isLanguageLevel5OrHigher(variable)) return; + PsiExpression initializer = variable.getInitializer(); + if (initializer == null || initializer instanceof PsiArrayInitializerExpression) return; + final PsiType initializerType = initializer.getType(); + checkRawToGenericsAssignment(initializer, variable.getType(), initializerType, true, myOnTheFly ? getChangeVariableTypeFixes(variable, initializerType) : null); + } + + @Override + public void visitForeachStatement(PsiForeachStatement statement) { + super.visitForeachStatement(statement); + if (!PsiUtil.isLanguageLevel5OrHigher(statement)) return; + final PsiParameter parameter = statement.getIterationParameter(); + final PsiType parameterType = parameter.getType(); + final PsiType itemType = GenericsHighlightUtil.getCollectionItemType(statement.getIteratedValue()); + if (!PsiUtil.isLanguageLevel5OrHigher(statement)) return; + checkRawToGenericsAssignment(parameter, parameterType, itemType, true, myOnTheFly ? getChangeVariableTypeFixes(parameter, itemType) : null); + } + + @Override + public void visitAssignmentExpression(PsiAssignmentExpression expression) { + super.visitAssignmentExpression(expression); + if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return; + if (!"=".equals(expression.getOperationSign().getText())) return; + PsiExpression lExpr = expression.getLExpression(); + PsiExpression rExpr = expression.getRExpression(); + if (rExpr == null) return; + PsiType lType = lExpr.getType(); + PsiType rType = rExpr.getType(); + if (rType == null) return; + PsiVariable leftVar = null; + if (lExpr instanceof PsiReferenceExpression) { + PsiElement element = ((PsiReferenceExpression)lExpr).resolve(); + if (element instanceof PsiVariable) { + leftVar = (PsiVariable)element; + } + } + checkRawToGenericsAssignment(rExpr, lType, rType, true, myOnTheFly && leftVar != null ? getChangeVariableTypeFixes(leftVar, rType) : null); + } + + @Override + public void visitArrayInitializerExpression(PsiArrayInitializerExpression arrayInitializer) { + super.visitArrayInitializerExpression(arrayInitializer); + if (!PsiUtil.isLanguageLevel5OrHigher(arrayInitializer)) return; + final PsiType type = arrayInitializer.getType(); + if (!(type instanceof PsiArrayType)) return; + final PsiType componentType = ((PsiArrayType)type).getComponentType(); + + + boolean arrayTypeFixChecked = false; + VariableArrayTypeFix fix = null; + + final PsiExpression[] initializers = arrayInitializer.getInitializers(); + for (PsiExpression expression : initializers) { + final PsiType itemType = expression.getType(); + + if (itemType == null) continue; + if (!TypeConversionUtil.isAssignable(componentType, itemType)) continue; + if (GenericsHighlightUtil.isRawToGeneric(componentType, itemType)) { + String description = JavaErrorMessages.message("generics.unchecked.assignment", + HighlightUtil.formatType(itemType), + HighlightUtil.formatType(componentType)); + if (!arrayTypeFixChecked) { + final PsiType checkResult = HighlightUtil.sameType(initializers); + fix = checkResult != null ? new VariableArrayTypeFix(arrayInitializer, checkResult) : null; + arrayTypeFixChecked = true; + } + + if (fix != null) { + registerProblem(description, expression, (LocalQuickFix)fix); + } + } + } + } + + private void checkRawToGenericsAssignment(PsiElement parameter, + PsiType parameterType, + PsiType itemType, + boolean checkAssignability, + final LocalQuickFix... quickFix) { + if (parameterType == null || itemType == null) return; + if (checkAssignability && !TypeConversionUtil.isAssignable(parameterType, itemType)) return; + if (GenericsHighlightUtil.isRawToGeneric(parameterType, itemType)) { + String description = JavaErrorMessages.message("generics.unchecked.assignment", + HighlightUtil.formatType(itemType), + HighlightUtil.formatType(parameterType)); + registerProblem(description, parameter, quickFix); + } + } + + @Override + public void visitMethod(PsiMethod method) { + super.visitMethod(method); + if (!PsiUtil.isLanguageLevel5OrHigher(method)) return; + if (!method.isConstructor()) { + List superMethodSignatures = method.getHierarchicalMethodSignature().getSuperSignatures(); + if (!superMethodSignatures.isEmpty() && !method.hasModifierProperty(PsiModifier.STATIC)) { + final MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY); + for (MethodSignatureBackedByPsiMethod superSignature : superMethodSignatures) { + PsiMethod baseMethod = superSignature.getMethod(); + PsiSubstitutor substitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(signature, superSignature); + if (substitutor == null) substitutor = superSignature.getSubstitutor(); + if (PsiUtil.isRawSubstitutor(baseMethod, superSignature.getSubstitutor())) continue; + final PsiType baseReturnType = substitutor.substitute(baseMethod.getReturnType()); + final PsiType overriderReturnType = method.getReturnType(); + if (baseReturnType == null || overriderReturnType == null) return; + if (GenericsHighlightUtil.isRawToGeneric(baseReturnType, overriderReturnType)) { + final String message = JavaErrorMessages.message("unchecked.overriding.incompatible.return.type", + HighlightUtil.formatType(overriderReturnType), + HighlightUtil.formatType(baseReturnType)); + + final PsiTypeElement returnTypeElement = method.getReturnTypeElement(); + LOG.assertTrue(returnTypeElement != null); + registerProblem(message, returnTypeElement); + } + } + } + } + } + + @Override + public void visitReturnStatement(PsiReturnStatement statement) { + super.visitReturnStatement(statement); + if (!PsiUtil.isLanguageLevel5OrHigher(statement)) return; + final PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class); + if (method != null) { + final PsiType returnType = method.getReturnType(); + if (returnType != null && returnType != PsiType.VOID) { + final PsiExpression returnValue = statement.getReturnValue(); + if (returnValue != null) { + final PsiType valueType = returnValue.getType(); + if (valueType != null) { + checkRawToGenericsAssignment(returnValue, returnType, valueType, + false, + (LocalQuickFix)QuickFixFactory.getInstance().createMethodReturnFix(method, valueType, true)); + } + } + } + } + } + + + @Nullable + public static String getUncheckedCallDescription(JavaResolveResult resolveResult) { + final PsiMethod method = (PsiMethod)resolveResult.getElement(); + if (method == null) return null; + final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + final PsiParameter[] parameters = method.getParameterList().getParameters(); + for (final PsiParameter parameter : parameters) { + final PsiType parameterType = parameter.getType(); + if (parameterType.accept(new PsiTypeVisitor() { + public Boolean visitPrimitiveType(PsiPrimitiveType primitiveType) { + return Boolean.FALSE; + } + + public Boolean visitArrayType(PsiArrayType arrayType) { + return arrayType.getComponentType().accept(this); + } + + public Boolean visitClassType(PsiClassType classType) { + PsiClass psiClass = classType.resolve(); + if (psiClass instanceof PsiTypeParameter) { + return substitutor.substitute((PsiTypeParameter)psiClass) == null ? Boolean.TRUE : Boolean.FALSE; + } + PsiType[] parameters = classType.getParameters(); + for (PsiType parameter : parameters) { + if (parameter.accept(this).booleanValue()) return Boolean.TRUE; + } + return Boolean.FALSE; + } + + public Boolean visitWildcardType(PsiWildcardType wildcardType) { + PsiType bound = wildcardType.getBound(); + if (bound != null) return bound.accept(this); + return Boolean.FALSE; + } + + public Boolean visitEllipsisType(PsiEllipsisType ellipsisType) { + return ellipsisType.getComponentType().accept(this); + } + }).booleanValue()) { + final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); + PsiType type = elementFactory.createType(method.getContainingClass(), substitutor); + return JavaErrorMessages.message("generics.unchecked.call.to.member.of.raw.type", + HighlightUtil.formatMethod(method), + HighlightUtil.formatType(type)); + } + } + return null; + } + } + + public static LocalQuickFix[] getChangeVariableTypeFixes(PsiVariable parameter, PsiType itemType) { + final List result = new ArrayList(); + for (ChangeVariableTypeQuickFixProvider fixProvider : Extensions.getExtensions(ChangeVariableTypeQuickFixProvider.EP_NAME)) { + for (IntentionAction action : fixProvider.getFixes(parameter, itemType)) { + if (action instanceof LocalQuickFix) { + result.add((LocalQuickFix)action); + } + } + } + return result.toArray(new LocalQuickFix[result.size()]); + } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java index ab08ae041339..06ff29ce7b48 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java @@ -86,12 +86,12 @@ class SemKey { } public static T[] append(final T[] src, final T element) { - return append(src, element, (Class)src.getClass().getComponentType()); + return append(src, element, (Class)src.getClass().getComponentType()); } public static T[] append(T[] src, final T element, Class componentType) { int length = src.length; - T[] result = (T[])java.lang.reflect.Array.newInstance(componentType, length + 1); + T[] result = (T[])java.lang.reflect.Array.newInstance(componentType, length + 1); System.arraycopy(src, 0, result, 0, length); result[length] = element; return result; @@ -118,4 +118,4 @@ class OCM { OCM(T s, Condition... c) { this(s, false, c); } -} \ No newline at end of file +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IntersectionTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IntersectionTypes.java index 863890a701b6..3316c0d83386 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IntersectionTypes.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IntersectionTypes.java @@ -8,7 +8,7 @@ class Test { } void foo() { - List> l = this.asList(String.class, Integer.class); + List> l = this.asList(String.class, Integer.class); l.size(); List objects = this.asList(new String(), new Integer(0)); objects.size(); @@ -131,7 +131,7 @@ class IDEADEV25515 { public static final List> SIMPLE_TYPES = -asList(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/ +asList(String.class, Integer.class ,Long.class, Double.class, /*Date.class,*/ Boolean.class, Boolean.TYPE /*,String[].class */ /*,BigDecimal.class*/); @@ -162,4 +162,4 @@ public class MaximalType { } class M extends MaximalType implements L{} class M2 extends MaximalType implements L{} -///////////// \ No newline at end of file +///////////// diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before3.java index f5504c6e31eb..8200d154a64c 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before3.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/redundantUncheckedVarargs/before3.java @@ -9,7 +9,7 @@ public class Test { void foo() { //noinspection unchecked - foo(new ArrayList()).addAll(Arrays.asList(new ArrayList); + foo(new ArrayList()).addAll(Arrays.asList(new ArrayList())); } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java index a4ab1b0aa8e6..dcb332113c87 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/LightAdvHighlightingJdk7Test.java @@ -6,6 +6,7 @@ import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.codeInspection.reference.EntryPoint; import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.extensions.ExtensionPoint; @@ -30,7 +31,7 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase { @Override protected LocalInspectionTool[] configureLocalInspectionTools() { - return new LocalInspectionTool[]{new UnusedSymbolLocalInspection()}; + return new LocalInspectionTool[]{new UnusedSymbolLocalInspection(), new UncheckedWarningLocalInspection()}; } public void testDuplicateAnnotations() throws Exception { From 63658f8e26735977ab187564d96d69bcf6eb08e2 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 10 Feb 2011 16:14:41 +0300 Subject: [PATCH 32/90] reasonable defaults --- .../execution/process/CommandLineArgumentsProvider.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java b/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java index 4bd59d27ff5d..10ce65497c9d 100644 --- a/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java +++ b/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java @@ -17,8 +17,10 @@ package com.intellij.execution.process; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.Map; /** @@ -28,12 +30,12 @@ public abstract class CommandLineArgumentsProvider { /** * @return Commands to execute (one command corresponds to one add argument) */ - public abstract String[] getArguments(); + public String[] getArguments() { return ArrayUtil.EMPTY_STRING_ARRAY; } - public abstract boolean passParentEnvs(); + public boolean passParentEnvs() { return false; } @Nullable - public abstract Map getAdditionalEnvs(); + public Map getAdditionalEnvs() { return Collections.emptyMap(); } public String getCommandLineString() { From 04436678cb0d987e8ee2baf4cf4f374e5f97fd31 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Thu, 10 Feb 2011 16:15:40 +0300 Subject: [PATCH 33/90] reasonable defaults --- .../execution/process/CommandLineArgumentsProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java b/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java index 10ce65497c9d..f708e6a6c553 100644 --- a/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java +++ b/platform/platform-api/src/com/intellij/execution/process/CommandLineArgumentsProvider.java @@ -26,7 +26,7 @@ import java.util.Map; /** * @author Roman.Chernyatchik, oleg */ -public abstract class CommandLineArgumentsProvider { +public class CommandLineArgumentsProvider { /** * @return Commands to execute (one command corresponds to one add argument) */ From 47ea1bee5e7edcfae69e99013f572c6b49cfc025 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 14 Feb 2011 16:58:08 +0300 Subject: [PATCH 34/90] Roo console initial --- .../execution/runners/ConsoleExecuteActionHandler.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java index ac214de42679..6f4571eb3502 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/ConsoleExecuteActionHandler.java @@ -57,11 +57,15 @@ public class ConsoleExecuteActionHandler { } public void processLine(String line) { + sendLine(line + "\n"); + } + + public void sendLine(String line) { //final Charset charset = myProcessHandler.getCharset(); final OutputStream outputStream = myProcessHandler.getProcessInput(); try { //byte[] bytes = (line + "\n").getBytes(charset.name()); - byte[] bytes = (line + "\n").getBytes(); + byte[] bytes = line.getBytes(); outputStream.write(bytes); outputStream.flush(); } From 19ccf65b78b6b9199cf31a3375d3ba0345857ce9 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 16 Feb 2011 13:37:45 +0300 Subject: [PATCH 35/90] builder-style interface --- .../fileChooser/FileChooserDescriptor.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java index 5cdede04c27a..17e83681136a 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java @@ -33,12 +33,12 @@ import java.util.List; import java.util.Map; public class FileChooserDescriptor implements Cloneable{ - private final boolean myChooseFiles; - private final boolean myChooseFolders; - private final boolean myChooseJars; - private final boolean myChooseJarsAsFiles; - private final boolean myChooseJarContents; - private final boolean myChooseMultiple; + private boolean myChooseFiles; + private boolean myChooseFolders; + private boolean myChooseJars; + private boolean myChooseJarsAsFiles; + private boolean myChooseJarContents; + private boolean myChooseMultiple; private String myTitle = UIBundle.message("file.chooser.default.title"); private String myDescription; @@ -74,6 +74,15 @@ public class FileChooserDescriptor implements Cloneable{ myChooseMultiple = chooseMultiple; } + public FileChooserDescriptor() { + this(false, false, false, false, false, false); + } + + public FileChooserDescriptor chooseFolders() { + myChooseFolders = true; + return this; + } + public final String getTitle() { return myTitle; } From 304d43fffac3f8271c8af366d3268170c43681f1 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 16 Feb 2011 15:36:12 +0300 Subject: [PATCH 36/90] cleanup --- .../configuration/ModuleChooserElement.java | 87 ------------------- 1 file changed, 87 deletions(-) delete mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleChooserElement.java diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleChooserElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleChooserElement.java deleted file mode 100644 index 0831bce4e3ee..000000000000 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleChooserElement.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.openapi.roots.ui.configuration; - -import com.intellij.ide.util.ElementsChooser; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ModuleOrderEntry; -import com.intellij.openapi.roots.ui.util.CellAppearanceUtils; - -import javax.swing.*; -import java.awt.*; - -/** - * TODO: remove it together witrh DependenciesEditor - */ -public class ModuleChooserElement implements ElementsChooser.ElementProperties{ - private final String myName; - private final Module myModule; - private ModuleOrderEntry myOrderEntry; - - public ModuleChooserElement(Module module, ModuleOrderEntry orderEntry) { - myModule = module; - myOrderEntry = orderEntry; - myName = module != null? module.getName() : orderEntry.getModuleName(); - } - - public Module getModule() { - return myModule; - } - - public ModuleOrderEntry getOrderEntry() { - return myOrderEntry; - } - - public void setOrderEntry(ModuleOrderEntry orderEntry) { - myOrderEntry = orderEntry; - } - - public String getName() { - return myName; - } - - public Icon getIcon() { - if (myModule != null) { - return myModule.getModuleType().getNodeIcon(false); - } - else { - return CellAppearanceUtils.INVALID_ICON; - } - } - - public Color getColor() { - return myModule == null ? Color.RED : null; - } - - public String toString() { - return getName(); - } - - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof ModuleChooserElement)) return false; - - final ModuleChooserElement chooserElement = (ModuleChooserElement)o; - - if (!myName.equals(chooserElement.myName)) return false; - - return true; - } - - public int hashCode() { - return myName.hashCode(); - } -} From 7a6bd7b4b93b60ad661a0fe9d0733b02f818903b Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 16 Feb 2011 15:48:04 +0300 Subject: [PATCH 37/90] cleanup --- .../configuration/LibraryChooserElement.java | 94 ------------------- 1 file changed, 94 deletions(-) delete mode 100644 java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java deleted file mode 100644 index 99c2c8efebd6..000000000000 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/LibraryChooserElement.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @author cdr - */ -package com.intellij.openapi.roots.ui.configuration; - -import com.intellij.ide.util.ElementsChooser; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.ProjectBundle; -import com.intellij.openapi.roots.LibraryOrderEntry; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.util.Icons; - -import javax.swing.*; -import java.awt.*; - -public class LibraryChooserElement { - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.LibraryChooserElement"); - - private final String myName; - private final Library myLibrary; - private LibraryOrderEntry myOrderEntry; - public static final ElementsChooser.ElementProperties VALID_LIBRARY_ELEMENT_PROPERTIES = new ElementsChooser.ElementProperties() { - public Icon getIcon() { - return Icons.LIBRARY_ICON; - } - public Color getColor() { - return null; - } - }; - public static final ElementsChooser.ElementProperties INVALID_LIBRARY_ELEMENT_PROPERTIES = new ElementsChooser.ElementProperties() { - public Icon getIcon() { - return Icons.LIBRARY_ICON; - } - public Color getColor() { - return Color.RED; - } - }; - - public LibraryChooserElement(Library library, final LibraryOrderEntry orderEntry) { - myLibrary = library; - myOrderEntry = orderEntry; - if (myLibrary == null && myOrderEntry == null) { - LOG.error("Both library and order entry are null"); - myName = ProjectBundle.message("module.libraries.unknown.item"); - } - else { - myName = myLibrary != null? myLibrary.getName() : myOrderEntry.getLibraryName(); - } - } - - public String toString() { - return myName; - } - - public String getName() { - return myName; - } - - public Library getLibrary() { - return myLibrary; - } - - public LibraryOrderEntry getOrderEntry() { - return myOrderEntry; - } - - public void setOrderEntry(LibraryOrderEntry orderEntry) { - myOrderEntry = orderEntry; - } - - public boolean isAttachedToProject() { - return myOrderEntry != null; - } - - public boolean isValid() { - return myLibrary != null; - } -} \ No newline at end of file From fc590c75e2c73f1b6773cdfc4118dc9a84deb241 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 16 Feb 2011 15:50:01 +0300 Subject: [PATCH 38/90] javadoc --- .../src/com/intellij/ide/util/ElementsChooser.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java b/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java index 19703b9bbe16..04f695012f0e 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java +++ b/platform/platform-impl/src/com/intellij/ide/util/ElementsChooser.java @@ -34,6 +34,9 @@ import java.awt.event.KeyEvent; import java.util.*; import java.util.List; +/** + * @see ChooseElementsDialog + */ public class ElementsChooser extends JPanel implements ComponentWithEmptyText, ComponentWithExpandableItems { private JBTable myTable = null; private MyTableModel myTableModel = null; @@ -42,7 +45,7 @@ public class ElementsChooser extends JPanel implements ComponentWithEmptyText private final Map myElementToPropertiesMap = new HashMap(); private final Map myDisabledMap = new HashMap(); - public static interface ElementsMarkListener { + public interface ElementsMarkListener { void elementMarkChanged(T element, boolean isMarked); } From c4b0be9abda648a1e6a7a271ffcf05c712af01bd Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 16 Feb 2011 16:06:52 +0300 Subject: [PATCH 39/90] comforts --- .../artifacts/ArtifactEditorContextImpl.java | 5 +---- .../com/intellij/ide/util/ChooseElementsDialog.java | 13 +++++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorContextImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorContextImpl.java index 866913fb8a3c..8427af7488f6 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorContextImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorContextImpl.java @@ -169,10 +169,7 @@ public class ArtifactEditorContextImpl implements ArtifactEditorContext { } public List chooseModules(final List modules, final String title) { - ChooseModulesDialog dialog = new ChooseModulesDialog(getProject(), modules, title, null); - dialog.show(); - List selected = dialog.getChosenElements(); - return dialog.isOK() ? selected : Collections.emptyList(); + return new ChooseModulesDialog(getProject(), modules, title, null).showAndGetResult(); } public List chooseLibraries(final String title) { diff --git a/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java b/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java index 19e701b5fffb..c7a73dbbd8c9 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java @@ -88,10 +88,18 @@ public abstract class ChooseElementsDialog extends DialogWrapper { init(); } + public List showAndGetResult() { + show(); + return getChosenElements(); + } + protected abstract String getItemText(T item); + @Nullable + protected abstract Icon getItemIcon(T item); + public List getChosenElements() { - return myChooser.getSelectedElements(); + return isOK() ? myChooser.getSelectedElements() : Collections.emptyList(); } public void selectElements(@NotNull List elements) { @@ -130,7 +138,4 @@ public abstract class ChooseElementsDialog extends DialogWrapper { } }; } - - @Nullable - protected abstract Icon getItemIcon(T item); } From 4f89fcf32236761cd327a1444c4fd6a62352a61c Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 17 Feb 2011 13:05:55 +0300 Subject: [PATCH 40/90] IDEA-65613 Wrong EditorTextField initial size in several places in UI Editor size calculation algorithm is corrected in order to have one line height as a minimum preferred size height value (used to return zero-height for the empty document) --- .../src/com/intellij/openapi/editor/impl/EditorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 09442c02bd0f..e003cb69d206 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -5552,7 +5552,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi maxWidth = Math.max(maxWidth, myLineWidths.getQuick(i)); } - mySize = new Dimension(maxWidth, getLineHeight() * getVisibleLineCount()); + mySize = new Dimension(maxWidth, getLineHeight() * Math.max(getVisibleLineCount(), 1)); myIsDirty = false; } From a24b616346b65efdc548db35b39e5c8f5d650991 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 17 Feb 2011 13:17:20 +0300 Subject: [PATCH 41/90] git log: fix search by hash (?) --- plugins/git4idea/src/git4idea/changes/GitChangeUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java b/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java index 16e6467e84f3..0ae8d180ee41 100644 --- a/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java +++ b/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java @@ -306,7 +306,7 @@ public class GitChangeUtils { h.setNoSSH(true); h.setSilent(true); h.addParameters(parameters); - h.addParameters("--max-count=1", "--pretty=%H", "--encoding=UTF-8", "\"" + anyReference + "\"", "--"); + h.addParameters("--max-count=1", "--pretty=%H", "--encoding=UTF-8", anyReference, "--"); try { final String output = h.run().trim(); if (StringUtil.isEmptyOrSpaces(output)) return null; From 4e45f7dd086bbc3b4d828f3137f4d435fc35e651 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 17 Feb 2011 11:26:08 +0100 Subject: [PATCH 42/90] idea check: temporarily disable non-blocking read for tests' debug mode --- .../javaCompiler/CompilerParsingThread.java | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java index 6dabf6c78cdc..5c786f9a2207 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -224,29 +224,24 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { private int readNextByte(final Reader reader) { try { - while(!reader.ready()) { - if (isProcessTerminated()) { - if (CompileDriver.ourDebugMode) { - String text; - try { - text = reader.ready()? "ready" : "not ready"; - } - catch (IOException e) { - text = "Exception " + e.getMessage(); - } - System.out.println("COMPILER PARSING THREAD: reader not ready before isTerminatedCheck(), after the check: isReady= " + text); + if (!CompileDriver.ourDebugMode) { + while(!reader.ready()) { + if (isProcessTerminated()) { + return -1; + } + try { + Thread.sleep(1L); + } + catch (InterruptedException ignore) { } - return -1; - } - try { - Thread.sleep(1L); - } - catch (InterruptedException ignore) { } } return reader.read(); } catch (IOException e) { + if (CompileDriver.ourDebugMode) { + e.printStackTrace(); + } return -1; // When process terminated Process.getInputStream()'s underlying stream becomes closed on Linux. } } From aa08c5f05e7563f87c2569185f8a697f1616427a Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 17 Feb 2011 13:37:53 +0300 Subject: [PATCH 43/90] git log: completion provider to correct place --- resources/src/META-INF/IdeaPlugin.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 868c3ae07341..9a8aa3592a9e 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -260,6 +260,7 @@ order="last, before javaSmart"/> + From 1f8283df9be92c3872f0a7d0ad426793c4afe970 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 16 Feb 2011 14:34:32 +0300 Subject: [PATCH 44/90] cleanup --- .../com/intellij/lang/PsiBuilderQuickTest.java | 5 +++-- .../org/jetbrains/idea/maven/MavenTestCase.java | 15 ++++++++------- .../maven/compiler/ResourceFilteringTest.java | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java b/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java index ab25345b030f..c60a76a73da0 100644 --- a/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java +++ b/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java @@ -17,6 +17,7 @@ package com.intellij.lang; import com.intellij.lang.impl.PsiBuilderImpl; import com.intellij.lexer.LexerBase; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.psi.TokenType; @@ -64,7 +65,7 @@ public class PsiBuilderQuickTest { @BeforeClass public static void setUp() { - if (ApplicationManagerEx.getApplication() == null) { + if (ApplicationManager.getApplication() == null) { if (myMockApp == null) { myMockApp = createMock(ApplicationEx.class); expect(myMockApp.isInternal()).andReturn(true); @@ -466,7 +467,7 @@ public class PsiBuilderQuickTest { " PsiElement(OTHER)('}')\n"); } - private static abstract class MyLazyElementType extends ILazyParseableElementType implements ILightLazyParseableElementType { + private abstract static class MyLazyElementType extends ILazyParseableElementType implements ILightLazyParseableElementType { protected MyLazyElementType(@NonNls String debugName) { super(debugName, Language.ANY); } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java index 77aca6041cc9..1b4200f1991c 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/MavenTestCase.java @@ -384,7 +384,7 @@ public abstract class MavenTestCase extends UsefulTestCase { return createProfilesFile(createProjectSubDir(relativePath), xml, false); } - private VirtualFile createProfilesFile(VirtualFile dir, String xml, boolean oldStyle) throws IOException { + private static VirtualFile createProfilesFile(VirtualFile dir, String xml, boolean oldStyle) throws IOException { return createProfilesFile(dir, createValidProfiles(xml, oldStyle)); } @@ -396,7 +396,7 @@ public abstract class MavenTestCase extends UsefulTestCase { return createProfilesFile(createProjectSubDir(relativePath), content); } - private VirtualFile createProfilesFile(final VirtualFile dir, String content) throws IOException { + private static VirtualFile createProfilesFile(final VirtualFile dir, String content) throws IOException { VirtualFile f = dir.findChild("profiles.xml"); if (f == null) { f = new WriteAction() { @@ -411,6 +411,7 @@ public abstract class MavenTestCase extends UsefulTestCase { return f; } + @Language("XML") private static String createValidProfiles(String xml, boolean oldStyle) { if (oldStyle) { return "" + @@ -478,15 +479,15 @@ public abstract class MavenTestCase extends UsefulTestCase { assertEquals(expected, actual); } - protected void assertOrderedElementsAreEqual(Collection actual, Collection expected) { + protected static void assertOrderedElementsAreEqual(Collection actual, Collection expected) { assertOrderedElementsAreEqual(actual, expected.toArray()); } - protected void assertUnorderedElementsAreEqual(Collection actual, Collection expected) { + protected static void assertUnorderedElementsAreEqual(Collection actual, Collection expected) { assertUnorderedElementsAreEqual(actual, expected.toArray()); } - protected void assertUnorderedElementsAreEqual(U[] actual, T... expected) { + protected static void assertUnorderedElementsAreEqual(U[] actual, T... expected) { assertUnorderedElementsAreEqual(Arrays.asList(actual), expected); } @@ -514,7 +515,7 @@ public abstract class MavenTestCase extends UsefulTestCase { for (int i = 0; i < expected.length; i++) { T expectedElement = expected[i]; U actualElement = actualList.get(i); - assertTrue(s, expectedElement.equals(actualElement)); + assertEquals(s, expectedElement, actualElement); } } @@ -526,7 +527,7 @@ public abstract class MavenTestCase extends UsefulTestCase { protected static void assertDoNotContain(List actual, T... expected) { List actualCopy = new ArrayList(actual); actualCopy.removeAll(Arrays.asList(expected)); - assertTrue(actual.toString(), actualCopy.size() == actual.size()); + assertEquals(actual.toString(), actualCopy.size(), actual.size()); } protected boolean ignore() { 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 8655c42934bb..8c35ad17b4b0 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 @@ -19,7 +19,7 @@ import com.intellij.compiler.CompilerConfiguration; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.fileTypes.FileTypeManager; -import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.idea.maven.MavenImportingTestCase; @@ -858,7 +858,7 @@ public class ResourceFilteringTest extends MavenImportingTestCase { public void testDoNotFilterButCopyBigFiles() throws Exception { assertFalse(CompilerConfiguration.getInstance(myProject).isResourceFile("file.xyz")); - assertEquals(FileTypeManager.getInstance().getFileTypeByFileName("file.xyz"), StdFileTypes.UNKNOWN); + assertEquals(FileTypeManager.getInstance().getFileTypeByFileName("file.xyz"), FileTypes.UNKNOWN); createProjectSubFile("resources/file.xyz").setBinaryContent(new byte[1024 * 1024 * 20]); From e4a7d40de9602d28184425023a93947686820c53 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 16 Feb 2011 16:47:51 +0300 Subject: [PATCH 45/90] javadoc --- java/openapi/src/com/intellij/psi/PsiType.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/openapi/src/com/intellij/psi/PsiType.java b/java/openapi/src/com/intellij/psi/PsiType.java index 5c70c8a21576..d52949c5f6d6 100644 --- a/java/openapi/src/com/intellij/psi/PsiType.java +++ b/java/openapi/src/com/intellij/psi/PsiType.java @@ -61,7 +61,7 @@ public abstract class PsiType implements PsiAnnotationOwner { } /** - * Returns text of this type that can be presented to user. + * @return text of this type that can be presented to user. */ public abstract String getPresentableText(); @@ -79,7 +79,7 @@ public abstract class PsiType implements PsiAnnotationOwner { public abstract boolean isValid(); /** - * Checks whether values of type type can be assigned to rvalues of this type. + * @return true if values of type type can be assigned to rvalues of this type. */ public boolean isAssignableFrom(@NotNull PsiType type) { return TypeConversionUtil.isAssignable(this, type); From 6c65c043037bce750ad6aceef489861ed46680b2 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 16 Feb 2011 17:36:53 +0300 Subject: [PATCH 46/90] unnecessary calls to getMockJDK() removed in tests --- .../completion/ClassNameCompletionTest.java | 5 --- .../HeavySmartTypeCompletion15Test.java | 4 --- .../SecondSmartTypeCompletionTest.java | 5 --- .../daemon/AnnotationsHighlightingTest.java | 4 --- .../daemon/GenericsHighlightingTest.java | 5 --- .../daemon/JavadocHighlightingTest.java | 5 --- .../daemon/SuppressWarningsTest.java | 4 --- .../CreateFieldFromParameterTest.java | 4 --- .../quickFix/LightQuickFix15TestCase.java | 6 ---- ...moveRedundantUncheckedSuppressionTest.java | 6 ---- ...eplaceAddAllArrayToCollectionsFixTest.java | 5 --- .../quickFix/SafeVarargsCanBeUsedTest.java | 6 ---- .../Simplify2DiamondInspectionsTest.java | 6 ---- .../quickFix/Suppress15InspectionsTest.java | 6 ---- .../quickFix/SurroundWithArrayFixTest.java | 5 --- .../quickFix/SurroundWithIfFixTest.java | 5 --- .../AddOnDemandStaticImportActionTest.java | 5 --- .../codeInsight/slice/SliceBackwardTest.java | 5 --- .../codeInsight/slice/SliceForwardTest.java | 5 --- .../codeInsight/slice/SliceTreeTest.java | 4 --- .../projectView/JavaTreeStructureTest.java | 6 ---- .../projectView/ProjectViewSwitchingTest.java | 6 ---- .../StructureViewUpdatingTest.java | 6 ---- .../intellij/psi/ModifyAnnotationsTest.java | 5 --- .../com/intellij/psi/OptimizeImportsTest.java | 5 --- .../intellij/psi/Src15RepositoryUseTest.java | 5 --- .../refactoring/AnonymousToInnerTest.java | 5 --- .../ChangeSignatureTargetTest.java | 5 --- .../refactoring/ExtractMethod15Test.java | 6 ---- .../refactoring/ExtractMethodTest.java | 5 --- .../refactoring/ExtractSuperClassTest.java | 5 --- .../FindMethodDuplicatesBaseTest.java | 5 --- .../InheritanceToDelegationTest.java | 5 --- .../refactoring/InlineSuperClassTest.java | 5 --- .../refactoring/IntroduceConstantTest.java | 5 --- .../IntroduceFieldInSameClassTest.java | 5 --- .../refactoring/IntroduceParameterTest.java | 5 --- .../refactoring/IntroduceVariableTest.java | 5 --- .../refactoring/PullUpMultifileTest.java | 6 ---- .../com/intellij/refactoring/PullUpTest.java | 5 --- .../refactoring/PushDownMultifileTest.java | 5 --- .../intellij/refactoring/RenameClassTest.java | 5 --- .../refactoring/RenameCollisionsTest.java | 5 --- .../refactoring/SuggestedParamTypesTest.java | 5 --- .../refactoring/TurnRefsToSuperTest.java | 5 --- .../intellij/refactoring/TypeCookTest.java | 5 --- .../refactoring/WrapReturnValueTest.java | 5 --- .../ChangeClassSignatureTest.java | 5 --- .../inline/InlineConstantFieldTest.java | 5 --- .../refactoring/inline/InlineLocalTest.java | 5 --- .../refactoring/inline/InlineMethodTest.java | 5 --- .../inline/InlineParameterTest.java | 5 --- .../inline/InlineToAnonymousClassTest.java | 5 --- .../projectView/BaseProjectViewTestCase.java | 5 --- .../LightCodeInsightFixtureTestCase.java | 31 ++----------------- .../impl/JavaTestFixtureFactoryImpl.java | 2 +- .../plugins/groovy/LightGroovyTestCase.java | 17 ++-------- .../gant/GantReferenceCompletionTest.groovy | 19 +++--------- .../binding/RenameUIRelatedTest.java | 5 --- 59 files changed, 9 insertions(+), 340 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java index 9fe6b5a8729d..3c49ffa9dd21 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java @@ -34,11 +34,6 @@ public class ClassNameCompletionTest extends CompletionTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - @Override protected void tearDown() throws Exception { CodeInsightSettings.getInstance().AUTOCOMPLETE_ON_CLASS_NAME_COMPLETION = myOldSetting; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavySmartTypeCompletion15Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavySmartTypeCompletion15Test.java index 750c40dedd5b..49793d481d48 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavySmartTypeCompletion15Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavySmartTypeCompletion15Test.java @@ -81,8 +81,4 @@ public class HeavySmartTypeCompletion15Test extends CompletionTestCase { LookupManager.getInstance(myProject).hideActiveLookup(); super.tearDown(); } - - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java index 4670cc526d22..85c3caba21ec 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SecondSmartTypeCompletionTest.java @@ -178,9 +178,4 @@ public class SecondSmartTypeCompletionTest extends LightCompletionTestCase { LookupManager.getInstance(getProject()).hideActiveLookup(); super.tearDown(); } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java index 7ec7c261da7d..72facd2c365c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AnnotationsHighlightingTest.java @@ -37,8 +37,4 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testPackageAnnotationNotInPackageInfo() throws Exception { doTest(BASE_PATH + "/" + getTestName(true) + "/notPackageInfo.java", false, false); } - - @Override protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17(); - } } 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 452ece2addbb..f3f76a8a5f65 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -36,11 +36,6 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { LanguageLevelProjectExtension.getInstance(getJavaFacade().getProject()).setLanguageLevel(level); } - @Override protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - - public void testReferenceTypeParams() throws Exception { doTest(false); } public void testOverridingMethods() throws Exception { doTest(false); } public void testTypeParameterBoundsList() throws Exception { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java index 8f9b3907effe..765ac83ce899 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/JavadocHighlightingTest.java @@ -106,9 +106,4 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase { protected void doTest() throws Exception { super.doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false); } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/SuppressWarningsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/SuppressWarningsTest.java index c73767a23e24..841b6f80a29f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/SuppressWarningsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/SuppressWarningsTest.java @@ -17,10 +17,6 @@ public class SuppressWarningsTest extends LightDaemonAnalyzerTestCase { doTest(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false); } - @Override protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{new UnusedSymbolLocalInspection()}; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateFieldFromParameterTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateFieldFromParameterTest.java index 1469f4559152..dd91045350ef 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateFieldFromParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/CreateFieldFromParameterTest.java @@ -30,8 +30,4 @@ public class CreateFieldFromParameterTest extends LightIntentionActionTestCase { protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/createFieldFromParameter"; } - - @Override protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java index f5a060bdb80f..cd1e7f02e3ac 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/LightQuickFix15TestCase.java @@ -7,10 +7,4 @@ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; * @author ven */ public abstract class LightQuickFix15TestCase extends LightQuickFixTestCase { - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java index 7f2d28816f63..a886624d27e3 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RemoveRedundantUncheckedSuppressionTest.java @@ -23,12 +23,6 @@ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; public class RemoveRedundantUncheckedSuppressionTest extends LightQuickFixTestCase { - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17(); - } - @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceAddAllArrayToCollectionsFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceAddAllArrayToCollectionsFixTest.java index f9b254d0977d..eaaf9552978c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceAddAllArrayToCollectionsFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ReplaceAddAllArrayToCollectionsFixTest.java @@ -16,9 +16,4 @@ public class ReplaceAddAllArrayToCollectionsFixTest extends LightQuickFixTestCas protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/replaceAddAllArrayToCollections"; } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SafeVarargsCanBeUsedTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SafeVarargsCanBeUsedTest.java index 8cf7f2001b31..1bd158a99325 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SafeVarargsCanBeUsedTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SafeVarargsCanBeUsedTest.java @@ -22,12 +22,6 @@ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; public class SafeVarargsCanBeUsedTest extends LightQuickFixTestCase { - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17(); - } - @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java index de19e1fc48b4..8667fdfcd617 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Simplify2DiamondInspectionsTest.java @@ -32,12 +32,6 @@ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; //todo test3 should be checked if it compiles - as now javac infers Object instead of String?! public class Simplify2DiamondInspectionsTest extends LightQuickFixTestCase { - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17(); - } - @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Suppress15InspectionsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Suppress15InspectionsTest.java index ea7f4f737b64..b9bb396985d2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Suppress15InspectionsTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/Suppress15InspectionsTest.java @@ -16,12 +16,6 @@ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; public class Suppress15InspectionsTest extends LightQuickFixTestCase { - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17(); - } - @Override protected void setUp() throws Exception { super.setUp(); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithArrayFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithArrayFixTest.java index 19eb09ac7061..715c7032dedd 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithArrayFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithArrayFixTest.java @@ -16,9 +16,4 @@ public class SurroundWithArrayFixTest extends LightQuickFix15TestCase { protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithArray"; } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithIfFixTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithIfFixTest.java index 99a556b2e88b..a9d352678609 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithIfFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/SurroundWithIfFixTest.java @@ -23,9 +23,4 @@ public class SurroundWithIfFixTest extends LightQuickFixTestCase { protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/surroundWithIf"; } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/AddOnDemandStaticImportActionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/AddOnDemandStaticImportActionTest.java index d9600e13982f..d917ffc71b1b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/intention/AddOnDemandStaticImportActionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/AddOnDemandStaticImportActionTest.java @@ -12,9 +12,4 @@ public class AddOnDemandStaticImportActionTest extends LightIntentionActionTestC protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/addOnDemandStaticImport"; } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17(); - } } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java index 5c03d221fef0..a2c458564e23 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceBackwardTest.java @@ -33,11 +33,6 @@ import java.util.*; public class SliceBackwardTest extends DaemonAnalyzerTestCase { private final TIntObjectHashMap myFlownOffsets = new TIntObjectHashMap(); - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - private void dotest() throws Exception { configureByFile("/codeInsight/slice/backward/"+getTestName(false)+".java"); Map sliceUsageName2Offset = extractSliceOffsetsFromDocument(getEditor().getDocument()); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java index 5eeb74e1a597..3c6049a0bd6f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceForwardTest.java @@ -24,11 +24,6 @@ import java.util.Map; public class SliceForwardTest extends DaemonAnalyzerTestCase { private final TIntObjectHashMap myFlownOffsets = new TIntObjectHashMap(); - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - private void dotest() throws Exception { configureByFile("/codeInsight/slice/forward/"+getTestName(false)+".java"); Map sliceUsageName2Offset = SliceBackwardTest.extractSliceOffsetsFromDocument(getEditor().getDocument()); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java index 0d3677d62d96..a114c363b27b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/slice/SliceTreeTest.java @@ -24,10 +24,6 @@ import java.util.*; * @author cdr */ public class SliceTreeTest extends LightDaemonAnalyzerTestCase { - @Override protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17(); - } - private SliceTreeStructure configureTree(@NonNls final String name) throws Exception { configureByFile("/codeInsight/slice/backward/"+ name +".java"); PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); diff --git a/java/java-tests/testSrc/com/intellij/projectView/JavaTreeStructureTest.java b/java/java-tests/testSrc/com/intellij/projectView/JavaTreeStructureTest.java index f7afbe7fb133..ce1577e6dab0 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/JavaTreeStructureTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/JavaTreeStructureTest.java @@ -214,10 +214,4 @@ public class JavaTreeStructureTest extends TestSourceBasedTestCase { protected String getTestDataPath() { return JavaTestUtil.getJavaTestDataPath(); } - - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17(); - } - } diff --git a/java/java-tests/testSrc/com/intellij/projectView/ProjectViewSwitchingTest.java b/java/java-tests/testSrc/com/intellij/projectView/ProjectViewSwitchingTest.java index 81279689983b..14769572ad6c 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ProjectViewSwitchingTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/ProjectViewSwitchingTest.java @@ -64,10 +64,4 @@ public class ProjectViewSwitchingTest extends TestSourceBasedTestCase { protected String getTestDataPath() { return JavaTestUtil.getJavaTestDataPath(); } - - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17(); - } - } diff --git a/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java b/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java index cf157662a789..d7ee434b124c 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java @@ -246,10 +246,4 @@ public class StructureViewUpdatingTest extends TestSourceBasedTestCase { protected String getTestDataPath() { return JavaTestUtil.getJavaTestDataPath(); } - - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17(); - } - } diff --git a/java/java-tests/testSrc/com/intellij/psi/ModifyAnnotationsTest.java b/java/java-tests/testSrc/com/intellij/psi/ModifyAnnotationsTest.java index d5ec9c2980b5..a362f3fb693a 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ModifyAnnotationsTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ModifyAnnotationsTest.java @@ -24,11 +24,6 @@ public class ModifyAnnotationsTest extends PsiTestCase { PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("mock 1.5"); - } - public void testReplaceAnnotation() throws Exception { //be sure not to load tree getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.ALL); diff --git a/java/java-tests/testSrc/com/intellij/psi/OptimizeImportsTest.java b/java/java-tests/testSrc/com/intellij/psi/OptimizeImportsTest.java index 358049a5d8c4..8b0816694ea6 100644 --- a/java/java-tests/testSrc/com/intellij/psi/OptimizeImportsTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/OptimizeImportsTest.java @@ -43,11 +43,6 @@ public class OptimizeImportsTest extends PsiTestCase{ public void testNewImportListIsEmptyAndCommentPreserved() throws Exception { doTest(); } public void testNewImportListIsEmptyAndJavaDocWithInvalidCodePreserved() throws Exception { doTest(); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("mock 1.5"); - } - private void doTest() throws Exception { final String extension = ".java"; doTest(extension); diff --git a/java/java-tests/testSrc/com/intellij/psi/Src15RepositoryUseTest.java b/java/java-tests/testSrc/com/intellij/psi/Src15RepositoryUseTest.java index 99c0c964392f..b3fd5a1a4e28 100644 --- a/java/java-tests/testSrc/com/intellij/psi/Src15RepositoryUseTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/Src15RepositoryUseTest.java @@ -37,11 +37,6 @@ public class Src15RepositoryUseTest extends PsiTestCase { PsiTestUtil.createTestProjectStructure(myProject, myModule, root, myFilesToDelete); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("mock 1.5"); - } - @Override protected void tearDown() throws Exception { LanguageLevelProjectExtension.getInstance(myProject).setLanguageLevel(LanguageLevel.JDK_1_5); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/AnonymousToInnerTest.java b/java/java-tests/testSrc/com/intellij/refactoring/AnonymousToInnerTest.java index 609b41c5b308..1324468bf5e9 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/AnonymousToInnerTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/AnonymousToInnerTest.java @@ -17,11 +17,6 @@ public class AnonymousToInnerTest extends LightCodeInsightTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testGenericTypeParameters() throws Exception { // IDEADEV-29446 doTest("MyIterator", true); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java index 546d947a8acc..b03da3135c7a 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTargetTest.java @@ -35,11 +35,6 @@ public class ChangeSignatureTargetTest extends LightCodeInsightTestCase { doTest("A1"); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - private void doTest(String expectedMemberName) throws Exception { String basePath = "/refactoring/changeSignatureTarget/" + getTestName(true); @NonNls final String filePath = basePath + ".java"; diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethod15Test.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethod15Test.java index 31a250a06b54..d8d7ba33dcb9 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethod15Test.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethod15Test.java @@ -23,10 +23,4 @@ public class ExtractMethod15Test extends LightCodeInsightTestCase { assertTrue(success); checkResultByFile(BASE_PATH + getTestName(false) + "_after.java"); } - - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java index 5ddf845b5212..9d632414afb4 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java @@ -30,11 +30,6 @@ public class ExtractMethodTest extends LightCodeInsightTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testExitPoints1() throws Exception { doExitPointsTest(true); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractSuperClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractSuperClassTest.java index 4bab81f11dc4..34f7b9b2cc86 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractSuperClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractSuperClassTest.java @@ -108,11 +108,6 @@ public class ExtractSuperClassTest extends CodeInsightTestCase { doTest("p1.A", "AA", new RefactoringTestUtil.MemberDescriptor("m1", PsiMethod.class)); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17(); - } - @Override protected void setUp() throws Exception { super.setUp(); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/FindMethodDuplicatesBaseTest.java b/java/java-tests/testSrc/com/intellij/refactoring/FindMethodDuplicatesBaseTest.java index 036e8f45f349..dc4b52b2b5dc 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/FindMethodDuplicatesBaseTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/FindMethodDuplicatesBaseTest.java @@ -20,11 +20,6 @@ public abstract class FindMethodDuplicatesBaseTest extends LightCodeInsightTestC return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - protected void doTest() throws Exception { doTest(true); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InheritanceToDelegationTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InheritanceToDelegationTest.java index a3a0f74771eb..62ed537207b2 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InheritanceToDelegationTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InheritanceToDelegationTest.java @@ -23,11 +23,6 @@ public class InheritanceToDelegationTest extends MultiFileTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - @Override protected String getTestRoot() { return "/refactoring/inheritanceToDelegation/"; diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java index 9deeb8202c37..d4b03c5545eb 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/InlineSuperClassTest.java @@ -23,11 +23,6 @@ public class InlineSuperClassTest extends MultiFileTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17(); - } - private void doTest() throws Exception { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java index bab6d71717ea..7e9be3f2c649 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java @@ -124,9 +124,4 @@ public class IntroduceConstantTest extends LightCodeInsightTestCase { } }.invoke(getProject(), getEditor(), getFile(), null); } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFieldInSameClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFieldInSameClassTest.java index 80a17f4aa744..2ad2588f7561 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFieldInSameClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceFieldInSameClassTest.java @@ -18,11 +18,6 @@ public class IntroduceFieldInSameClassTest extends LightCodeInsightTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testInClassInitializer () throws Exception { configureByFile("/refactoring/introduceField/before1.java"); performRefactoring(BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION, true); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java index cba854352cc2..c193eeae4d9e 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java @@ -348,9 +348,4 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase { IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE, declareFinal, false, null, parametersToRemove).run(); } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 2a19c88e5d7b..2094231236f5 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -256,9 +256,4 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { testMe.invoke(getProject(), getEditor(), getFile(), null); checkResultByFile(baseName + ".after.java"); } - - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17(); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java index 21f07ad9bca6..abad0d75f8c9 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpMultifileTest.java @@ -51,12 +51,6 @@ public class PullUpMultifileTest extends MultiFileTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - - private void doTest(final String... conflicts) throws Exception { final MultiMap conflictsMap = new MultiMap(); doTest(new PerformAction() { diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java index 53ef64abd01f..b5ddaf93ecdd 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java @@ -135,11 +135,6 @@ public class PullUpTest extends LightCodeInsightTestCase { checkResultByFile(BASE_PATH + getTestName(false) + "_after.java"); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("50"); - } - @Override protected String getTestDataPath() { return JavaTestUtil.getJavaTestDataPath(); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PushDownMultifileTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PushDownMultifileTest.java index c408ae325a05..385f5de7075b 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PushDownMultifileTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PushDownMultifileTest.java @@ -28,11 +28,6 @@ public class PushDownMultifileTest extends MultiFileTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - private void doTest() throws Exception { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameClassTest.java index 6550750f19ae..cf397aaab416 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/RenameClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameClassTest.java @@ -113,9 +113,4 @@ public class RenameClassTest extends MultiFileTestCase { protected String getTestRoot() { return "/refactoring/renameClass/"; } - - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java index bfd33dd79548..279875a4d0ab 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameCollisionsTest.java @@ -182,11 +182,6 @@ public class RenameCollisionsTest extends LightCodeInsightTestCase { checkResultByFile(BASE_PATH + getTestName(false) + ".java.after"); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testAllUsagesInCode() throws Exception { configureByFile(BASE_PATH + getTestName(false) + ".java"); PsiElement element = TargetElementUtilBase diff --git a/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java b/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java index b9f55f2a3942..d59a4ea63168 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java @@ -46,11 +46,6 @@ public class SuggestedParamTypesTest extends LightCodeInsightTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testPostfixExprUsedAsOutput() throws Exception { doTest("byte"); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java b/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java index fe0356736a9c..872232ed37f9 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/TurnRefsToSuperTest.java @@ -159,9 +159,4 @@ public class TurnRefsToSuperTest extends MultiFileTestCase { new TurnRefsToSuperProcessor(myProject, aClass, superClass, replaceInstanceOf).run(); FileDocumentManager.getInstance().saveAllDocuments(); } - - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/TypeCookTest.java b/java/java-tests/testSrc/com/intellij/refactoring/TypeCookTest.java index 5c43b16e3556..9fea974ce682 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/TypeCookTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/TypeCookTest.java @@ -29,11 +29,6 @@ import java.io.PrintWriter; */ public class TypeCookTest extends MultiFileTestCase { - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - @Override protected String getTestDataPath() { return JavaTestUtil.getJavaTestDataPath(); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/WrapReturnValueTest.java b/java/java-tests/testSrc/com/intellij/refactoring/WrapReturnValueTest.java index ae2288fd5529..37e312545086 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/WrapReturnValueTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/WrapReturnValueTest.java @@ -26,11 +26,6 @@ public class WrapReturnValueTest extends MultiFileTestCase{ return "/refactoring/wrapReturnValue/"; } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - private void doTest(final boolean existing) throws Exception { doTest(existing, null); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureTest.java b/java/java-tests/testSrc/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureTest.java index ae8a135a5029..67473d302711 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureTest.java @@ -21,11 +21,6 @@ public class ChangeClassSignatureTest extends LightCodeInsightTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testNoParams() throws Exception { doTest(new GenParams() { @Override diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineConstantFieldTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineConstantFieldTest.java index a27675020e98..27f6c8ca34f7 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineConstantFieldTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineConstantFieldTest.java @@ -29,11 +29,6 @@ public class InlineConstantFieldTest extends LightCodeInsightTestCase { doTest(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - private void doTest() throws Exception { String name = getTestName(false); @NonNls String fileName = "/refactoring/inlineConstantField/" + name + ".java"; diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java index 9f20be7086c9..adf2b4571e95 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineLocalTest.java @@ -22,11 +22,6 @@ public class InlineLocalTest extends LightCodeInsightTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testInference () throws Exception { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java index 9d66d2a6ac0c..21e5c85695bf 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java @@ -165,11 +165,6 @@ public class InlineMethodTest extends LightCodeInsightTestCase { doTest(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - private void doTest() throws Exception { String name = getTestName(false); @NonNls String fileName = "/refactoring/inlineMethod/" + name + ".java"; diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java index af27522eb21f..4ee1ff6c85d7 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineParameterTest.java @@ -20,11 +20,6 @@ public class InlineParameterTest extends LightCodeInsightTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testSameValue() throws Exception { doTest(true); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineToAnonymousClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineToAnonymousClassTest.java index f032dbcd87de..51a2c7017e0d 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineToAnonymousClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineToAnonymousClassTest.java @@ -24,11 +24,6 @@ public class InlineToAnonymousClassTest extends LightCodeInsightTestCase { return JavaTestUtil.getJavaTestDataPath(); } - @Override - protected Sdk getProjectJDK() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - public void testSimple() throws Exception { doTest(false, false); } diff --git a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java index 9d74773385d4..cbe0eb8c9a30 100644 --- a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java +++ b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java @@ -300,9 +300,4 @@ public abstract class BaseProjectViewTestCase extends TestSourceBasedTestCase { protected String getTestDataPath() { return PathManagerEx.getTestDataPath(getClass()); } - - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17(); - } } diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java index 4861b0c9ffa4..106fd70128fa 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java @@ -19,8 +19,6 @@ import com.intellij.lang.Language; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.module.StdModuleTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; @@ -42,15 +40,10 @@ import java.io.File; * @author peter */ public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase{ - public static final LightProjectDescriptor JAVA_1_4 = new LightProjectDescriptor() { - @Override - public ModuleType getModuleType() { - return StdModuleTypes.JAVA; - } - + public static final LightProjectDescriptor JAVA_1_4 = new DefaultLightProjectDescriptor() { @Override public Sdk getSdk() { - return JavaSdkImpl.getMockJdk17(); + return JavaSdkImpl.getMockJdk14(); } @Override @@ -58,32 +51,12 @@ public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase{ } }; public static final LightProjectDescriptor JAVA_1_5 = new DefaultLightProjectDescriptor() { - @Override - public ModuleType getModuleType() { - return StdModuleTypes.JAVA; - } - - @Override - public Sdk getSdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - @Override public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_5); } }; public static final LightProjectDescriptor JAVA_1_6 = new DefaultLightProjectDescriptor() { - @Override - public ModuleType getModuleType() { - return StdModuleTypes.JAVA; - } - - @Override - public Sdk getSdk() { - return JavaSdkImpl.getMockJdk17("java 1.6"); - } - @Override public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_6); diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java index e78a22b41e22..d4e85df6c728 100644 --- a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java +++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java @@ -53,5 +53,5 @@ public class JavaTestFixtureFactoryImpl extends JavaTestFixtureFactory { } } - private static final LightProjectDescriptor ourJavaProjectDescriptor = LightCodeInsightFixtureTestCase.JAVA_1_4; + private static final LightProjectDescriptor ourJavaProjectDescriptor = LightCodeInsightFixtureTestCase.JAVA_1_6; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/LightGroovyTestCase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/LightGroovyTestCase.java index 8b1a8ee8aa29..ccdaaae4ed02 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/LightGroovyTestCase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/LightGroovyTestCase.java @@ -17,10 +17,6 @@ package org.jetbrains.plugins.groovy; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.module.StdModuleTypes; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.OrderRootType; @@ -28,6 +24,7 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -37,17 +34,7 @@ import org.jetbrains.plugins.groovy.util.TestUtils; * @author peter */ public abstract class LightGroovyTestCase extends LightCodeInsightFixtureTestCase { - public static final LightProjectDescriptor GROOVY_DESCRIPTOR = new LightProjectDescriptor() { - @Override - public ModuleType getModuleType() { - return StdModuleTypes.JAVA; - } - - @Override - public Sdk getSdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - + public static final LightProjectDescriptor GROOVY_DESCRIPTOR = new DefaultLightProjectDescriptor() { @Override public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/GantReferenceCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/GantReferenceCompletionTest.groovy index 3f83dff82597..35500fafe438 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/GantReferenceCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/GantReferenceCompletionTest.groovy @@ -17,23 +17,20 @@ package org.jetbrains.plugins.groovy.gant; import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleType -import com.intellij.openapi.module.StdModuleTypes -import com.intellij.openapi.projectRoots.Sdk -import com.intellij.openapi.projectRoots.impl.JavaSdkImpl import com.intellij.openapi.roots.ContentEntry import com.intellij.openapi.roots.ModifiableRootModel import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.libraries.Library import com.intellij.openapi.vfs.JarFileSystem import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection import org.jetbrains.plugins.groovy.util.TestUtils -import org.jetbrains.annotations.NotNull -/** + /** * @author ilyas */ public class GantReferenceCompletionTest extends LightCodeInsightFixtureTestCase { @@ -178,15 +175,7 @@ target (default : '') { } -class GantProjectDescriptor implements LightProjectDescriptor { - public ModuleType getModuleType() { - return StdModuleTypes.JAVA; - } - - public Sdk getSdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - +class GantProjectDescriptor extends DefaultLightProjectDescriptor { public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); diff --git a/plugins/ui-designer/testSrc/com/intellij/uiDesigner/binding/RenameUIRelatedTest.java b/plugins/ui-designer/testSrc/com/intellij/uiDesigner/binding/RenameUIRelatedTest.java index b1f6f3e83d9a..ffe873a1cbc6 100644 --- a/plugins/ui-designer/testSrc/com/intellij/uiDesigner/binding/RenameUIRelatedTest.java +++ b/plugins/ui-designer/testSrc/com/intellij/uiDesigner/binding/RenameUIRelatedTest.java @@ -41,11 +41,6 @@ public class RenameUIRelatedTest extends MultiFileTestCase { return PluginPathManager.getPluginHomePath("ui-designer") + "/testData"; } - @Override - protected Sdk getTestProjectJdk() { - return JavaSdkImpl.getMockJdk17("java 1.5"); - } - @Override protected void setupProject(VirtualFile rootDir) { LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).setLanguageLevel(LanguageLevel.JDK_1_5); From 1b70c8123085bd315918adadfc74d58da51c67e6 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 16 Feb 2011 17:54:38 +0300 Subject: [PATCH 47/90] empty project descriptor in tests --- .../intellij/openapi/module/ModuleType.java | 2 +- .../openapi/module/EmptyModuleType.java | 5 ++-- .../testframework/sm/FileUrlLocationTest.java | 2 +- .../sm/SMLightFixtureTestCase.java | 21 --------------- .../testFramework/LightProjectDescriptor.java | 17 ++++++++++++ .../impl/IdeaTestFixtureFactoryImpl.java | 27 +++---------------- 6 files changed, 25 insertions(+), 49 deletions(-) diff --git a/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java b/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java index bcaa7001c08d..93ce3b0c5364 100644 --- a/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java +++ b/platform/lang-api/src/com/intellij/openapi/module/ModuleType.java @@ -25,7 +25,7 @@ import org.jetbrains.annotations.NonNls; import javax.swing.*; public abstract class ModuleType { - public static ModuleType EMPTY; + public static final ModuleType EMPTY; private final String myId; diff --git a/platform/lang-impl/src/com/intellij/openapi/module/EmptyModuleType.java b/platform/lang-impl/src/com/intellij/openapi/module/EmptyModuleType.java index bae94974ff90..4465fc0bc1e1 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/EmptyModuleType.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/EmptyModuleType.java @@ -27,12 +27,13 @@ public class EmptyModuleType extends ModuleType { private static final Icon NODE_ICON_OPEN = IconLoader.getIcon("/nodes/ModuleOpen.png"); private static final Icon NODE_ICON_CLOSED = IconLoader.getIcon("/nodes/ModuleClosed.png"); @NonNls public static final String EMPTY_MODULE = "EMPTY_MODULE"; - private static final EmptyModuleType ourInstance = new EmptyModuleType(); + //private static final EmptyModuleType ourInstance = new EmptyModuleType(); public static EmptyModuleType getInstance() { - return ourInstance; + return (EmptyModuleType)ModuleType.EMPTY; } + @SuppressWarnings({"UnusedDeclaration"}) // implicitly instantiated from ModuleType public EmptyModuleType() { this(EMPTY_MODULE); } diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/FileUrlLocationTest.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/FileUrlLocationTest.java index dc9b834fcea3..58a0170ccdec 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/FileUrlLocationTest.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/FileUrlLocationTest.java @@ -25,7 +25,7 @@ import com.intellij.testFramework.LightProjectDescriptor; public class FileUrlLocationTest extends SMLightFixtureTestCase { @Override protected LightProjectDescriptor getProjectDescriptor() { - return ourDescriptor; + return LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; } public void testSpecNavigation() throws Throwable { diff --git a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/SMLightFixtureTestCase.java b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/SMLightFixtureTestCase.java index 0019a618db55..03bc6b5c967b 100644 --- a/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/SMLightFixtureTestCase.java +++ b/platform/smRunner/testSrc/com/intellij/execution/testframework/sm/SMLightFixtureTestCase.java @@ -15,12 +15,7 @@ */ package com.intellij.execution.testframework.sm; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.psi.PsiFile; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.PlatformTestCase; @@ -43,22 +38,6 @@ public abstract class SMLightFixtureTestCase extends UsefulTestCase { PlatformTestCase.initPlatformLangPrefix(); } - protected static final LightProjectDescriptor ourDescriptor = new LightProjectDescriptor() { - @Override - public ModuleType getModuleType() { - return ModuleType.EMPTY; - } - - @Override - public Sdk getSdk() { - return null; - } - - @Override - public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { - //Do nothing - } - }; protected CodeInsightTestFixture myFixture; @Override diff --git a/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java b/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java index 737cf97e5ef9..d0a714175025 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java @@ -15,6 +15,7 @@ */ package com.intellij.testFramework; +import com.intellij.openapi.module.EmptyModuleType; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.projectRoots.Sdk; @@ -28,4 +29,20 @@ public interface LightProjectDescriptor { ModuleType getModuleType(); Sdk getSdk(); void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry); + + LightProjectDescriptor EMPTY_PROJECT_DESCRIPTOR = new LightProjectDescriptor() { + @Override + public ModuleType getModuleType() { + return EmptyModuleType.getInstance(); + } + + @Override + public Sdk getSdk() { + return null; + } + + @Override + public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { + } + }; } diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/IdeaTestFixtureFactoryImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/IdeaTestFixtureFactoryImpl.java index 921c00a8a5d4..128066fd5d95 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/IdeaTestFixtureFactoryImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/IdeaTestFixtureFactoryImpl.java @@ -16,12 +16,6 @@ package com.intellij.testFramework.fixtures.impl; -import com.intellij.openapi.module.EmptyModuleType; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.builders.EmptyModuleFixtureBuilder; import com.intellij.testFramework.builders.ModuleFixtureBuilder; @@ -69,13 +63,14 @@ public class IdeaTestFixtureFactoryImpl extends IdeaTestFixtureFactory { @Override public TestFixtureBuilder createLightFixtureBuilder() { - return new LightTestFixtureBuilderImpl(new LightIdeaTestFixtureImpl(ourEmptyProjectDescriptor)); + return new LightTestFixtureBuilderImpl(new LightIdeaTestFixtureImpl( + LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR)); } @Override public TestFixtureBuilder createLightFixtureBuilder(@Nullable LightProjectDescriptor projectDescriptor) { if (projectDescriptor == null) { - projectDescriptor = ourEmptyProjectDescriptor; + projectDescriptor = LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR; } return new LightTestFixtureBuilderImpl(new LightIdeaTestFixtureImpl(projectDescriptor)); } @@ -105,20 +100,4 @@ public class IdeaTestFixtureFactoryImpl extends IdeaTestFixtureFactory { return new ModuleFixtureImpl(this); } } - - private static final LightProjectDescriptor ourEmptyProjectDescriptor = new LightProjectDescriptor() { - @Override - public ModuleType getModuleType() { - return EmptyModuleType.getInstance(); - } - - @Override - public Sdk getSdk() { - return null; - } - - @Override - public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { - } - }; } From 15719609530f46adc05bf3307c6037155a445c3d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 16 Feb 2011 20:40:56 +0300 Subject: [PATCH 48/90] usage view sync dispose --- .../intellij/usages/impl/UsageViewImpl.java | 98 ++++++++++--------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index 44c89df82d8c..d7d72a975fa9 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -125,6 +125,7 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra private JPanel myCentralPanel; private final GroupNode myRoot; private final UsageViewTreeModelBuilder myModel; + private final Object lock = new Object(); public UsageViewImpl(@NotNull final Project project, @NotNull UsageViewPresentation presentation, @@ -171,53 +172,56 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra if (!myPresentation.isDetachedMode()) { UIUtil.invokeLaterIfNeeded(new Runnable() { public void run() { - if (isDisposed) return; - myTree.setModel(myModel); + // lock here to avoid concurrent execution of this init and dispose in other thread + synchronized (lock) { + if (isDisposed) return; + myTree.setModel(myModel); - myRootPanel.setLayout(new BorderLayout()); + myRootPanel.setLayout(new BorderLayout()); - final SimpleToolWindowPanel twPanel = new SimpleToolWindowPanel(false, true); - myRootPanel.add(twPanel, BorderLayout.CENTER); + final SimpleToolWindowPanel twPanel = new SimpleToolWindowPanel(false, true); + myRootPanel.add(twPanel, BorderLayout.CENTER); - JPanel toolbarPanel = new JPanel(new BorderLayout()); - toolbarPanel.add(createActionsToolbar(), BorderLayout.WEST); - toolbarPanel.add(createFiltersToolbar(), BorderLayout.CENTER); - twPanel.setToolbar(toolbarPanel); + JPanel toolbarPanel = new JPanel(new BorderLayout()); + toolbarPanel.add(createActionsToolbar(), BorderLayout.WEST); + toolbarPanel.add(createFiltersToolbar(), BorderLayout.CENTER); + twPanel.setToolbar(toolbarPanel); - myCentralPanel = new JPanel(); - myCentralPanel.setLayout(new BorderLayout()); - setupCentralPanel(); + myCentralPanel = new JPanel(); + myCentralPanel.setLayout(new BorderLayout()); + setupCentralPanel(); - initTree(); - twPanel.setContent(myCentralPanel); + initTree(); + twPanel.setContent(myCentralPanel); - myTree.setCellRenderer(new UsageViewTreeCellRenderer(UsageViewImpl.this)); - collapseAll(); + myTree.setCellRenderer(new UsageViewTreeCellRenderer(UsageViewImpl.this)); + collapseAll(); - myModelTracker.addListener(UsageViewImpl.this); + myModelTracker.addListener(UsageViewImpl.this); - if (myPresentation.isShowCancelButton()) { - addButtonToLowerPane(new Runnable() { - public void run() { - close(); - } - }, UsageViewBundle.message("usage.view.cancel.button")); - } - - myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { - public void valueChanged(final TreeSelectionEvent e) { - SwingUtilities.invokeLater(new Runnable() { + if (myPresentation.isShowCancelButton()) { + addButtonToLowerPane(new Runnable() { public void run() { - if (isDisposed) return; - List infos = getSelectedUsageInfos(); - if (infos != null && myUsagePreviewPanel != null) { - myUsagePreviewPanel.updateLayout(infos); - } + close(); } - }); + }, UsageViewBundle.message("usage.view.cancel.button")); } - }); + + myTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(final TreeSelectionEvent e) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (isDisposed) return; + List infos = getSelectedUsageInfos(); + if (infos != null && myUsagePreviewPanel != null) { + myUsagePreviewPanel.updateLayout(infos); + } + } + }); + } + }); + } } }); } @@ -783,17 +787,19 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra } public void dispose() { - isDisposed = true; - ToolTipManager.sharedInstance().unregisterComponent(myTree); - myModelTracker.removeListener(this); - myUpdateAlarm.cancelAllRequests(); - if (myUsagePreviewPanel != null) { - UsageViewSettings.getInstance().PREVIEW_USAGES_SPLITTER_PROPORTIONS = ((Splitter)myUsagePreviewPanel.getParent()).getProportion(); - myUsagePreviewPanel = null; - } - for (Usage usage : getUsages()) { - if (usage instanceof UsageInfo2UsageAdapter) { - ((UsageInfo2UsageAdapter)usage).dispose(); + synchronized (lock) { + isDisposed = true; + ToolTipManager.sharedInstance().unregisterComponent(myTree); + myModelTracker.removeListener(this); + myUpdateAlarm.cancelAllRequests(); + if (myUsagePreviewPanel != null) { + UsageViewSettings.getInstance().PREVIEW_USAGES_SPLITTER_PROPORTIONS = ((Splitter)myUsagePreviewPanel.getParent()).getProportion(); + myUsagePreviewPanel = null; + } + for (Usage usage : getUsages()) { + if (usage instanceof UsageInfo2UsageAdapter) { + ((UsageInfo2UsageAdapter)usage).dispose(); + } } } } From 059ed11736ad0078f2c50fb6f3d1c6353ef261ec Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 17 Feb 2011 13:57:20 +0300 Subject: [PATCH 49/90] light project in the middle of another test --- .../util/indexing/FileBasedIndex.java | 32 +++++++++++----- .../application/impl/ApplicationImpl.java | 7 +++- .../components/impl/ComponentManagerImpl.java | 12 ++++-- .../openapi/progress/BackgroundTaskQueue.java | 9 +++-- .../openapi/project/ex/ProjectEx.java | 2 +- .../openapi/project/impl/ProjectImpl.java | 7 ++-- .../src/com/intellij/mock/MockProject.java | 2 +- .../testFramework/LightPlatformTestCase.java | 37 ++++++++----------- .../testFramework/PlatformTestCase.java | 2 +- .../maven/indices/MavenIndicesManager.java | 16 +++----- 10 files changed, 72 insertions(+), 54 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java index 9babf16bbf86..d54a659b2deb 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndex.java @@ -1052,11 +1052,26 @@ public class FileBasedIndex implements ApplicationComponent { } } - private Set getUnsavedOrTransactedDocuments() { + private Set getUnsavedOrTransactedDocuments(Project project) { Set docs = new HashSet(Arrays.asList(myFileDocumentManager.getUnsavedDocuments())); synchronized (myTransactionMap) { docs.addAll(myTransactionMap.keySet()); } + + if (project != null) { + // filter out foreign documents + Iterator iterator = docs.iterator(); + ProjectLocator projectLocator = ProjectLocator.getInstance(); + while (iterator.hasNext()) { + Document document = iterator.next(); + VirtualFile virtualFile = myFileDocumentManager.getFile(document); + if (virtualFile == null) continue; + Project guessed = projectLocator.guessProjectForFile(virtualFile); + if (guessed != null && guessed != project) { + iterator.remove(); + } + } + } return docs; } @@ -1066,7 +1081,7 @@ public class FileBasedIndex implements ApplicationComponent { return; // no need to index unsaved docs } - final Set documents = getUnsavedOrTransactedDocuments(); + final Set documents = getUnsavedOrTransactedDocuments(project); if (!documents.isEmpty()) { // now index unsaved data final StorageGuard.Holder guard = setDataBufferingEnabled(true); @@ -1075,8 +1090,8 @@ public class FileBasedIndex implements ApplicationComponent { assert semaphore != null : "Semaphore for unsaved data indexing was not initialized for index " + indexId; - boolean allDocsProcessed = true; semaphore.down(); + boolean allDocsProcessed = true; try { for (Document document : documents) { allDocsProcessed &= indexUnsavedDocument(document, indexId, project, filter); @@ -1215,14 +1230,13 @@ public class FileBasedIndex implements ApplicationComponent { public static final Key VIRTUAL_FILE = new Key("Context virtual file"); @Nullable - private PsiFile findDominantPsiForDocument(final Document document, @Nullable Project project) { + private PsiFile findDominantPsiForDocument(@NotNull Document document, @Nullable Project project) { synchronized (myTransactionMap) { - if (myTransactionMap.containsKey(document)) { - return myTransactionMap.get(document); - } + PsiFile psiFile = myTransactionMap.get(document); + if (psiFile != null) return psiFile; } - return project == null? null : findLatestKnownPsiForUncomittedDocument(document, project); + return project == null ? null : findLatestKnownPsiForUncomittedDocument(document, project); } private final StorageGuard myStorageLock = new StorageGuard(); @@ -1873,7 +1887,7 @@ public class FileBasedIndex implements ApplicationComponent { } @Nullable - private static PsiFile findLatestKnownPsiForUncomittedDocument(Document doc, Project project) { + private static PsiFile findLatestKnownPsiForUncomittedDocument(@NotNull Document doc, @NotNull Project project) { return PsiDocumentManager.getInstance(project).getCachedPsiFile(doc); } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index c32c952d4cb2..eee3ef34f7d8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -1209,6 +1209,11 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application @Override public String toString() { - return "Application"; + return "Application" + + (isDisposed() ? " (Disposed)" : "") + + (isUnitTestMode() ? " (Unit test)" : "") + + (isInternal() ? " (Internal)" : "") + + (isHeadlessEnvironment() ? " (Headless)" : "") + + (isCommandLine() ? " (Command line)" : ""); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java index 0cecdf25f2d8..6d90ee6f7eb6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/components/impl/ComponentManagerImpl.java @@ -41,6 +41,7 @@ import com.intellij.util.pico.IdeaPicoContainer; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.picocontainer.*; import org.picocontainer.defaults.CachingComponentAdapter; import org.picocontainer.defaults.ConstructorInjectionComponentAdapter; @@ -211,7 +212,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements } public T getComponent(Class interfaceClass) { - assert !myDisposeCompleted : "Already disposed"; + assert !myDisposeCompleted : "Already disposed: "+this; return getComponent(interfaceClass, null); } @@ -375,9 +376,14 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements } public boolean isDisposed() { - return myDisposed; + return myDisposed || temporarilyDisposed; } + private volatile boolean temporarilyDisposed = false; + @TestOnly + public void setTemporarilyDisposed(boolean disposed) { + temporarilyDisposed = disposed; + } public void initComponents() { createComponents(); @@ -391,7 +397,7 @@ public abstract class ComponentManagerImpl extends UserDataHolderBase implements protected void boostrapPicoContainer() { myPicoContainer = createPicoContainer(); - myMessageBus = MessageBusFactory.newMessageBus(this, myParentComponentManager != null ? myParentComponentManager.getMessageBus() : null); + myMessageBus = MessageBusFactory.newMessageBus(this, myParentComponentManager == null ? null : myParentComponentManager.getMessageBus()); final MutablePicoContainer picoContainer = getPicoContainer(); picoContainer.registerComponentInstance(MessageBus.class, myMessageBus); /* diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java index 1d1e2b5a0e29..0b38bee82dd0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java @@ -24,6 +24,8 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.PairConsumer; import com.intellij.util.concurrency.QueueProcessor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Runs backgroundable tasks one by one. @@ -40,18 +42,19 @@ public class BackgroundTaskQueue { private final QueueProcessor myProcessor; private Boolean myForcedTestMode; - public BackgroundTaskQueue(final Project project, String title) { + public BackgroundTaskQueue(@Nullable Project project, @NotNull String title) { this(project, title, null); } - public BackgroundTaskQueue(final Project project, String title, final Boolean forcedHeadlessMode) { + public BackgroundTaskQueue(@Nullable final Project project, @NotNull String title, final Boolean forcedHeadlessMode) { final boolean headless = forcedHeadlessMode != null ? forcedHeadlessMode : ApplicationManager.getApplication().isHeadlessEnvironment(); myProcessor = new QueueProcessor(headless ? new BackgroundableHeadlessRunner() : new BackgroundableUnderProgressRunner(title, project), true, headless ? QueueProcessor.ThreadToUse.POOLED : QueueProcessor.ThreadToUse.AWT, new Condition() { @Override public boolean value(Object o) { - return (! ApplicationManager.getApplication().isUnitTestMode()) && (! project.isOpen()) || project.isDisposed(); + if (project == null) return ApplicationManager.getApplication().isDisposed(); + return !ApplicationManager.getApplication().isUnitTestMode() && !project.isOpen() || project.isDisposed(); } }); } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectEx.java b/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectEx.java index 2adaf0e140b1..dafbeb029bb8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectEx.java @@ -37,5 +37,5 @@ public interface ProjectEx extends Project { void checkUnknownMacros(final boolean showDialog); - void setProjectName(String name); + void setProjectName(@NotNull String name); } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java index f26b222bd078..5ce29e80bfb2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectImpl.java @@ -103,7 +103,7 @@ public class ProjectImpl extends ComponentManagerImpl implements ProjectEx { if (!isDefault() && projectName != null && getStateStore().getStorageScheme().equals(StorageScheme.DIRECTORY_BASED)) myOldName = ""; // new project } - public void setProjectName(final String projectName) { + public void setProjectName(@NotNull String projectName) { if (!projectName.equals(myName)) { myOldName = myName; myName = projectName; @@ -454,8 +454,9 @@ public class ProjectImpl extends ComponentManagerImpl implements ProjectEx { @Override public String toString() { return "Project " - + (isDisposed() ? "(Disposed) " : "") - + (isDefault() ? "(Default) " : "'" + getLocation()+"'") + + (isDisposed() ? "(Disposed) " : "'" + getLocation()+"'") + + (isDefault() ? " (Default)" : "") + + " " + myName ; } diff --git a/platform/testFramework/src/com/intellij/mock/MockProject.java b/platform/testFramework/src/com/intellij/mock/MockProject.java index 51edbd17e8f0..afe7d9274caf 100644 --- a/platform/testFramework/src/com/intellij/mock/MockProject.java +++ b/platform/testFramework/src/com/intellij/mock/MockProject.java @@ -38,7 +38,7 @@ public class MockProject extends MockComponentManager implements ProjectEx { } @Override - public void setProjectName(String name) { + public void setProjectName(@NotNull String name) { } @Override diff --git a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java index cd1da081ce42..22becea304f7 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightPlatformTestCase.java @@ -55,6 +55,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ex.ProjectEx; import com.intellij.openapi.project.ex.ProjectManagerEx; +import com.intellij.openapi.project.impl.ProjectImpl; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.*; import com.intellij.openapi.startup.StartupManager; @@ -87,6 +88,7 @@ import com.intellij.util.containers.CollectionFactory; import com.intellij.util.indexing.FileBasedIndex; import com.intellij.util.indexing.IndexableFileSet; import com.intellij.util.messages.MessageBusConnection; +import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; import junit.framework.TestCase; import org.jetbrains.annotations.NonNls; @@ -98,7 +100,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -340,6 +341,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da if (ourProject == null || !ourProjectDescriptor.equals(descriptor)) { initProject(descriptor); } + ((ProjectImpl)ourProject).setTemporarilyDisposed(false); ProjectManagerEx.getInstanceEx().setCurrentTestProject(ourProject); @@ -490,17 +492,12 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da ((PsiDocumentManagerImpl)PsiDocumentManager.getInstance(project)).clearUncommitedDocuments(); ((HintManagerImpl)HintManager.getInstance()).cleanup(); - Runnable runnable = new Runnable() { + UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { ((UndoManagerImpl)UndoManager.getGlobalInstance()).dropHistoryInTests(); } - }; - if (ApplicationManager.getApplication().isDispatchThread()) { - runnable.run(); - } else { - SwingUtilities.invokeAndWait(runnable); - } + }); TemplateDataLanguageMappings.getInstance(project).cleanupForNextTest(); @@ -514,6 +511,9 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da if (checkForEditors) { checkEditorsReleased(); } + if (isLight(project)) { + ((ProjectImpl)project).setTemporarilyDisposed(true); // mark temporarily as disposed so that rogue component trying to access it will fail + } } public static void checkEditorsReleased() { @@ -654,6 +654,7 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da public static synchronized void closeAndDeleteProject() { if (ourProject != null) { + ((ProjectImpl)ourProject).setTemporarilyDisposed(false); final VirtualFile projFile = ((ProjectEx)ourProject).getStateStore().getProjectFile(); final File projectFile = projFile == null ? null : VfsUtil.virtualToIoFile(projFile); if (!ourProject.isDisposed()) Disposer.dispose(ourProject); @@ -674,20 +675,12 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da ShutDownTracker.getInstance().registerShutdownTask(new Runnable() { @Override public void run() { - try { - SwingUtilities.invokeAndWait(new Runnable() { - @Override - public void run() { - closeAndDeleteProject(); - } - }); - } - catch (InterruptedException e) { - e.printStackTrace(); - } - catch (InvocationTargetException e) { - e.printStackTrace(); - } + UIUtil.invokeAndWaitIfNeeded(new Runnable() { + @Override + public void run() { + closeAndDeleteProject(); + } + }); } }); } diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 09431aaf29fe..53c481f95d52 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -288,7 +288,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } public static void cleanupApplicationCaches(Project project) { - if (project != null) { + if (project != null && !project.isDisposed()) { ((UndoManagerImpl)UndoManager.getInstance(project)).dropHistoryInTests(); ((PsiManagerEx)PsiManager.getInstance(project)).getFileManager().cleanupForNextTest(); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndicesManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndicesManager.java index be5352929912..5dd6b7f4e595 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndicesManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/indices/MavenIndicesManager.java @@ -23,7 +23,6 @@ import com.intellij.openapi.progress.BackgroundTaskQueue; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.JDOMUtil; @@ -46,7 +45,6 @@ import org.jetbrains.idea.maven.utils.*; import java.io.File; import java.io.IOException; -import java.rmi.RemoteException; import java.util.*; public class MavenIndicesManager { @@ -73,8 +71,7 @@ public class MavenIndicesManager { private final Object myUpdatingIndicesLock = new Object(); private final List myWaitingIndices = new ArrayList(); private volatile MavenIndex myUpdatingIndex; - private final BackgroundTaskQueue myUpdatingQueue = new BackgroundTaskQueue(ProjectManager.getInstance().getDefaultProject(), - IndicesBundle.message("maven.indices.updating")); + private final BackgroundTaskQueue myUpdatingQueue = new BackgroundTaskQueue(null, IndicesBundle.message("maven.indices.updating")); private volatile List myUserArchetypes = new ArrayList(); @@ -102,7 +99,7 @@ public class MavenIndicesManager { myIndexer = MavenFacadeManager.getInstance().createIndexer(); myDownloadListener = new MavenFacadeDownloadListener() { - public void artifactDownloaded(File file, String relativePath) throws RemoteException { + public void artifactDownloaded(File file, String relativePath) { addArtifact(file, relativePath); } }; @@ -205,7 +202,7 @@ public class MavenIndicesManager { } } - private String getRepositoryUrl(File artifactFile, String name) { + private static String getRepositoryUrl(File artifactFile, String name) { List parts = getArtifactParts(name); File result = artifactFile; @@ -215,7 +212,7 @@ public class MavenIndicesManager { return result.getPath(); } - private List getArtifactParts(String name) { + private static List getArtifactParts(String name) { return StringUtil.split(name, "/"); } @@ -284,11 +281,10 @@ public class MavenIndicesManager { } } - private MavenGeneralSettings getMavenSettings(@NotNull final Project project, @NotNull MavenProgressIndicator indicator) + private static MavenGeneralSettings getMavenSettings(@NotNull final Project project, @NotNull MavenProgressIndicator indicator) throws MavenProcessCanceledException { - MavenGeneralSettings settings; - settings = ApplicationManager.getApplication().runReadAction(new Computable() { + MavenGeneralSettings settings = ApplicationManager.getApplication().runReadAction(new Computable() { @Override public MavenGeneralSettings compute() { if (project.isDisposed()) return null; From 226a2a3167502f635463b68d826ce3f47e7918b9 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 17 Feb 2011 14:40:02 +0300 Subject: [PATCH 50/90] make sure focus will be oth selected file (IDEA-25757) --- .../src/com/intellij/ide/actions/Switcher.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java index 42fbeae96ca5..3be56bce173b 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java @@ -38,6 +38,7 @@ import com.intellij.openapi.util.Iconable; import com.intellij.openapi.vcs.FileStatus; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ex.WindowManagerEx; @@ -588,7 +589,12 @@ public class Switcher extends AnAction implements DumbAware { } else if (value instanceof VirtualFile) { final VirtualFile file = (VirtualFile)value; - FileEditorManager.getInstance(project).openFile(file, true, true); + IdeFocusManager.getInstance(project).doWhenFocusSettlesDown(new Runnable() { + @Override + public void run() { + FileEditorManager.getInstance(project).openFile(file, true, true); + } + }); } } From a68e914e0ab8b1e7f049c62689460411c448e75e Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Thu, 17 Feb 2011 12:48:17 +0100 Subject: [PATCH 51/90] CIDR: initial build errors view --- .../configurations/CommandLineTokenizer.java | 87 +++++++++++++++++++ .../openapi/util/text/StringUtil.java | 21 +++++ 2 files changed, 108 insertions(+) create mode 100644 platform/platform-api/src/com/intellij/execution/configurations/CommandLineTokenizer.java diff --git a/platform/platform-api/src/com/intellij/execution/configurations/CommandLineTokenizer.java b/platform/platform-api/src/com/intellij/execution/configurations/CommandLineTokenizer.java new file mode 100644 index 000000000000..0fc5654e909f --- /dev/null +++ b/platform/platform-api/src/com/intellij/execution/configurations/CommandLineTokenizer.java @@ -0,0 +1,87 @@ +package com.intellij.execution.configurations; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** + * Splits input String to tokens being aware of quoted tokens, + * usually used for splitting command line to separate arguments that may contain space symbols. + * Escaped symbols are not handled so there's no way to get token that itself contains quotation mark. + */ +public class CommandLineTokenizer extends StringTokenizer { + + private static String DEFAULT_DELIMITERS = " \t\n\r\f"; + // keep source level 1.4 + private List myTokens = new ArrayList(); + private int myCurrentToken = 0; + + public CommandLineTokenizer(String str) { + super(str, DEFAULT_DELIMITERS, true); + parseTokens(); + } + + public CommandLineTokenizer(String str, String delim) { + super(str, delim, true); + parseTokens(); + } + + public boolean hasMoreTokens() { + return myCurrentToken < myTokens.size(); + } + + public String nextToken() { + return (String) myTokens.get(myCurrentToken++); + } + + public int countTokens() { + return myTokens.size() - myCurrentToken; + } + + + public String nextToken(String delim) { + throw new UnsupportedOperationException(); + } + + private void parseTokens() { + String token; + while ((token = nextTokenInternal()) != null) { + myTokens.add(token); + } + } + + private String nextTokenInternal() { + String nextToken; + do { + if (super.hasMoreTokens()) { + nextToken = super.nextToken(); + } else { + nextToken = null; + } + } while (nextToken != null && nextToken.length() == 1 && DEFAULT_DELIMITERS.indexOf(nextToken.charAt(0)) >= 0); + + if (nextToken == null) { + return null; + } + + int i; + int quotationMarks = 0; + final StringBuffer buffer = new StringBuffer(); + + do { + while ((i = nextToken.indexOf('"')) >= 0) { + quotationMarks++; + buffer.append(nextToken.substring(0, i)); + nextToken = nextToken.substring(i + 1); + } + buffer.append(nextToken); + if (quotationMarks % 2 == 1 && super.hasMoreTokens()) { + nextToken = super.nextToken(); + } else { + nextToken = null; + } + } while (nextToken != null); + + return buffer.toString(); + } +} \ No newline at end of file diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 50525a8295f3..078c4ec16588 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -975,6 +975,27 @@ public class StringUtil { }; } + @NotNull + public static Iterable tokenize(@NotNull String s, final StringTokenizer tokenizer) { + return new Iterable() { + public Iterator iterator() { + return new Iterator() { + public boolean hasNext() { + return tokenizer.hasMoreTokens(); + } + + public String next() { + return tokenizer.nextToken(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }; + } + @NotNull public static List getWordsIn(@NotNull String text) { List result = new SmartList(); From 2ffb6802517e1288528b984bb7c328f1c8986ffa Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Thu, 17 Feb 2011 15:26:17 +0300 Subject: [PATCH 52/90] IDEA-57891 Reformat file: run under modal progress 1. Corrected 'format without progress' processing; 2. Don't hold hard refs to the target file and document; --- .../intellij/formatting/FormatProcessor.java | 22 +++++++++++----- .../intellij/formatting/FormatterImpl.java | 1 + .../FormattingProgressIndicatorImpl.java | 25 +++++++++++-------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java index f59a387a9fb4..19f37c372305 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatProcessor.java @@ -223,9 +223,7 @@ class FormatProcessor { return; } - while (myCurrentState.getStateId() == FormattingStateId.PROCESSING_BLOCKS && !myCurrentState.isDone()) { - myCurrentState.iteration(); - } + doIterationsSynchronously(FormattingStateId.PROCESSING_BLOCKS); } private void reset() { @@ -246,15 +244,27 @@ class FormatProcessor { assert !myDisposed; myCurrentState.setNext(new ApplyChangesState(model)); - if (!sequentially) { + if (sequentially) { return; } - while (myCurrentState.getStateId() == FormattingStateId.APPLYING_CHANGES && !myCurrentState.isDone()) { + doIterationsSynchronously(FormattingStateId.APPLYING_CHANGES); + } + + /** + * Perform iterations against the {@link #myCurrentState current state} until it's {@link FormattingStateId type} + * is {@link FormattingStateId#getPreviousStates() less} or equal to the given state. + * + * @param state target state to process + */ + private void doIterationsSynchronously(@NotNull FormattingStateId state) { + while ((myCurrentState.getStateId() == state || state.getPreviousStates().contains(myCurrentState.getStateId())) + && !myCurrentState.isDone()) + { myCurrentState.iteration(); } } - + public void setJavaIndentOptions(final CodeStyleSettings.IndentOptions javaIndentOptions) { myJavaIndentOptions = javaIndentOptions; } diff --git a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java index 052a2ca8a559..02a7cc6ff350 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormatterImpl.java @@ -214,6 +214,7 @@ public class FormatterImpl extends FormatterEx } finally { enableFormatting(); + myProgressIndicator = null; } } else { diff --git a/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java index 6916a1dcedcb..1a57f2c4a1bc 100644 --- a/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java +++ b/platform/lang-impl/src/com/intellij/formatting/FormattingProgressIndicatorImpl.java @@ -35,6 +35,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.HashMap; @@ -81,10 +82,9 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma private final Map> myCallbacks = new HashMap>(); - @Nullable - private final VirtualFile myFile; - private final Document myDocument; - private final int myFileTextLength; + private final WeakReference myFile; + private final WeakReference myDocument; + private final int myFileTextLength; @NotNull private FormattingStateId myLastState = FormattingStateId.WRAPPING_BLOCKS; @@ -98,8 +98,8 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma public FormattingProgressIndicatorImpl(@Nullable Project project, @NotNull PsiFile file, @NotNull Document document) { super(project, getTitle(file), true); - myFile = file.getVirtualFile(); - myDocument = document; + myFile = new WeakReference(file.getVirtualFile()); + myDocument = new WeakReference(document); myFileTextLength = file.getTextLength(); addCallback(EventType.CANCEL, new MyCancelCallback()); } @@ -140,7 +140,10 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma UIUtil.invokeAndWaitIfNeeded(new Runnable() { @Override public void run() { - myDocumentModificationStampBefore = myDocument.getModificationStamp(); + Document document = myDocument.get(); + if (document != null) { + myDocumentModificationStampBefore = document.getModificationStamp(); + } task.prepare(); } }); @@ -282,16 +285,18 @@ public class FormattingProgressIndicatorImpl extends Task.Modal implements Forma @Override public void run() { myRunning = false; - if (myFile == null || myDocumentModificationStampBefore < 0) { + VirtualFile file = myFile.get(); + Document document = myDocument.get(); + if (file == null || document == null || myDocumentModificationStampBefore < 0) { return; } - FileEditor editor = FileEditorManager.getInstance(myProject).getSelectedEditor(myFile); + FileEditor editor = FileEditorManager.getInstance(myProject).getSelectedEditor(file); if (editor == null) { return; } UndoManager manager = UndoManager.getInstance(myProject); - while (manager.isUndoAvailable(editor) && myDocument.getModificationStamp() != myDocumentModificationStampBefore) { + while (manager.isUndoAvailable(editor) && document.getModificationStamp() != myDocumentModificationStampBefore) { manager.undo(editor); } } From 908fc66b200164cc5fe31ec443fc017b3fcbb482 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 17 Feb 2011 15:31:23 +0300 Subject: [PATCH 53/90] background task queue: allow to specify modality and custom progress for the task --- .../util/concurrency/QueueProcessor.java | 41 +++++++++++++++++-- .../openapi/progress/BackgroundTaskQueue.java | 32 +++++++++++---- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java b/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java index 60e026f93b3e..b1d095ac5870 100644 --- a/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java +++ b/platform/platform-api/src/com/intellij/util/concurrency/QueueProcessor.java @@ -17,15 +17,18 @@ package com.intellij.util.concurrency; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Getter; +import com.intellij.openapi.util.Pair; import com.intellij.util.AsynchConsumer; import com.intellij.util.Consumer; import com.intellij.util.PairConsumer; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; +import java.util.*; /** *

QueueProcessor processes elements which are being added to a queue via {@link #add(Object)} and {@link #addFirst(Object)} methods.

@@ -48,6 +51,7 @@ public class QueueProcessor { private final ThreadToUse myThreadToUse; private final Condition myDeathCondition; + private final Map myModalityState; /** * Constructs a QueueProcessor with the given processor and autostart setting. @@ -65,6 +69,7 @@ public class QueueProcessor { myStarted = autostart; myThreadToUse = threadToUse; myDeathCondition = deathCondition; + myModalityState = new HashMap(); myContinuationContext = new Runnable() { @Override @@ -85,6 +90,11 @@ public class QueueProcessor { this(wrappingProcessor(processor), autostart, ThreadToUse.POOLED, deathCondition); } + public void add(T t, ModalityState state) { + myModalityState.put(new MyOverrideEquals(t), state); + doAdd(t, false); + } + private static PairConsumer wrappingProcessor(final Consumer processor) { return new PairConsumer() { @Override @@ -176,7 +186,12 @@ public class QueueProcessor { }; final Application application = ApplicationManager.getApplication(); if (ThreadToUse.AWT.equals(myThreadToUse)) { - application.invokeLater(runnable); + final ModalityState state = myModalityState.remove(new MyOverrideEquals(item)); + if (state != null) { + application.invokeLater(runnable, state); + } else { + application.invokeLater(runnable); + } } else { application.executeOnPooledThread(runnable); } @@ -193,4 +208,22 @@ public class QueueProcessor { AWT, POOLED } + + private static class MyOverrideEquals { + private final Object myDelegate; + + private MyOverrideEquals(Object delegate) { + myDelegate = delegate; + } + + @Override + public int hashCode() { + return myDelegate.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return ((MyOverrideEquals) obj).myDelegate == myDelegate; + } + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java index 0b38bee82dd0..dd2c56c12d81 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/BackgroundTaskQueue.java @@ -17,16 +17,21 @@ package com.intellij.openapi.progress; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Getter; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.PairConsumer; import com.intellij.util.concurrency.QueueProcessor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; + /** * Runs backgroundable tasks one by one. * To add a task to the queue use {@link #run(com.intellij.openapi.progress.Task.Backgroundable)} @@ -39,7 +44,7 @@ import org.jetbrains.annotations.Nullable; public class BackgroundTaskQueue { private static final Logger LOG = Logger.getInstance(BackgroundTaskQueue.class.getName()); //private final Project myProject; - private final QueueProcessor myProcessor; + private final QueueProcessor>> myProcessor; private Boolean myForcedTestMode; public BackgroundTaskQueue(@Nullable Project project, @NotNull String title) { @@ -48,7 +53,7 @@ public class BackgroundTaskQueue { public BackgroundTaskQueue(@Nullable final Project project, @NotNull String title, final Boolean forcedHeadlessMode) { final boolean headless = forcedHeadlessMode != null ? forcedHeadlessMode : ApplicationManager.getApplication().isHeadlessEnvironment(); - myProcessor = new QueueProcessor(headless ? + myProcessor = new QueueProcessor>>(headless ? new BackgroundableHeadlessRunner() : new BackgroundableUnderProgressRunner(title, project), true, headless ? QueueProcessor.ThreadToUse.POOLED : QueueProcessor.ThreadToUse.AWT, new Condition() { @Override @@ -68,23 +73,28 @@ public class BackgroundTaskQueue { } public void run(Task.Backgroundable task) { + run(task, null, null); + } + + public void run(Task.Backgroundable task, final ModalityState state, final Getter pi) { if (isTestMode()) { // test tasks are executed in this thread without the progress manager RunBackgroundable.runIfBackgroundThread(task, new EmptyProgressIndicator(), null); } else { - myProcessor.add(task); + myProcessor.add(new Pair>(task, pi), state); } } - private static class BackgroundableHeadlessRunner implements PairConsumer { + private static class BackgroundableHeadlessRunner implements PairConsumer>, Runnable> { @Override - public void consume(Task.Backgroundable backgroundable, Runnable runnable) { + public void consume(Pair> pair, Runnable runnable) { + final Task.Backgroundable backgroundable = pair.getFirst(); // synchronously ProgressManager.getInstance().run(backgroundable); runnable.run(); } } - private static class BackgroundableUnderProgressRunner implements PairConsumer { + private static class BackgroundableUnderProgressRunner implements PairConsumer>, Runnable> { private final String myTitle; private final Project myProject; @@ -94,7 +104,8 @@ public class BackgroundTaskQueue { } @Override - public void consume(final Task.Backgroundable backgroundable, final Runnable runnable) { + public void consume(final Pair> pair, final Runnable runnable) { + final Task.Backgroundable backgroundable = pair.getFirst(); final ProgressIndicator[] pi = new ProgressIndicator[1]; final boolean taskTitleIsEmpty = StringUtil.isEmptyOrSpaces(backgroundable.getTitle()); @@ -112,7 +123,12 @@ public class BackgroundTaskQueue { pm.runProcessWithProgressSynchronously(wrappedTask, taskTitleIsEmpty ? myTitle : backgroundable.getTitle(), backgroundable.isCancellable(), myProject); } else { - pi[0] = new BackgroundableProcessIndicator(backgroundable); + if (pair.getSecond() != null) { + pi[0] = pair.getSecond().get(); + } + if (pi[0] == null) { + pi[0] = new BackgroundableProcessIndicator(backgroundable); + } if (taskTitleIsEmpty) { ((BackgroundableProcessIndicator) pi[0]).setTitle(myTitle); } From 36dc21842d48661287af550d331576618865d727 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 17 Feb 2011 14:21:52 +0100 Subject: [PATCH 54/90] exception logging --- .../compiler/impl/javaCompiler/CompilerParsingThread.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java index 5c786f9a2207..f1433405afb9 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -244,6 +244,12 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { } return -1; // When process terminated Process.getInputStream()'s underlying stream becomes closed on Linux. } + catch (Throwable t) { + if (CompileDriver.ourDebugMode) { + t.printStackTrace(); + } + return -1; + } } private boolean isProcessTerminated() { From cb2ba08030f661c05a2c4308fb6edaf15bb88ae3 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 17 Feb 2011 14:28:45 +0100 Subject: [PATCH 55/90] exception logging 2 --- .../compiler/impl/javaCompiler/CompilerParsingThread.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java index f1433405afb9..6e43ed55f0df 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -105,6 +105,9 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { } public final String getNextLine() { + if (CompileDriver.ourDebugMode) { + System.out.println("Before reading line"); + } final String pushBack = myPushBackLine; if (pushBack != null) { myPushBackLine = null; @@ -227,7 +230,9 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { if (!CompileDriver.ourDebugMode) { while(!reader.ready()) { if (isProcessTerminated()) { - return -1; + //if (!reader.ready()) { + return -1; + //} } try { Thread.sleep(1L); From 5ddf7124335bf60484b31df13a9cabdf496e2691 Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Thu, 17 Feb 2011 16:40:26 +0300 Subject: [PATCH 56/90] usages statistics refactored + fixed tests --- .../ApplicationStatisticsPersistence.java | 7 ++- ...icationStatisticsPersistenceComponent.java | 59 +++++++++++++++++-- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java index b5021df47287..2b5586ec17c4 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistence.java @@ -24,9 +24,10 @@ public abstract class ApplicationStatisticsPersistence { @NotNull public Map> getApplicationData(@NotNull GroupDescriptor groupDescriptor) { - final Map> map = myApplicationData.get(groupDescriptor); - - return map == null ? new HashMap>(): map; + if (!myApplicationData.containsKey(groupDescriptor)) { + myApplicationData.put(groupDescriptor, new HashMap>()); + } + return myApplicationData.get(groupDescriptor); } @NotNull diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java index fb8d0fd6bffe..23b03085c414 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/ApplicationStatisticsPersistenceComponent.java @@ -16,10 +16,12 @@ package com.intellij.internal.statistic.persistence; +import com.intellij.ide.AppLifecycleListener; import com.intellij.internal.statistic.AbstractApplicationUsagesCollector; import com.intellij.internal.statistic.UsagesCollector; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.ApplicationComponent; @@ -30,9 +32,11 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerListener; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Function; import com.intellij.util.containers.HashSet; +import com.intellij.util.messages.MessageBus; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -52,6 +56,8 @@ import java.util.Set; ) public class ApplicationStatisticsPersistenceComponent extends ApplicationStatisticsPersistence implements ApplicationComponent, PersistentStateComponent { + private boolean persistOnClosing = true; + private static final String TOKENIZER = ","; @NonNls @@ -152,6 +158,11 @@ public class ApplicationStatisticsPersistenceComponent extends ApplicationStatis } public void initComponent() { + onAppClosing(); + onProjectClosing(); + } + + private void onProjectClosing() { ProjectManager.getInstance().addProjectManagerListener(new ProjectManagerListener() { @Override public void projectOpened(Project project) { @@ -169,16 +180,56 @@ public class ApplicationStatisticsPersistenceComponent extends ApplicationStatis @Override public void projectClosing(Project project) { if (project != null) { - for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { - if (usagesCollector instanceof AbstractApplicationUsagesCollector) { - ((AbstractApplicationUsagesCollector) usagesCollector).persistProjectUsages(project); - } + if (persistOnClosing) { + doPersistProjectUsages(project); } } } }); } + private static void doPersistProjectUsages(@NotNull Project project) { + for (UsagesCollector usagesCollector : Extensions.getExtensions(UsagesCollector.EP_NAME)) { + if (usagesCollector instanceof AbstractApplicationUsagesCollector) { + ((AbstractApplicationUsagesCollector) usagesCollector).persistProjectUsages(project); + } + } + } + + private void onAppClosing() { + final MessageBus messageBus = ApplicationManager.getApplication().getMessageBus(); + + messageBus.connect().subscribe(AppLifecycleListener.TOPIC, new AppLifecycleListener() { + @Override + public void appFrameCreated(String[] commandLineArgs, @NotNull Ref willOpenProject) { + } + + @Override + public void appStarting(Project projectFromCommandLine) { + } + + @Override + public void projectFrameClosed() { + } + + @Override + public void projectOpenFailed() { + } + + @Override + public void welcomeScreenDisplayed() { + } + + @Override + public void appClosing() { + for (Project project : ProjectManager.getInstance().getOpenProjects()) { + doPersistProjectUsages(project); + } + persistOnClosing = false; + } + }); + } + public void disposeComponent() { } } From c3dd3a230dfe7b9c33e485d45542b1c9585a170c Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 17 Feb 2011 14:22:46 +0300 Subject: [PATCH 57/90] more tests --- .../util/messages/MessageBusTest.java | 97 +++++++++++-------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/platform/util/testSrc/com/intellij/util/messages/MessageBusTest.java b/platform/util/testSrc/com/intellij/util/messages/MessageBusTest.java index 0e7dd44b4b2b..a016060a1605 100644 --- a/platform/util/testSrc/com/intellij/util/messages/MessageBusTest.java +++ b/platform/util/testSrc/com/intellij/util/messages/MessageBusTest.java @@ -39,8 +39,8 @@ public class MessageBusTest extends TestCase { void t22(); } - private final static Topic T1 = new Topic("T1", T1Listener.class); - private final static Topic T2 = new Topic("T1", T2Listener.class); + private static final Topic TOPIC1 = new Topic("T1", T1Listener.class); + private static final Topic TOPIC2 = new Topic("T2", T2Listener.class); private class T1Handler implements T1Listener { private final String id; @@ -86,58 +86,57 @@ public class MessageBusTest extends TestCase { } public void testNoListenersSubscribed() { - myBus.syncPublisher(T1).t11(); + myBus.syncPublisher(TOPIC1).t11(); assertEvents(); } public void testSingleMessage() { final MessageBusConnection connection = myBus.connect(); - connection.subscribe(T1, new T1Handler("c")); - myBus.syncPublisher(T1).t11(); + connection.subscribe(TOPIC1, new T1Handler("c")); + myBus.syncPublisher(TOPIC1).t11(); assertEvents("c:t11"); } public void testSingleMessageToTwoConnections() { final MessageBusConnection c1 = myBus.connect(); - c1.subscribe(T1, new T1Handler("c1")); + c1.subscribe(TOPIC1, new T1Handler("c1")); final MessageBusConnection c2 = myBus.connect(); - c2.subscribe(T1, new T1Handler("c2")); + c2.subscribe(TOPIC1, new T1Handler("c2")); - myBus.syncPublisher(T1).t11(); + myBus.syncPublisher(TOPIC1).t11(); assertEvents("c1:t11", "c2:t11"); } public void testTwoMessagesWithSingleSubscription() { final MessageBusConnection connection = myBus.connect(); - connection.subscribe(T1, new T1Handler("c")); - myBus.syncPublisher(T1).t11(); - myBus.syncPublisher(T1).t12(); + connection.subscribe(TOPIC1, new T1Handler("c")); + myBus.syncPublisher(TOPIC1).t11(); + myBus.syncPublisher(TOPIC1).t12(); assertEvents("c:t11", "c:t12"); } public void testTwoMessagesWithDoubleSubscription() { final MessageBusConnection c1 = myBus.connect(); - c1.subscribe(T1, new T1Handler("c1")); + c1.subscribe(TOPIC1, new T1Handler("c1")); final MessageBusConnection c2 = myBus.connect(); - c2.subscribe(T1, new T1Handler("c2")); + c2.subscribe(TOPIC1, new T1Handler("c2")); - myBus.syncPublisher(T1).t11(); - myBus.syncPublisher(T1).t12(); + myBus.syncPublisher(TOPIC1).t11(); + myBus.syncPublisher(TOPIC1).t12(); assertEvents("c1:t11", "c2:t11", "c1:t12", "c2:t12"); } public void testEventFiresAnotherEvent() { - final MessageBusConnection c1 = myBus.connect(); - c1.subscribe(T1, new T1Listener() { + myBus.connect().subscribe(TOPIC1, new T1Listener() { @Override public void t11() { - myLog.add("c1:t11"); - myBus.syncPublisher(T2).t21(); - myLog.add("c1:t11:done"); + myLog.add("inside:t11"); + myBus.syncPublisher(TOPIC2).t21(); + myLog.add("inside:t11:done"); } @Override @@ -146,50 +145,62 @@ public class MessageBusTest extends TestCase { } }); - final MessageBusConnection c2 = myBus.connect(); - c2.subscribe(T1, new T1Handler("c2")); - c2.subscribe(T2, new T2Handler("c2")); + final MessageBusConnection conn = myBus.connect(); + conn.subscribe(TOPIC1, new T1Handler("handler1")); + conn.subscribe(TOPIC2, new T2Handler("handler2")); - myBus.syncPublisher(T1).t12(); - myBus.syncPublisher(T1).t11(); + myBus.syncPublisher(TOPIC1).t12(); + assertEvents("c1:t12", "handler1:t12"); - assertEvents("c1:t12", "c2:t12", "c1:t11", "c2:t11", "c2:t21", "c1:t11:done"); + myBus.syncPublisher(TOPIC1).t11(); + assertEvents("c1:t12\n" + + "handler1:t12\n" + + "inside:t11\n" + + "handler1:t11\n" + + "handler2:t21\n" + + "inside:t11:done"); } public void testConnectionTerminatedInDispatch() { - final MessageBusConnection c1 = myBus.connect(); - c1.subscribe(T1, new T1Listener() { + final MessageBusConnection conn1 = myBus.connect(); + conn1.subscribe(TOPIC1, new T1Listener() { @Override public void t11() { - c1.disconnect(); - myLog.add("c1:t11"); - myBus.syncPublisher(T2).t21(); - myLog.add("c1:t11:done"); + conn1.disconnect(); + myLog.add("inside:t11"); + myBus.syncPublisher(TOPIC2).t21(); + myLog.add("inside:t11:done"); } @Override public void t12() { - myLog.add("c1:t12"); + myLog.add("inside:t12"); } }); - c1.subscribe(T2, new T2Handler("c1")); + conn1.subscribe(TOPIC2, new T2Handler("C1T2Handler")); - final MessageBusConnection c2 = myBus.connect(); - c2.subscribe(T1, new T1Handler("c2")); - c2.subscribe(T2, new T2Handler("c2")); + final MessageBusConnection conn2 = myBus.connect(); + conn2.subscribe(TOPIC1, new T1Handler("C2T1Handler")); + conn2.subscribe(TOPIC2, new T2Handler("C2T2Handler")); - myBus.syncPublisher(T1).t11(); - myBus.syncPublisher(T1).t12(); + myBus.syncPublisher(TOPIC1).t11(); + assertEvents("inside:t11", + "C2T1Handler:t11", + "C2T2Handler:t21", + "inside:t11:done"); + myBus.syncPublisher(TOPIC1).t12(); - assertEvents("c1:t11", "c2:t11", "c2:t21", "c1:t11:done", "c2:t12"); + assertEvents("inside:t11", + "C2T1Handler:t11", + "C2T2Handler:t21", + "inside:t11:done", + "C2T1Handler:t12"); } private void assertEvents(String... expected) { String joinExpected = StringUtil.join(expected, "\n"); - String joinActual = StringUtil.join(myLog.toArray(new String[0]), "\n"); + String joinActual = StringUtil.join(myLog, "\n"); assertEquals("events mismatch", joinExpected, joinActual); } - - } From ba28a3c44c3d4f3d15b839099dd9165ba6a5e4fb Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 17 Feb 2011 16:19:38 +0300 Subject: [PATCH 58/90] added additional assertion --- .../com/intellij/usages/impl/GroupNode.java | 35 +++++++++++-------- .../intellij/usages/impl/UsageViewImpl.java | 2 +- .../util/containers/TransferToEDTQueue.java | 2 +- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java index cd256daa4a35..1384f26676e8 100644 --- a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java +++ b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java @@ -43,7 +43,7 @@ public class GroupNode extends Node implements Navigatable, Comparable myUsageNodes = new ArrayList(); private volatile int myRecursiveUsageCount = 0; - public GroupNode(UsageGroup group, int ruleIndex, UsageViewTreeModelBuilder treeModel) { + public GroupNode(@NotNull UsageGroup group, int ruleIndex, @NotNull UsageViewTreeModelBuilder treeModel) { super(treeModel); setUserObject(group); myGroup = group; @@ -73,7 +73,7 @@ public class GroupNode extends Node implements Navigatable, Comparable groupNodes = mySubgroupNodes.values(); for(Iterator iterator = groupNodes.iterator();iterator.hasNext();) { @@ -129,7 +130,11 @@ public class GroupNode extends Node implements Navigatable, Comparable= 0 ? index : -index-1; } - private int indexedBinarySearch(UsageNode key) { + private int indexedBinarySearch(@NotNull UsageNode key) { int low = 0; int high = getChildCount() - 1; @@ -246,7 +253,7 @@ public class GroupNode extends Node implements Navigatable, Comparable myTransferToEDTQueue; - public void appendUsageLater(Usage usage) { + public void appendUsageLater(@NotNull Usage usage) { myTransferToEDTQueue.offer(usage); } diff --git a/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java b/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java index 8c51af670634..4f374caaa6c0 100644 --- a/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java +++ b/platform/util/src/com/intellij/util/containers/TransferToEDTQueue.java @@ -70,7 +70,7 @@ public class TransferToEDTQueue { myShutUpCondition = shutUpCondition; } - public void offer(final T thing) { + public void offer(@NotNull T thing) { myQueue.offer(thing); scheduleUpdate(); } From 52e93b96469dd6889ec02acd02c812359bd74e29 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 17 Feb 2011 16:21:01 +0300 Subject: [PATCH 59/90] javadoc --- .../src/com/intellij/openapi/fileEditor/FileEditorManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java index 6c0a2151931e..6d708c9103cd 100644 --- a/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/FileEditorManager.java @@ -141,7 +141,7 @@ public abstract class FileEditorManager { /** * Adds specified listener * @param listener listener to be added - * @deprecated Use MessageBus instead + * @deprecated Use MessageBus instead: see {@link FileEditorManagerListener#FILE_EDITOR_MANAGER} */ public abstract void addFileEditorManagerListener(@NotNull FileEditorManagerListener listener); From 3e7cf29951387e1360f1dc3dd7c261177f65cd0e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 17 Feb 2011 15:05:24 +0100 Subject: [PATCH 60/90] correctly pass optional dependencies when installing plugin (IDEA-65502) --- .../src/com/intellij/ide/plugins/ActionInstallPlugin.java | 2 +- .../src/com/intellij/ide/plugins/PluginNode.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java index 1f4967964880..e9f22adf8b75 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/ActionInstallPlugin.java @@ -85,7 +85,7 @@ public class ActionInstallPlugin extends AnAction implements DumbAware { else if (descr instanceof IdeaPluginDescriptorImpl) { pluginNode = new PluginNode(descr.getPluginId()); pluginNode.setName(descr.getName()); - pluginNode.setDepends(Arrays.asList(descr.getDependentPluginIds())); + pluginNode.setDepends(Arrays.asList(descr.getDependentPluginIds()), descr.getOptionalDependentPluginIds()); pluginNode.setSize("-1"); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginNode.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginNode.java index c5fcd1d51e6c..3bbc90df1de1 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginNode.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginNode.java @@ -56,6 +56,7 @@ public class PluginNode implements IdeaPluginDescriptor { private String url; private long date = Long.MAX_VALUE; private List depends; + private PluginId[] myOptionalDependencies; private int status = STATUS_UNKNOWN; private boolean loaded = false; @@ -221,8 +222,9 @@ public class PluginNode implements IdeaPluginDescriptor { return depends; } - public void setDepends(List depends) { + public void setDepends(List depends, PluginId[] optionalDependencies) { this.depends = depends; + myOptionalDependencies = optionalDependencies; } @@ -258,7 +260,7 @@ public class PluginNode implements IdeaPluginDescriptor { @Nullable public PluginId[] getOptionalDependentPluginIds() { - return null; + return myOptionalDependencies; } @Nullable From 7f11bc61994c2254c1cc2f3943f2c39d23e8268d Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 16:07:47 +0100 Subject: [PATCH 61/90] baseline alignment in hint autopopup --- .../codeInsight/lookup/impl/LookupImpl.java | 60 ++++++++++--------- .../intellij/ui/SimpleColoredComponent.java | 12 +++- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 8a4982f74396..0a1b1180afc6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1135,11 +1135,10 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } else if (myHintMode) { final int itemTextPadding = 2; - final int borderWidth = 0; - final JPanel hintComponent = createAutopopupHintComponent(itemTextPadding, borderWidth); + final JPanel hintComponent = createAutopopupHintComponent(itemTextPadding); Point bestPoint = calculatePosition(hintComponent); - bestPoint.x += myCellRenderer.getIconIndent() - itemTextPadding - borderWidth; + bestPoint.x += myCellRenderer.getIconIndent() - itemTextPadding; Point editorPoint = SwingUtilities.convertPoint( editor.getComponent().getRootPane().getLayeredPane(), bestPoint, @@ -1165,7 +1164,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } } - private JPanel createAutopopupHintComponent(int itemTextPadding, int borderWidth) { + private JPanel createAutopopupHintComponent(int itemTextPadding) { int maxAutopopupItems = 7; JPanel pane = new JPanel(new GridBagLayout()); pane.setBackground(HintUtil.INFORMATION_COLOR); @@ -1185,30 +1184,38 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { c.ipadx = itemTextPadding; c.fill = GridBagConstraints.HORIZONTAL; - final SimpleColoredComponent comp = new SimpleColoredComponent(); - comp.setFont(editorFont); - final int style = presentation.isItemTextBold() ? Font.BOLD : Font.PLAIN; - myCellRenderer.renderItemName(element, LookupCellRenderer.FOREGROUND_COLOR, false, style, - StringUtil.notNullize(presentation.getItemText()), comp); - final JPanel p1 = new JPanel(new BorderLayout()); - p1.setBackground(pane.getBackground()); - p1.add(comp, BorderLayout.WEST); - final JLabel label = new JLabel(presentation.getTailText()); - label.setFont(label.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); - p1.add(label, BorderLayout.CENTER); - pane.add(p1, c); - } + { + final GridBagLayout gridBagLayout = new GridBagLayout(); + final JPanel row = new JPanel(gridBagLayout); + row.setBackground(pane.getBackground()); - { - final GridBagConstraints c = new GridBagConstraints(); - c.gridx = 1; - c.gridy = i; - c.fill = GridBagConstraints.HORIZONTAL; - final JLabel comp = new JLabel(" " + StringUtil.notNullize(presentation.getTypeText()) + " "); - comp.setFont(comp.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); - comp.setHorizontalAlignment(SwingConstants.RIGHT); - pane.add(comp, c); + GridBagConstraints c1 = new GridBagConstraints(); + c1.anchor = GridBagConstraints.BASELINE; + + final SimpleColoredComponent nameLabel = new SimpleColoredComponent(); + nameLabel.setFont(editorFont); + final int style = presentation.isItemTextBold() ? Font.BOLD : Font.PLAIN; + myCellRenderer.renderItemName(element, LookupCellRenderer.FOREGROUND_COLOR, false, style, + StringUtil.notNullize(presentation.getItemText()), nameLabel); + row.add(nameLabel, c1); + + c1 = new GridBagConstraints(); + c1.weightx = 1; + c1.anchor = GridBagConstraints.BASELINE; + c1.fill = GridBagConstraints.HORIZONTAL; + final JLabel tailLabel = new JLabel(presentation.getTailText()); + tailLabel.setFont(tailLabel.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); + row.add(tailLabel, c1); + + c1 = new GridBagConstraints(); + c1.fill = GridBagConstraints.NONE; + final JLabel typeLabel = new JLabel(" " + StringUtil.notNullize(presentation.getTypeText()) + " "); + typeLabel.setFont(typeLabel.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); + row.add(typeLabel, c1); + + pane.add(row, c); + } } } @@ -1231,7 +1238,6 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } } - //pane.setBorder(new LineBorder(Color.darkGray, borderWidth)); return pane; } diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java index aff4263398ee..eb099fce193a 100644 --- a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java +++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java @@ -433,7 +433,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible { } g.setColor(color); - final int textBaseline = (getHeight() - metrics.getHeight()) / 2 + metrics.getAscent(); + final int textBaseline = getTextBaseLine(metrics, getHeight()); if (!attributes.isSearchMatch()) g.drawString(fragment, xOffset, textBaseline); @@ -497,6 +497,16 @@ public class SimpleColoredComponent extends JComponent implements Accessible { } } + @Override + public int getBaseline(int width, int height) { + super.getBaseline(width, height); + return getTextBaseLine(getFontMetrics(getFont()), height); + } + + private static int getTextBaseLine(FontMetrics metrics, final int height) { + return (height - metrics.getHeight()) / 2 + metrics.getAscent(); + } + private static void checkCanPaint(Graphics g) { if (UIUtil.isPrinting(g)) return; From 4d6446a5034b752aeac01ca0792c03266cc6486f Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 17 Feb 2011 16:13:04 +0100 Subject: [PATCH 62/90] trying in tests async read of javac output --- .../javaCompiler/CompilerParsingThread.java | 70 +++++++++++++++---- 1 file changed, 55 insertions(+), 15 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java index 6e43ed55f0df..63c851a8cb06 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java @@ -27,6 +27,8 @@ import com.intellij.util.StringBuilderSpinAllocator; import org.jetbrains.annotations.NonNls; import java.io.*; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; /** * @author Eugene Zhuravlev @@ -47,6 +49,8 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { private String myPushBackLine = null; private volatile boolean myProcessExited = false; private final CompileContext myContext; + + private final BlockingQueue myLines = new LinkedBlockingQueue(); public CompilerParsingThread(Process process, OutputParser outputParser, final boolean readErrorStream, boolean trimLines, CompileContext context) { myProcess = process; @@ -60,6 +64,24 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { volatile boolean processing; public void run() { + if (CompileDriver.ourDebugMode) { + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + while (true) { + final String line = readLine(myCompilerOutStreamReader); + if (CompileDriver.ourDebugMode) { + System.out.println("RAW_LIne read: #" + line + "#"); + } + if (line == null) { + myLines.offer(TERMINATION_STRING); + break; + } + myLines.offer(line); + } + } + }); + } processing = true; try { while (true) { @@ -105,16 +127,13 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { } public final String getNextLine() { - if (CompileDriver.ourDebugMode) { - System.out.println("Before reading line"); - } final String pushBack = myPushBackLine; if (pushBack != null) { myPushBackLine = null; myLastReadLine = pushBack; return pushBack; } - final String line = readLine(myCompilerOutStreamReader); + final String line = getNextUnprocessedLine(); if (LOG.isDebugEnabled()) { LOG.debug("LIne read: #" + line + "#"); } @@ -130,6 +149,28 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { return myLastReadLine; } + private String getNextUnprocessedLine() { + if (CompileDriver.ourDebugMode) { + try { + if (TERMINATION_STRING.equals(myLines.peek())) { + return TERMINATION_STRING; + } + final String line = myLines.take(); + if (TERMINATION_STRING.equals(line)) { + myLines.offer(TERMINATION_STRING); // pushback + } + return line; + } + catch (InterruptedException e) { + e.printStackTrace(); + return TERMINATION_STRING; + } + } + else { + return readLine(myCompilerOutStreamReader); + } + } + @Override public void pushBack(String line) { myLastReadLine = null; @@ -227,18 +268,17 @@ public class CompilerParsingThread implements Runnable, OutputParser.Callback { private int readNextByte(final Reader reader) { try { - if (!CompileDriver.ourDebugMode) { - while(!reader.ready()) { - if (isProcessTerminated()) { - //if (!reader.ready()) { - return -1; - //} - } - try { - Thread.sleep(1L); - } - catch (InterruptedException ignore) { + while(!reader.ready()) { + if (isProcessTerminated()) { + if (reader.ready()) { + break; } + return -1; + } + try { + Thread.sleep(1L); + } + catch (InterruptedException ignore) { } } return reader.read(); From 3f6691a38bc0df02f17ddd644f0fa6fef1d139ed Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Thu, 17 Feb 2011 18:22:25 +0300 Subject: [PATCH 63/90] IDEA-65641 --- .../com/intellij/find/impl/LivePreview.java | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java b/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java index 5882ea6c05a9..e092ac5293fe 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java +++ b/platform/lang-impl/src/com/intellij/find/impl/LivePreview.java @@ -307,9 +307,31 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele private void highlightUsages(TextRange oldCursorRange) { if (myEditor == null || myShouldStop) return; - LiveOccurrence firstVisibleOccurrence = null; - LiveOccurrence firstOccurrence = null; + for (LiveOccurrence o : mySearchResults) { + for (TextRange textRange : o.getSecondaryRanges()) { + highlightRange(textRange, OTHER_TARGETS_ATTRIBUTES, myHighlighters); + } + highlightRange(o.getPrimaryRange(), MAIN_TARGET_ATTRIBUTES, myHighlighters); + } + + if (!tryToRepairOldCursor(oldCursorRange)) { + LiveOccurrence afterCaret = firstOccurrenceAfterCaret(); + if (afterCaret != null) { + setCursor(afterCaret); + } else { + LiveOccurrence occurrence = firstVisibleOccurrence(); + if (occurrence != null) { + setCursor(occurrence); + } + } + } + } + + @Nullable + private LiveOccurrence firstVisibleOccurrence() { int offset = Integer.MAX_VALUE; + LiveOccurrence firstOccurrence = null; + LiveOccurrence firstVisibleOccurrence = null; for (LiveOccurrence o : mySearchResults) { if (insideVisibleArea(myEditor, o.getPrimaryRange())) { if (firstVisibleOccurrence == null || o.getPrimaryRange().getStartOffset() < firstVisibleOccurrence.getPrimaryRange().getStartOffset()) { @@ -320,16 +342,22 @@ public class LivePreview extends DocumentAdapter implements ReplacementView.Dele offset = o.getPrimaryRange().getStartOffset(); firstOccurrence = o; } + } + return firstVisibleOccurrence != null ? firstVisibleOccurrence : firstOccurrence; + } - for (TextRange textRange : o.getSecondaryRanges()) { - highlightRange(textRange, OTHER_TARGETS_ATTRIBUTES, myHighlighters); + @Nullable + private LiveOccurrence firstOccurrenceAfterCaret() { + LiveOccurrence afterCaret = null; + int caret = myEditor.getCaretModel().getOffset(); + for (LiveOccurrence occurrence : mySearchResults) { + if (occurrence.getPrimaryRange().getStartOffset() >= caret) { + if (afterCaret == null || occurrence.getPrimaryRange().getStartOffset() < afterCaret.getPrimaryRange().getStartOffset() ) { + afterCaret = occurrence; + } } - highlightRange(o.getPrimaryRange(), MAIN_TARGET_ATTRIBUTES, myHighlighters); - } - - if (!tryToRepairOldCursor(oldCursorRange)) { - setCursor(firstVisibleOccurrence != null ? firstVisibleOccurrence : firstOccurrence); } + return afterCaret; } private boolean tryToRepairOldCursor(TextRange oldCursorRange) { From 0398d39f8f4935fa16c4ddbc2562999ab1a51d1f Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 17 Feb 2011 16:33:09 +0100 Subject: [PATCH 64/90] can be converted to diamonds - like unused symbol --- .../ExplicitTypeCanBeDiamondInspection.java | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java b/java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java index a916513e5a5d..afd8c91f32b5 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.daemon.GroupNames; +import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.openapi.project.Project; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -71,29 +72,8 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements(); if (typeElements.length > 0) { if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return; - holder.registerProblem(parameterList, "Redundant type argument #ref #loc", - new LocalQuickFix() { - @NotNull - @Override - public String getName() { - return "Replace with <>"; - } - - @NotNull - @Override - public String getFamilyName() { - return getName(); - } - - @Override - public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - final PsiElement psiElement = descriptor.getPsiElement(); - if (psiElement instanceof PsiReferenceParameterList) { - final PsiTypeElement[] parameterElements = ((PsiReferenceParameterList)psiElement).getTypeParameterElements(); - psiElement.deleteChildRange(parameterElements[0], parameterElements[parameterElements.length - 1]); - } - } - }); + holder.registerProblem(parameterList, "Redundant type argument #ref #loc", + ProblemHighlightType.LIKE_UNUSED_SYMBOL, new ReplaceWithDiamondFix()); } } } @@ -101,4 +81,27 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT } }; } + + private static class ReplaceWithDiamondFix implements LocalQuickFix, HighPriorityAction { + @NotNull + @Override + public String getName() { + return "Replace with <>"; + } + + @NotNull + @Override + public String getFamilyName() { + return getName(); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement psiElement = descriptor.getPsiElement(); + if (psiElement instanceof PsiReferenceParameterList) { + final PsiTypeElement[] parameterElements = ((PsiReferenceParameterList)psiElement).getTypeParameterElements(); + psiElement.deleteChildRange(parameterElements[0], parameterElements[parameterElements.length - 1]); + } + } + } } From 50278d4d91310b4a22a4ed1daaf1c3fe07f6f6f1 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 17 Feb 2011 16:35:13 +0100 Subject: [PATCH 65/90] typo --- .../intellij/codeInspection/SafeVarargsCanBeUsedInspection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/SafeVarargsCanBeUsedInspection.java b/java/java-impl/src/com/intellij/codeInspection/SafeVarargsCanBeUsedInspection.java index 63eaa00f3c94..112f3011e831 100644 --- a/java/java-impl/src/com/intellij/codeInspection/SafeVarargsCanBeUsedInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/SafeVarargsCanBeUsedInspection.java @@ -82,7 +82,7 @@ public class SafeVarargsCanBeUsedInspection extends BaseJavaLocalInspectionTool } final PsiIdentifier nameIdentifier = method.getNameIdentifier(); if (nameIdentifier != null) { - holder.registerProblem(nameIdentifier, "Possible heap pollution from parametrized vararg type #loc", new LocalQuickFix() { + holder.registerProblem(nameIdentifier, "Possible heap pollution from parameterized vararg type #loc", new LocalQuickFix() { @NotNull @Override public String getName() { From 0f9fced33c53903483d289495b176fd54f7913a3 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 17 Feb 2011 16:46:33 +0100 Subject: [PATCH 66/90] warn about possible heap pollution: annotates as SafeVarargs for final/static methods only (to be improved) --- .../SafeVarargsCanBeUsedInspection.java | 72 ++++++++++--------- .../quickFix/safeVarargs/before4.java | 7 -- 2 files changed, 37 insertions(+), 42 deletions(-) delete mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/safeVarargs/before4.java diff --git a/java/java-impl/src/com/intellij/codeInspection/SafeVarargsCanBeUsedInspection.java b/java/java-impl/src/com/intellij/codeInspection/SafeVarargsCanBeUsedInspection.java index 112f3011e831..c5ed564fa65a 100644 --- a/java/java-impl/src/com/intellij/codeInspection/SafeVarargsCanBeUsedInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/SafeVarargsCanBeUsedInspection.java @@ -68,43 +68,22 @@ public class SafeVarargsCanBeUsedInspection extends BaseJavaLocalInspectionTool if (!PsiUtil.getLanguageLevel(method).isAtLeast(LanguageLevel.JDK_1_7)) return; if (AnnotationUtil.isAnnotated(method, "java.lang.SafeVarargs", false)) return; if (!method.isVarArgs()) return; - if (method.hasModifierProperty(PsiModifier.STATIC) || method.hasModifierProperty(PsiModifier.FINAL)) { - final PsiParameter psiParameter = method.getParameterList().getParameters()[method.getParameterList().getParametersCount() - 1]; - final PsiType componentType = ((PsiEllipsisType)psiParameter.getType()).getComponentType(); - if (GenericsHighlightUtil.isReifiableType(componentType)) { + final PsiParameter psiParameter = method.getParameterList().getParameters()[method.getParameterList().getParametersCount() - 1]; + final PsiType componentType = ((PsiEllipsisType)psiParameter.getType()).getComponentType(); + if (GenericsHighlightUtil.isReifiableType(componentType)) { + return; + } + for (PsiReference reference : ReferencesSearch.search(psiParameter)) { + final PsiElement element = reference.getElement(); + if (element instanceof PsiExpression && !PsiUtil.isAccessedForReading((PsiExpression)element)) { return; } - for (PsiReference reference : ReferencesSearch.search(psiParameter)) { - final PsiElement element = reference.getElement(); - if (element instanceof PsiExpression && !PsiUtil.isAccessedForReading((PsiExpression)element)) { - return; - } - } - final PsiIdentifier nameIdentifier = method.getNameIdentifier(); - if (nameIdentifier != null) { - holder.registerProblem(nameIdentifier, "Possible heap pollution from parameterized vararg type #loc", new LocalQuickFix() { - @NotNull - @Override - public String getName() { - return "Annotate as @SafeVarargs"; - } - - @NotNull - @Override - public String getFamilyName() { - return getName(); - } - - @Override - public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - final PsiElement psiElement = descriptor.getPsiElement(); - if (psiElement instanceof PsiIdentifier) { - final PsiMethod psiMethod = (PsiMethod)psiElement.getParent(); - new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor); - } - } - }); - } + } + final PsiIdentifier nameIdentifier = method.getNameIdentifier(); + if (nameIdentifier != null) { + holder.registerProblem(nameIdentifier, "Possible heap pollution from parameterized vararg type #loc", + //todo check if can be final or static + method.hasModifierProperty(PsiModifier.FINAL) || method.hasModifierProperty(PsiModifier.STATIC) ? new AnnotateAsSafeVarargsQuickFix() : null); } } @@ -113,4 +92,27 @@ public class SafeVarargsCanBeUsedInspection extends BaseJavaLocalInspectionTool } }; } + + private static class AnnotateAsSafeVarargsQuickFix implements LocalQuickFix { + @NotNull + @Override + public String getName() { + return "Annotate as @SafeVarargs"; + } + + @NotNull + @Override + public String getFamilyName() { + return getName(); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement psiElement = descriptor.getPsiElement(); + if (psiElement instanceof PsiIdentifier) { + final PsiMethod psiMethod = (PsiMethod)psiElement.getParent(); + new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor); + } + } + } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/safeVarargs/before4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/safeVarargs/before4.java deleted file mode 100644 index aed4ed01314a..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/safeVarargs/before4.java +++ /dev/null @@ -1,7 +0,0 @@ -// "Annotate as @SafeVarargs" "false" -public class Test { - public void main(T... args) { - - } -} - From 1268579de947c16147b81c055e5f82fcf834fea8 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 17 Feb 2011 18:38:34 +0300 Subject: [PATCH 67/90] NPE --- platform/usageView/src/com/intellij/usages/impl/GroupNode.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java index 1384f26676e8..583fce9f8caa 100644 --- a/platform/usageView/src/com/intellij/usages/impl/GroupNode.java +++ b/platform/usageView/src/com/intellij/usages/impl/GroupNode.java @@ -26,6 +26,7 @@ import com.intellij.usages.rules.MergeableUsage; import com.intellij.util.ui.UIUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; @@ -43,7 +44,7 @@ public class GroupNode extends Node implements Navigatable, Comparable myUsageNodes = new ArrayList(); private volatile int myRecursiveUsageCount = 0; - public GroupNode(@NotNull UsageGroup group, int ruleIndex, @NotNull UsageViewTreeModelBuilder treeModel) { + public GroupNode(@Nullable UsageGroup group, int ruleIndex, @NotNull UsageViewTreeModelBuilder treeModel) { super(treeModel); setUserObject(group); myGroup = group; From 8de82e1f0328f4b4c3e2577be51c10209c4c7f26 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Thu, 17 Feb 2011 19:14:09 +0300 Subject: [PATCH 68/90] test fix --- .../usages/impl/UsageNodeTreeBuilderTest.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/platform/usageView/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java b/platform/usageView/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java index 0d01f31bbcb5..11fb2df0b0b2 100644 --- a/platform/usageView/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java +++ b/platform/usageView/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java @@ -18,11 +18,11 @@ package com.intellij.usages.impl; import com.intellij.openapi.fileEditor.FileEditorLocation; import com.intellij.openapi.vcs.FileStatus; +import com.intellij.testFramework.LightPlatformTestCase; import com.intellij.usages.*; import com.intellij.usages.rules.UsageFilteringRule; import com.intellij.usages.rules.UsageGroupingRule; import com.intellij.util.ui.UIUtil; -import junit.framework.TestCase; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -30,12 +30,7 @@ import javax.swing.*; /** * @author max */ -public class UsageNodeTreeBuilderTest extends TestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - } - +public class UsageNodeTreeBuilderTest extends LightPlatformTestCase { public void testNoGroupingRules() throws Exception { GroupNode groupNode = buildUsageTree(new int[]{2, 3, 0}, new UsageGroupingRule[] {}); @@ -90,14 +85,13 @@ public class UsageNodeTreeBuilderTest extends TestCase { usages[i] = createUsage(indices[i]); } - //DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode("temp")); UsageViewTreeModelBuilder model = new UsageViewTreeModelBuilder(new UsageViewPresentation(), new UsageTarget[0]); GroupNode rootNode = new GroupNode(null, 0, model); model.setRoot(rootNode); UsageNodeTreeBuilder usageNodeTreeBuilder = new UsageNodeTreeBuilder(rules, UsageFilteringRule.EMPTY_ARRAY, rootNode); for (Usage usage : usages) { usageNodeTreeBuilder.appendUsage(usage); - UIUtil.pump(); + UIUtil.dispatchAllInvocationEvents(); } return rootNode; From 3578202b39ce063bfd1eeef60d3babf91e4cc4c0 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 17 Feb 2011 17:07:30 +0100 Subject: [PATCH 69/90] IDEA-65657 (better check applicability) --- .../intention/impl/InsertLiteralUnderscoresAction.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/InsertLiteralUnderscoresAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/InsertLiteralUnderscoresAction.java index 40762fde4f14..281a18d78abc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/InsertLiteralUnderscoresAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/InsertLiteralUnderscoresAction.java @@ -39,7 +39,10 @@ public class InsertLiteralUnderscoresAction extends PsiElementBaseIntentionActio !PsiType.FLOAT.equals(type) && !PsiType.DOUBLE.equals(type)) return false; final String text = literalExpression.getText(); - return text != null && !text.contains("_"); + if (text == null || text.contains("_")) return false; + + final String converted = LiteralFormatUtil.format(text, type); + return converted.length() != text.length(); } @Override From 3818bf52344cb6df9162571a0e99526ed75cc178 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 16 Feb 2011 16:26:01 +0100 Subject: [PATCH 70/90] To JB dictionary --- .../src/com/intellij/spellchecker/jetbrains.dic | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index 3d84c3e01c53..5e4a963686c2 100644 --- a/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/plugins/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -221,6 +221,13 @@ readonly refactor refactored refactoring +reifiable +reification +reifications +reified +reifies +reify +reifying reindex renderer resetlogs From 3407acd7c9dfdd557349c4a1be7fdc25cdf463b6 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 16 Feb 2011 15:05:13 +0100 Subject: [PATCH 71/90] Typos --- .../ui/TypeSelectorManagerImpl.java | 18 +++++++++--------- .../src/com/intellij/psi/PsiParameter.java | 2 +- .../src/com/intellij/psi/PsiSubstitutor.java | 6 +++--- .../src/com/intellij/psi/PsiTryStatement.java | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java index e5b588e196d2..747aab957c19 100644 --- a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java @@ -40,7 +40,7 @@ import java.util.*; public class TypeSelectorManagerImpl implements TypeSelectorManager { private SmartTypePointer myPointer; private PsiType myDefaultType; - private final PsiExpression myMainOccurence; + private final PsiExpression myMainOccurrence; private final PsiExpression[] myOccurrences; private final PsiType[] myTypesForMain; private final PsiType[] myTypesForAll; @@ -51,8 +51,8 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { private ExpectedTypesProvider.ExpectedClassProvider myOccurrenceClassProvider; private ExpectedTypesProvider myExpectedTypesProvider; - public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression mainOccurence, PsiExpression[] occurrences) { - this(project, type, null, mainOccurence, occurrences); + public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression mainOccurrence, PsiExpression[] occurrences) { + this(project, type, null, mainOccurrence, occurrences); } public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression[] occurrences) { @@ -63,7 +63,7 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { myFactory = JavaPsiFacade.getInstance(project).getElementFactory(); mySmartTypePointerManager = SmartTypePointerManager.getInstance(project); setDefaultType(type); - myMainOccurence = null; + myMainOccurrence = null; myOccurrences = occurrences; myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project); myOccurrenceClassProvider = createOccurrenceClassProvider(); @@ -83,12 +83,12 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { public TypeSelectorManagerImpl(Project project, PsiType type, PsiMethod containingMethod, - PsiExpression mainOccurence, + PsiExpression mainOccurrence, PsiExpression[] occurrences) { myFactory = JavaPsiFacade.getInstance(project).getElementFactory(); mySmartTypePointerManager = SmartTypePointerManager.getInstance(project); setDefaultType(type); - myMainOccurence = mainOccurence; + myMainOccurrence = mainOccurrence; myOccurrences = occurrences; myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project); @@ -160,7 +160,7 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { } private PsiType[] getTypesForMain() { - final ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(myMainOccurence, false, myOccurrenceClassProvider, + final ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(myMainOccurrence, false, myOccurrenceClassProvider, false); final ArrayList allowedTypes = new ArrayList(); RefactoringHierarchyUtil.processSuperTypes(getDefaultType(), new RefactoringHierarchyUtil.SuperTypeVisitor() { @@ -259,8 +259,8 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { result.add(0, unboxedType); } - if (defaultType instanceof PsiPrimitiveType && myMainOccurence != null) { - final PsiClassType boxedType = ((PsiPrimitiveType)defaultType).getBoxedType(myMainOccurence); + if (defaultType instanceof PsiPrimitiveType && myMainOccurrence != null) { + final PsiClassType boxedType = ((PsiPrimitiveType)defaultType).getBoxedType(myMainOccurrence); if (boxedType != null) { result.remove(boxedType); result.add(0, boxedType); diff --git a/java/openapi/src/com/intellij/psi/PsiParameter.java b/java/openapi/src/com/intellij/psi/PsiParameter.java index cee4c3820388..4d0c63d8fed3 100644 --- a/java/openapi/src/com/intellij/psi/PsiParameter.java +++ b/java/openapi/src/com/intellij/psi/PsiParameter.java @@ -45,7 +45,7 @@ public interface PsiParameter extends PsiVariable { /** * Checks if the parameter accepts a variable number of arguments. * - * @return true if the parameter is varargs, false otherwise + * @return true if the parameter is a vararg, false otherwise */ boolean isVarArgs(); diff --git a/java/openapi/src/com/intellij/psi/PsiSubstitutor.java b/java/openapi/src/com/intellij/psi/PsiSubstitutor.java index 7ded0e1a995b..c60ece83b8a7 100644 --- a/java/openapi/src/com/intellij/psi/PsiSubstitutor.java +++ b/java/openapi/src/com/intellij/psi/PsiSubstitutor.java @@ -38,7 +38,7 @@ public interface PsiSubstitutor { /** * Empty, or natural, substitutor. For any type parameter T, - * substitues type T. + * substitutes type T. * Example: consider class List<E>. this * inside class List has type List with EMPTY substitutor. */ @@ -56,7 +56,7 @@ public interface PsiSubstitutor { PsiType substitute(@NotNull PsiTypeParameter typeParameter); /** - * Substitutes type parameters occuring in type with their values. + * Substitutes type parameters occurring in type with their values. * If value for type parameter is null, appropriate erasure is returned. * * @param type the type to substitute the type parameters for. @@ -98,7 +98,7 @@ public interface PsiSubstitutor { PsiSubstitutor putAll(PsiSubstitutor another); /** - * Returns the map from type parameters to types used for substution by this substitutor. + * Returns the map from type parameters to types used for substitution by this substitutor. * * @return the substitution map instance. */ diff --git a/java/openapi/src/com/intellij/psi/PsiTryStatement.java b/java/openapi/src/com/intellij/psi/PsiTryStatement.java index deb2c0560af2..a74ae8d52e61 100644 --- a/java/openapi/src/com/intellij/psi/PsiTryStatement.java +++ b/java/openapi/src/com/intellij/psi/PsiTryStatement.java @@ -40,7 +40,7 @@ public interface PsiTryStatement extends PsiStatement { PsiCodeBlock[] getCatchBlocks(); /** - * Returns the array of parametets for catch sections. + * Returns the array of parameters for catch sections. * * @return the array of parameters, or an empty array if the statement has no catch sections. */ From 451520b4d0ae9d7d2c547edd3f028a791782a5c3 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 16:49:47 +0100 Subject: [PATCH 72/90] when class name differs from file name, reflect that in project view --- .../ide/projectView/impl/ClassesTreeStructureProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java index 6e00723653a6..d7ba93b430ae 100644 --- a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java +++ b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java @@ -66,7 +66,8 @@ public class ClassesTreeStructureProvider implements SelectableTreeStructureProv PsiClass[] classes = classOwner.getClasses(); if (fileInRoots(file)) { - if (classes.length == 1 && !(classes[0] instanceof SyntheticElement)) { + if (classes.length == 1 && !(classes[0] instanceof SyntheticElement) && + (file == null || file.getNameWithoutExtension().equals(classes[0].getName()))) { result.add(new ClassTreeNode(myProject, classes[0], settings1)); } else { result.add(new PsiClassOwnerTreeNode(classOwner, settings1)); From 66bafd7c05870c5bb4725fd113bf473ce01937df Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 17:08:32 +0100 Subject: [PATCH 73/90] IDEA-65286 JAVA: autocomplete triggers within double-value --- .../completion/JavaCompletionContributor.java | 1 + .../codeInsight/completion/JavaAutoPopupTest.groovy | 9 +++++++++ .../src/com/intellij/patterns/PsiElementPattern.java | 8 ++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index a04bc0bf4dcb..81807cd7b863 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -177,6 +177,7 @@ public class JavaCompletionContributor extends CompletionContributor { } if (AFTER_NUMBER_LITERAL.accepts(position)) { + _result.stopHere(); return; } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 658c03401b20..1439b3b55f83 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -476,5 +476,14 @@ class JavaAutoPopupTest extends CompletionAutoPopupTestCase { assert !lookup } + public void testDoubleLiteralInField() { + myFixture.configureByText "a.java", """ +public interface Test { + double FULL = 1.0 +}""" + type 'd' + assert !lookup + } + } diff --git a/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java b/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java index cd72d658f331..c0339cb46e4c 100644 --- a/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java +++ b/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java @@ -66,11 +66,11 @@ public abstract class PsiElementPattern pattern) { - return afterLeafSkipping(psiElement().whitespaceCommentOrError(), pattern); + return afterLeafSkipping(psiElement().whitespaceCommentEmptyOrError(), pattern); } public Self beforeLeaf(@NotNull final ElementPattern pattern) { - return beforeLeafSkipping(psiElement().whitespaceCommentOrError(), pattern); + return beforeLeafSkipping(psiElement().whitespaceCommentEmptyOrError(), pattern); } public Self whitespace() { @@ -81,6 +81,10 @@ public abstract class PsiElementPattern pattern) { return withChildren(collection(PsiElement.class).filter(not(psiElement().whitespace()), collection(PsiElement.class).first(pattern))); } From b417cb4606f10f54f1830000baa07d5a073981b9 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 17:22:32 +0100 Subject: [PATCH 74/90] [rev=anna] IDEA-65611 "Unrecognized option: -javaagent:..." when running JUnit 3 tests in JDK 1.3 module with debugger --- .../groovy/debugger/GroovyHotSwapper.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java index 4acba2698cfd..d8085109a7bd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java @@ -1,17 +1,17 @@ package org.jetbrains.plugins.groovy.debugger; import com.intellij.execution.Executor; -import com.intellij.execution.configurations.JavaParameters; -import com.intellij.execution.configurations.RunConfiguration; -import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.*; import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.runners.JavaProgramPatcher; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.PluginPathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.JdkUtil; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.LanguageLevelModuleExtension; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; @@ -78,10 +78,20 @@ public class GroovyHotSwapper extends JavaProgramPatcher { return; } - if (LanguageLevelProjectExtension.getInstance(project).getLanguageLevel().compareTo(LanguageLevel.JDK_1_5) < 0) { + if (!LanguageLevelProjectExtension.getInstance(project).getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_5)) { return; } + if (configuration instanceof ModuleBasedConfiguration) { + final Module module = ((ModuleBasedConfiguration)configuration).getConfigurationModule().getModule(); + if (module != null) { + final LanguageLevel level = LanguageLevelModuleExtension.getInstance(module).getLanguageLevel(); + if (level != null && !level.isAtLeast(LanguageLevel.JDK_1_5)) { + return; + } + } + } + Sdk jdk = javaParameters.getJdk(); if (jdk != null) { String vendor = JdkUtil.getJdkMainAttribute(jdk, Attributes.Name.IMPLEMENTATION_VENDOR); From 6b44b057faa9bb330b3856bab88dde8b4fd075ed Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 17 Feb 2011 17:52:04 +0100 Subject: [PATCH 75/90] More fair handle of PsiDisjunctionType; introduce variable for multi-catch types --- .../SmartTypePointerManagerImpl.java | 58 ++++++++++++++----- .../psi/impl/source/PsiTypeElementImpl.java | 8 ++- .../source/tree/JavaChangeUtilSupport.java | 11 ++-- .../ui/TypeSelectorManagerImpl.java | 30 +++++----- .../MultiCatchSimple.after.java | 11 ++++ .../introduceVariable/MultiCatchSimple.java | 11 ++++ .../MultiCatchTyped.after.java | 12 ++++ .../introduceVariable/MultiCatchTyped.java | 12 ++++ .../refactoring/IntroduceVariableTest.java | 10 +++- .../com/intellij/psi/PsiDisjunctionType.java | 39 ++++++------- .../src/com/intellij/psi/PsiTypeVisitor.java | 4 ++ .../intellij/psi/util/TypeConversionUtil.java | 28 +++++++-- 12 files changed, 171 insertions(+), 63 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceVariable/MultiCatchSimple.after.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/MultiCatchSimple.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/MultiCatchTyped.after.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/MultiCatchTyped.java diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java index fe1db0118759..ae32fccd1998 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java @@ -13,10 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * @author max - */ package com.intellij.psi.impl.smartPointers; import com.intellij.openapi.diagnostic.Logger; @@ -26,20 +22,28 @@ import com.intellij.psi.impl.PsiSubstitutorImpl; import com.intellij.psi.impl.source.PsiClassReferenceType; import com.intellij.psi.impl.source.PsiImmediateClassType; import com.intellij.psi.util.PsiUtil; +import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.NullableFunction; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.Map; import java.util.Set; +/** + * @author max + */ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SmartTypePointerManagerImpl"); + private final SmartPointerManager myPsiPointerManager; private final Project myProject; - public SmartTypePointerManagerImpl(SmartPointerManager psiPointerManager, final Project project) { + public SmartTypePointerManagerImpl(final SmartPointerManager psiPointerManager, final Project project) { myPsiPointerManager = psiPointerManager; myProject = project; } @@ -102,26 +106,24 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { return PsiWildcardType.createUnbounded(myManager); } else { + final PsiType type = myBoundPointer.getType(); + assert type != null : myBoundPointer; if (myIsExtending) { - return PsiWildcardType.createExtends(myManager, myBoundPointer.getType()); + return PsiWildcardType.createExtends(myManager, type); } else { - return PsiWildcardType.createSuper(myManager, myBoundPointer.getType()); + return PsiWildcardType.createSuper(myManager, type); } } } } - private static class ClassTypePointer implements SmartTypePointer { private PsiType myType; private final SmartPsiElementPointer myClass; private final Map myMap; - - public ClassTypePointer(PsiType type, - SmartPsiElementPointer aClass, - Map map) { + public ClassTypePointer(PsiType type, SmartPsiElementPointer aClass, Map map) { myType = type; myClass = aClass; myMap = map; @@ -182,15 +184,40 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { } } + private class DisjunctionTypePointer implements SmartTypePointer { + private PsiType myType; + private final List myPointers; + + private DisjunctionTypePointer(final PsiDisjunctionType type) { + myType = type; + myPointers = ContainerUtil.map(type.getDisjunctions(), new Function() { + @Override public SmartTypePointer fun(PsiType psiType) { return createSmartTypePointer(psiType); } + }); + } + + @Override + public PsiType getType() { + if (myType.isValid()) return myType; + + final List types = ContainerUtil.map(myPointers, new NullableFunction() { + @Override public PsiType fun(SmartTypePointer typePointer) { return typePointer.getType(); } + }); + return new PsiDisjunctionType(types, PsiManager.getInstance(myProject)); + } + } + private class SmartTypeCreatingVisitor extends PsiTypeVisitor { + @Override public SmartTypePointer visitPrimitiveType(PsiPrimitiveType primitiveType) { return new SimpleTypePointer(primitiveType); } + @Override public SmartTypePointer visitArrayType(PsiArrayType arrayType) { return new ArrayTypePointer(arrayType, arrayType.getComponentType().accept(this)); } + @Override public SmartTypePointer visitWildcardType(PsiWildcardType wildcardType) { final PsiType bound = wildcardType.getBound(); final SmartTypePointer boundPointer; @@ -203,6 +230,7 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { return new WildcardTypePointer(wildcardType, boundPointer); } + @Override public SmartTypePointer visitClassType(PsiClassType classType) { final PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics(); final PsiClass aClass = resolveResult.getElement(); @@ -226,6 +254,10 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { } return new ClassTypePointer(classType, myPsiPointerManager.createSmartPsiElementPointer(aClass), map); } - } + @Override + public SmartTypePointer visitDisjunctionType(PsiDisjunctionType disjunctionType) { + return new DisjunctionTypePointer(disjunctionType); + } + } } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java index bc34754b5053..b24b1e46c962 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java @@ -32,6 +32,7 @@ import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PatchedSoftReference; import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -102,7 +103,12 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl cachedType = componentType.createArrayType(); } else { - cachedType = new PsiDisjunctionType(this); + final List typeElements = PsiTreeUtil.getChildrenOfTypeAsList(this, PsiTypeElement.class); + if (typeElements.size() < 2) LOG.error("Incorrect nested type: " + this); + final List types = ContainerUtil.map(typeElements, new Function() { + @Override public PsiType fun(final PsiTypeElement psiTypeElement) { return psiTypeElement.getType(); } + }); + cachedType = new PsiDisjunctionType(types, getManager()); } } else if (elementType == JavaElementType.JAVA_CODE_REFERENCE) { diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaChangeUtilSupport.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaChangeUtilSupport.java index 69eaa196df72..8dd87bc0b290 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaChangeUtilSupport.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaChangeUtilSupport.java @@ -180,15 +180,18 @@ public class JavaChangeUtilSupport implements TreeGenerator, TreeCopyHandler { return createType(original.getProject(), originalText, null, generated); } if (type instanceof PsiIntersectionType) { - PsiIntersectionType intersectionType = (PsiIntersectionType)type; - LightTypeElement te = new LightTypeElement(original.getManager(), intersectionType.getConjuncts()[0]); + LightTypeElement te = new LightTypeElement(original.getManager(), ((PsiIntersectionType)type).getRepresentative()); + return ChangeUtil.generateTreeElement(te, table, manager); + } + if (type instanceof PsiDisjunctionType) { + LightTypeElement te = new LightTypeElement(original.getManager(), ((PsiDisjunctionType)type).getLeastUpperBound()); return ChangeUtil.generateTreeElement(te, table, manager); } PsiClassType classType = (PsiClassType)type; String text = classType.getPresentableText(); final TreeElement element = createType(original.getProject(), text, original, false); - PsiTypeElementImpl result = (PsiTypeElementImpl)SourceTreeToPsiMap.treeElementToPsi(element); + PsiTypeElementImpl result = SourceTreeToPsiMap.treeToPsiNotNull(element); CodeEditUtil.setNodeGenerated(result, generated); if (generated) { @@ -397,7 +400,7 @@ public class JavaChangeUtilSupport implements TreeGenerator, TreeCopyHandler { case PsiJavaCodeReferenceElementImpl.CLASS_NAME_KIND: case PsiJavaCodeReferenceElementImpl.CLASS_OR_PACKAGE_NAME_KIND: case PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND: - final PsiElement target = ((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(original)).resolve(); + final PsiElement target = SourceTreeToPsiMap.treeToPsiNotNull(original).resolve(); if (target instanceof PsiClass) { ref.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)target); } diff --git a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java index 747aab957c19..a4ae0cdf045b 100644 --- a/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/ui/TypeSelectorManagerImpl.java @@ -49,7 +49,6 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { private final PsiElementFactory myFactory; private final SmartTypePointerManager mySmartTypePointerManager; private ExpectedTypesProvider.ExpectedClassProvider myOccurrenceClassProvider; - private ExpectedTypesProvider myExpectedTypesProvider; public TypeSelectorManagerImpl(Project project, PsiType type, PsiExpression mainOccurrence, PsiExpression[] occurrences) { this(project, type, null, mainOccurrence, occurrences); @@ -65,12 +64,12 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { setDefaultType(type); myMainOccurrence = null; myOccurrences = occurrences; - myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project); + myOccurrenceClassProvider = createOccurrenceClassProvider(); myTypesForAll = getTypesForAll(areTypesDirected); myTypesForMain = PsiType.EMPTY_ARRAY; - myIsOneSuggestion = myTypesForAll.length == 1; + myIsOneSuggestion = myTypesForAll.length == 1; if (myIsOneSuggestion) { myTypeSelector = new TypeSelector(myTypesForAll[0]); } @@ -90,7 +89,6 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { setDefaultType(type); myMainOccurrence = mainOccurrence; myOccurrences = occurrences; - myExpectedTypesProvider = ExpectedTypesProvider.getInstance(project); myOccurrenceClassProvider = createOccurrenceClassProvider(); myTypesForMain = getTypesForMain(); @@ -149,8 +147,8 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { private ExpectedTypesProvider.ExpectedClassProvider createOccurrenceClassProvider() { final Set occurrenceClasses = new HashSet(); - for (final PsiExpression occurence : myOccurrences) { - final PsiType occurrenceType = occurence.getType(); + for (final PsiExpression occurrence : myOccurrences) { + final PsiType occurrenceType = occurrence.getType(); final PsiClass aClass = PsiUtil.resolveClassInType(occurrenceType); if (aClass != null) { occurrenceClasses.add(aClass); @@ -160,8 +158,7 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { } private PsiType[] getTypesForMain() { - final ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(myMainOccurrence, false, myOccurrenceClassProvider, - false); + final ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(myMainOccurrence, false, myOccurrenceClassProvider, false); final ArrayList allowedTypes = new ArrayList(); RefactoringHierarchyUtil.processSuperTypes(getDefaultType(), new RefactoringHierarchyUtil.SuperTypeVisitor() { public void visitType(PsiType aType) { @@ -173,9 +170,8 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { } private void checkIfAllowed(PsiType type) { - if (expectedTypes != null && expectedTypes.length > 0) { - final ExpectedTypeInfo - typeInfo = ExpectedTypesProvider.createInfo(type, ExpectedTypeInfo.TYPE_STRICTLY, type, TailType.NONE); + if (expectedTypes.length > 0) { + final ExpectedTypeInfo typeInfo = ExpectedTypesProvider.createInfo(type, ExpectedTypeInfo.TYPE_STRICTLY, type, TailType.NONE); for (ExpectedTypeInfo expectedType : expectedTypes) { if (expectedType.intersect(typeInfo).length != 0) { allowedTypes.add(type); @@ -196,9 +192,7 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { private PsiType[] getTypesForAll(final boolean areTypesDirected) { final ArrayList expectedTypesFromAll = new ArrayList(); for (PsiExpression occurrence : myOccurrences) { - - final ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(occurrence, false, myOccurrenceClassProvider, - isUsedAfter()); + final ExpectedTypeInfo[] expectedTypes = ExpectedTypesProvider.getExpectedTypes(occurrence, false, myOccurrenceClassProvider, isUsedAfter()); if (expectedTypes.length > 0) { expectedTypesFromAll.add(expectedTypes); } @@ -266,13 +260,15 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager { result.add(0, boxedType); } } - result.add(0, defaultType); + if (!TypeConversionUtil.isComposite(defaultType)) { + result.add(0, defaultType); + } return result; } - public void setAllOccurences(boolean allOccurences) { + public void setAllOccurences(boolean occurrences) { if (myIsOneSuggestion) return; - setTypesAndPreselect(allOccurences ? myTypesForAll : myTypesForMain); + setTypesAndPreselect(occurrences ? myTypesForAll : myTypesForMain); } private void setTypesAndPreselect(PsiType[] types) { diff --git a/java/java-tests/testData/refactoring/introduceVariable/MultiCatchSimple.after.java b/java/java-tests/testData/refactoring/introduceVariable/MultiCatchSimple.after.java new file mode 100644 index 000000000000..cf16e0b4b794 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/MultiCatchSimple.after.java @@ -0,0 +1,11 @@ +class C { + static class E1 extends Exception { } + static class E2 extends Exception { } + + void m() { + try { } + catch (E1 | E2 ex) { + final Exception e = ex; + } + } +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/MultiCatchSimple.java b/java/java-tests/testData/refactoring/introduceVariable/MultiCatchSimple.java new file mode 100644 index 000000000000..582755caaab1 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/MultiCatchSimple.java @@ -0,0 +1,11 @@ +class C { + static class E1 extends Exception { } + static class E2 extends Exception { } + + void m() { + try { } + catch (E1 | E2 ex) { + ex; + } + } +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/MultiCatchTyped.after.java b/java/java-tests/testData/refactoring/introduceVariable/MultiCatchTyped.after.java new file mode 100644 index 000000000000..aed77f0ac0b7 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/MultiCatchTyped.after.java @@ -0,0 +1,12 @@ +class C { + interface B { } + static class E1 extends Exception implements B { } + static class E2 extends Exception implements B { } + + void m() { + try { } + catch (E1 | E2 ex) { + final B b = ex; + } + } +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/MultiCatchTyped.java b/java/java-tests/testData/refactoring/introduceVariable/MultiCatchTyped.java new file mode 100644 index 000000000000..6a8ce4f135ce --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/MultiCatchTyped.java @@ -0,0 +1,12 @@ +class C { + interface B { } + static class E1 extends Exception implements B { } + static class E2 extends Exception implements B { } + + void m() { + try { } + catch (E1 | E2 ex) { + ex; + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 2094231236f5..6bbc35d63484 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -3,8 +3,6 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiType; @@ -250,6 +248,14 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { }); } + public void testMultiCatchSimple() throws Exception { + doTest(new MockIntroduceVariableHandler("e", true, true, false, "C.E1 | C.E2")); + } + + public void testMultiCatchTyped() throws Exception { + doTest(new MockIntroduceVariableHandler("b", true, true, false, "C.E1 | C.E2")); + } + private void doTest(IntroduceVariableBase testMe) throws Exception { @NonNls String baseName = "/refactoring/introduceVariable/" + getTestName(false); configureByFile(baseName + ".java"); diff --git a/java/openapi/src/com/intellij/psi/PsiDisjunctionType.java b/java/openapi/src/com/intellij/psi/PsiDisjunctionType.java index e764b3bde987..0ae89e9850b4 100644 --- a/java/openapi/src/com/intellij/psi/PsiDisjunctionType.java +++ b/java/openapi/src/com/intellij/psi/PsiDisjunctionType.java @@ -18,39 +18,38 @@ package com.intellij.psi; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.*; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.Function; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.util.Collections; import java.util.List; +/** + * Composite type resulting from Project Coin's multi-catch statements, * i.e. FileNotFoundException | EOFException. + * In most cases should be threatened via its least upper bound * (IOException in the example above). + */ public class PsiDisjunctionType extends PsiType { - private final PsiTypeElement myTypeElement; + private final PsiManager myManager; private final List myTypes; private final CachedValue myLubCache; - public PsiDisjunctionType(final PsiTypeElement typeElement) { + public PsiDisjunctionType(final List types, final PsiManager psiManager) { super(PsiAnnotation.EMPTY_ARRAY); - myTypeElement = typeElement; + myManager = psiManager; + myTypes = Collections.unmodifiableList(types); - final List typeElements = PsiTreeUtil.getChildrenOfTypeAsList(myTypeElement, PsiTypeElement.class); - myTypes = Collections.unmodifiableList(ContainerUtil.map(typeElements, new Function() { - @Override - public PsiType fun(final PsiTypeElement psiTypeElement) { - return psiTypeElement.getType(); - } - })); - - final CachedValuesManager cacheManager = CachedValuesManager.getManager(myTypeElement.getProject()); + final CachedValuesManager cacheManager = CachedValuesManager.getManager(psiManager.getProject()); myLubCache = cacheManager.createCachedValue(new CachedValueProvider() { public Result compute() { PsiType lub = myTypes.get(0); for (int i = 1; i < myTypes.size(); i++) { - lub = GenericsUtil.getLeastUpperBound(lub, myTypes.get(i), myTypeElement.getManager()); + lub = GenericsUtil.getLeastUpperBound(lub, myTypes.get(i), psiManager); } return Result.create(lub, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } @@ -65,6 +64,10 @@ public class PsiDisjunctionType extends PsiType { return myTypes; } + public PsiManager getManager() { + return myManager; + } + @Override public String getPresentableText() { return StringUtil.join(myTypes, new Function() { @@ -101,11 +104,7 @@ public class PsiDisjunctionType extends PsiType { @Override public A accept(final PsiTypeVisitor visitor) { - final PsiType lub = getLeastUpperBound(); - if (lub instanceof PsiClassType) { - return visitor.visitClassType((PsiClassType)lub); - } - return visitor.visitType(lub); + return visitor.visitDisjunctionType(this); } @Override diff --git a/java/openapi/src/com/intellij/psi/PsiTypeVisitor.java b/java/openapi/src/com/intellij/psi/PsiTypeVisitor.java index 59c52a49e931..045060685ce0 100644 --- a/java/openapi/src/com/intellij/psi/PsiTypeVisitor.java +++ b/java/openapi/src/com/intellij/psi/PsiTypeVisitor.java @@ -48,4 +48,8 @@ public class PsiTypeVisitor { public A visitEllipsisType(PsiEllipsisType ellipsisType) { return visitArrayType(ellipsisType); } + + public A visitDisjunctionType(PsiDisjunctionType disjunctionType) { + return visitType(disjunctionType); + } } diff --git a/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java b/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java index cad7a05a0836..feb7c854bd8e 100644 --- a/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java @@ -33,10 +33,7 @@ import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; +import java.util.*; public class TypeConversionUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.TypeConversionUtil"); @@ -75,6 +72,7 @@ public class TypeConversionUtil { TYPE_TO_RANK_MAP.put(PsiType.BOOLEAN, BOOL_RANK); } + private TypeConversionUtil() { } /** * @return true if fromType can be casted to toType @@ -1077,6 +1075,10 @@ public class TypeConversionUtil { return type != null && isPrimitiveWrapper(type.getCanonicalText()); } + public static boolean isComposite(final PsiType type) { + return type instanceof PsiDisjunctionType || type instanceof PsiIntersectionType; + } + public static PsiType typeParameterErasure(@NotNull PsiTypeParameter typeParameter) { return typeParameterErasure(typeParameter, PsiSubstitutor.EMPTY); } @@ -1122,9 +1124,10 @@ public class TypeConversionUtil { return erasure(type, PsiSubstitutor.EMPTY); } - public static PsiType erasure(PsiType type, final PsiSubstitutor beforeSubstitutor) { + public static PsiType erasure(final PsiType type, final PsiSubstitutor beforeSubstitutor) { if (type == null) return null; return type.accept(new PsiTypeVisitor() { + @Override public PsiType visitClassType(PsiClassType classType) { final PsiClass aClass = classType.resolve(); if (aClass instanceof PsiTypeParameter) { @@ -1135,14 +1138,17 @@ public class TypeConversionUtil { } } + @Override public PsiType visitWildcardType(PsiWildcardType wildcardType) { return wildcardType.getExtendsBound().accept(this); } + @Override public PsiType visitPrimitiveType(PsiPrimitiveType primitiveType) { return primitiveType; } + @Override public PsiType visitEllipsisType(PsiEllipsisType ellipsisType) { final PsiType componentType = ellipsisType.getComponentType(); final PsiType newComponentType = componentType.accept(this); @@ -1150,12 +1156,23 @@ public class TypeConversionUtil { return new PsiArrayType(newComponentType); } + @Override public PsiType visitArrayType(PsiArrayType arrayType) { final PsiType componentType = arrayType.getComponentType(); final PsiType newComponentType = componentType.accept(this); if (newComponentType == componentType) return arrayType; return newComponentType.createArrayType(); } + + @Override + public PsiType visitDisjunctionType(PsiDisjunctionType disjunctionType) { + final List original = disjunctionType.getDisjunctions(); + final List erased = new ArrayList(original.size()); + for (PsiType psiType : original) { + erased.add(erasure(psiType, beforeSubstitutor)); + } + return new PsiDisjunctionType(erased, disjunctionType.getManager()); + } }); } @@ -1539,6 +1556,5 @@ public class TypeConversionUtil { } return new ClassCandidateInfo(clazz, result.getSubstitutor()); - } } From 22736c4a9c6e86089cc48f0c62697fa93897636a Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 18:10:56 +0100 Subject: [PATCH 76/90] honor tail text color in hint --- .../intellij/codeInsight/lookup/impl/LookupCellRenderer.java | 2 +- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java index f606603161fe..bbba75b5f69b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupCellRenderer.java @@ -198,7 +198,7 @@ public class LookupCellRenderer implements ListCellRenderer { return text.substring(0, i) + ELLIPSIS; } - private static Color getTailTextColor(boolean isSelected, LookupElementPresentation presentation, Color defaultForeground) { + public static Color getTailTextColor(boolean isSelected, LookupElementPresentation presentation, Color defaultForeground) { if (presentation.isTailGrayed()) { return getGrayedForeground(isSelected); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 0a1b1180afc6..68053fa206c5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1206,6 +1206,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { c1.fill = GridBagConstraints.HORIZONTAL; final JLabel tailLabel = new JLabel(presentation.getTailText()); tailLabel.setFont(tailLabel.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); + tailLabel.setForeground(LookupCellRenderer.getTailTextColor(false, presentation, tailLabel.getForeground())); row.add(tailLabel, c1); c1 = new GridBagConstraints(); From c191322cef3872d776ca2360f9b5b9ceacc4d9c1 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 18:35:28 +0100 Subject: [PATCH 77/90] shortcut hint --- .../codeInsight/lookup/impl/LookupImpl.java | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 68053fa206c5..f7baddd2cfe9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -67,6 +67,7 @@ import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; +import javax.swing.border.MatteBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; @@ -1220,23 +1221,37 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { } } - if (items.size() > maxAutopopupItems) { - { - final GridBagConstraints c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = maxAutopopupItems; - c.gridwidth = 2; - c.ipadx = 5; - c.ipady = 2; - c.fill = GridBagConstraints.HORIZONTAL; - final String moreText = " ... (" + - KeymapUtil - .getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION)) + - " for more suggestions)"; - final JLabel label = new JLabel(moreText); - label.setFont(label.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); - pane.add(label, c); + { + final GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = maxAutopopupItems; + c.gridwidth = 2; + c.ipadx = 5; + c.ipady = 2; + c.fill = GridBagConstraints.HORIZONTAL; + final JPanel ad = new JPanel(new BorderLayout()); + ad.setBorder(new MatteBorder(1, 0, 0, 0, Color.lightGray)); + ad.setOpaque(false); + + if (items.size() > maxAutopopupItems) { + final String ctrlSpace = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CODE_COMPLETION)); + if (StringUtil.isNotEmpty(ctrlSpace)) { + final String moreText = ctrlSpace + " for more"; + final JLabel moreLabel = new JLabel(moreText); + moreLabel.setFont(moreLabel.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); + ad.add(moreLabel, BorderLayout.WEST); + } } + + final String tab = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE)); + if (StringUtil.isNotEmpty(tab)) { + final String enter = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM)); + String message = tab + (isFocused() ? ", " + enter : "") + " for the first item"; + final JLabel fstLabel = new JLabel(message); + fstLabel.setFont(fstLabel.getFont().deriveFont(Font.PLAIN, editorFont.getSize())); + ad.add(fstLabel, BorderLayout.EAST); + } + pane.add(ad, c); } return pane; From 74a71a2b44638d6ba5423c9e02b56f9317c02294 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 17 Feb 2011 20:37:38 +0300 Subject: [PATCH 78/90] IDEA-65266 Pressing Ctrl+P hid text under cursor + other hint fixes --- .../hint/ParameterInfoComponent.java | 7 +- .../com/intellij/ide/IdeTooltipManager.java | 3 +- .../openapi/progress/util/ProgressWindow.java | 2 +- .../src/com/intellij/ui/BalloonImpl.java | 72 +++++++++++-------- .../src/com/intellij/ui/LightweightHint.java | 61 ++++++++++++++-- .../com/intellij/ui/popup/AbstractPopup.java | 52 +------------- .../util/src/com/intellij/ui/PopupBorder.java | 4 +- 7 files changed, 110 insertions(+), 91 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java index f747e3e324d2..fd82f3913f66 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java @@ -67,7 +67,6 @@ class ParameterInfoComponent extends JPanel{ myObjects = objects; setLayout(new GridBagLayout()); - setBorder(BorderFactory.createCompoundBorder(LineBorder.createGrayLineBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 5))); setBackground(BACKGROUND_COLOR); myHandler = handler; @@ -314,7 +313,11 @@ class ParameterInfoComponent extends JPanel{ Dimension normalPreferredSize = super.getPreferredSize(); // some fonts (for example, Arial Black Cursiva) have NORMAL characters wider than BOLD characters - return new Dimension(Math.max(boldPreferredSize.width, normalPreferredSize.width), Math.max(boldPreferredSize.height, normalPreferredSize.height)); + Dimension d = new Dimension(Math.max(boldPreferredSize.width, normalPreferredSize.width), + Math.max(boldPreferredSize.height, normalPreferredSize.height)); + + System.out.println("d = " + d); + return d; } } } diff --git a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java index 7d4d43dd76c1..4de43e5babbb 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java @@ -472,7 +472,8 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener if (prefSizeOriginal.width > fitWidth) { setSize(new Dimension(fitWidth, Integer.MAX_VALUE)); Dimension fixedWidthSize = super.getPreferredSize(); - prefSize.set(new Dimension(fitWidth, fixedWidthSize.height)); + Dimension minSize = super.getMinimumSize(); + prefSize.set(new Dimension(fitWidth > minSize.width ? fitWidth : minSize.width, fixedWidthSize.height)); } else { prefSize.set(new Dimension(prefSizeOriginal)); diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index d2a297431da3..c055dd7739a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -678,7 +678,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa protected void init() { super.init(); setUndecorated(true); - myPanel.setBorder(PopupBorder.Factory.create(true)); + myPanel.setBorder(PopupBorder.Factory.create(true, true)); } protected boolean isProgressDialog() { diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index 92373029be56..0241f7886fcd 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -78,7 +78,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi private MyComponent myComp; private JLayeredPane myLayeredPane; - private Position myPosition; + private AbstractPosition myPosition; private Point myTargetPoint; private final boolean myHideOnFrameResize; @@ -226,7 +226,13 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } public void show(final RelativePoint target, final Balloon.Position position) { - Position pos = BELOW; + AbstractPosition pos = getAbstractPositionFor(position); + + show(target, pos); + } + + private static AbstractPosition getAbstractPositionFor(Position position) { + AbstractPosition pos = BELOW; switch (position) { case atLeft: pos = AT_LEFT; @@ -241,12 +247,11 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi pos = ABOVE; break; } - - show(target, pos); + return pos; } public void show(PositionTracker tracker, Balloon.Position position) { - Position pos = BELOW; + AbstractPosition pos = BELOW; switch (position) { case atLeft: pos = AT_LEFT; @@ -266,11 +271,11 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } - private void show(RelativePoint target, Position position) { + private void show(RelativePoint target, AbstractPosition position) { show(new PositionTracker.Static(target), position); } - private void show(PositionTracker tracker, Position position) { + private void show(PositionTracker tracker, AbstractPosition position) { assert !myDisposed : "Balloon is already disposed"; if (isVisible()) return; @@ -279,7 +284,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi myTracker = tracker; myTracker.init(this); - Position originalPreferred = position; + AbstractPosition originalPreferred = position; JRootPane root = null; JDialog dialog = IJSwingUtilities.findParentOfType(tracker.getComponent(), JDialog.class); @@ -324,9 +329,9 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi Rectangle2D currentSquare = lp.createIntersection(rec); double maxSquare = currentSquare.getWidth() * currentSquare.getHeight(); - Position targetPosition = myPosition; + AbstractPosition targetPosition = myPosition; - for (Position eachPosition : myPosition.getOtherPositions()) { + for (AbstractPosition eachPosition : myPosition.getOtherPositions()) { Rectangle2D eachIntersection = lp.createIntersection(getRecForPosition(eachPosition, false)); double eachSquare = eachIntersection.getWidth() * eachIntersection.getHeight(); if (maxSquare < eachSquare) { @@ -383,7 +388,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi }, this); } - private Rectangle getRecForPosition(Position position, boolean adjust) { + private Rectangle getRecForPosition(AbstractPosition position, boolean adjust) { Dimension size = getContentSizeFor(position); Rectangle rec = new Rectangle(new Point(0, 0), size); @@ -398,7 +403,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi return rec; } - private Dimension getContentSizeFor(Position position) { + private Dimension getContentSizeFor(AbstractPosition position) { Insets insets = position.createBorder(this).getBorderInsets(); if (insets == null) { insets = new Insets(0, 0, 0, 0); @@ -514,18 +519,23 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi return 3; } - int getPointerWidth(Position position) { + int getPointerWidth(AbstractPosition position) { return position.isTopBottomPointer() ? 14 : 11; } - int getNormalInset() { + public static int getNormalInset() { return 3; } - int getPointerLength(Position position) { + static int getPointerLength(AbstractPosition position) { return position.isTopBottomPointer() ? 10 : 8; } + public static int getPointerLength(Position position) { + return getPointerLength((getAbstractPositionFor(position))); + } + + public void hide() { Disposer.dispose(this); @@ -596,14 +606,14 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } } - public abstract static class Position { + public abstract static class AbstractPosition { abstract EmptyBorder createBorder(final BalloonImpl balloon); abstract void setRecToRelativePosition(Rectangle rec, Point targetPoint); - abstract int getChangeShift(Position original, int xShift, int yShift); + abstract int getChangeShift(AbstractPosition original, int xShift, int yShift); public void updateBounds(final BalloonImpl balloon) { balloon.myComp._setBounds(getUpdatedBounds(balloon.myLayeredPane.getSize(), @@ -690,8 +700,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi protected abstract Rectangle getPointlessContentRec(Rectangle bounds, int pointerLength); - public Set getOtherPositions() { - HashSet all = new HashSet(); + public Set getOtherPositions() { + HashSet all = new HashSet(); all.add(BELOW); all.add(ABOVE); all.add(AT_RIGHT); @@ -705,13 +715,13 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi public abstract Point getShiftedPoint(Point targetPoint, int shift); } - public static final Position BELOW = new Below(); - public static final Position ABOVE = new Above(); - public static final Position AT_RIGHT = new AtRight(); - public static final Position AT_LEFT = new AtLeft(); + public static final AbstractPosition BELOW = new Below(); + public static final AbstractPosition ABOVE = new Above(); + public static final AbstractPosition AT_RIGHT = new AtRight(); + public static final AbstractPosition AT_LEFT = new AtLeft(); - private static class Below extends Position { + private static class Below extends AbstractPosition { @Override @@ -720,7 +730,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } @Override - int getChangeShift(Position original, int xShift, int yShift) { + int getChangeShift(AbstractPosition original, int xShift, int yShift) { return original == ABOVE ? yShift : 0; } @@ -772,7 +782,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } - private static class Above extends Position { + private static class Above extends AbstractPosition { @Override public Point getShiftedPoint(Point targetPoint, int shift) { @@ -780,7 +790,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } @Override - int getChangeShift(Position original, int xShift, int yShift) { + int getChangeShift(AbstractPosition original, int xShift, int yShift) { return original == BELOW ? -yShift : 0; } @@ -834,7 +844,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } } - private static class AtRight extends Position { + private static class AtRight extends AbstractPosition { @Override public Point getShiftedPoint(Point targetPoint, int shift) { @@ -842,7 +852,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } @Override - int getChangeShift(Position original, int xShift, int yShift) { + int getChangeShift(AbstractPosition original, int xShift, int yShift) { return original == AT_LEFT ? xShift : 0; } @@ -892,7 +902,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } } - private static class AtLeft extends Position { + private static class AtLeft extends AbstractPosition { @Override public Point getShiftedPoint(Point targetPoint, int shift) { @@ -900,7 +910,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } @Override - int getChangeShift(Position original, int xShift, int yShift) { + int getChangeShift(AbstractPosition original, int xShift, int yShift) { return original == AT_RIGHT ? -xShift : 0; } diff --git a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java index ee8865ba3a0e..900089dc08a2 100644 --- a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java +++ b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java @@ -20,14 +20,17 @@ import com.intellij.ide.IdeTooltip; import com.intellij.ide.IdeTooltipManager; import com.intellij.ide.TooltipEvent; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.components.panels.OpaquePanel; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import javax.swing.border.LineBorder; import javax.swing.event.EventListenerList; import java.awt.*; import java.awt.event.ActionEvent; @@ -177,13 +180,26 @@ public class LightweightHint extends UserDataHolderBase implements Hint { } else { myIsRealPopup = true; - myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(myComponent, myFocusRequestor) + Point actualPoint = new Point(x, y); + JComponent actualComponent = new OpaquePanel(new BorderLayout()); + actualComponent.add(myComponent, BorderLayout.CENTER); + if (myHintHint.isAwtTooltip()) { + fixActualPoint(actualPoint); + + + int inset = BalloonImpl.getNormalInset(); + actualComponent.setBorder(new LineBorder(hintHint.getTextBackground(), inset)); + actualComponent.setBackground(hintHint.getTextBackground()); + actualComponent.validate(); + } + + myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(actualComponent, myFocusRequestor) .setRequestFocus(myFocusRequestor != null) .setResizable(myResizable) .setMovable(myTitle != null) .setTitle(myTitle) .setModalContext(false) - .setShowShadow(!myForceLightweightPopup && myForceShowAsPopup) + .setShowShadow(isRealPopup()) .setCancelKeyEnabled(false) .setCancelOnClickOutside(myCancelOnClickOutside) .setCancelOnOtherWindowOpen(myCancelOnOtherWindowOpen) @@ -191,7 +207,30 @@ public class LightweightHint extends UserDataHolderBase implements Hint { .createPopup(); beforeShow(); - myPopup.show(new RelativePoint(myParentComponent, new Point(x, y))); + myPopup.show(new RelativePoint(myParentComponent, new Point(actualPoint.x, actualPoint.y))); + } + } + + private void fixActualPoint(Point actualPoint) { + if (!myHintHint.isAwtTooltip()) return; + if (!myIsRealPopup) return; + + Dimension size = myComponent.getPreferredSize(); + Balloon.Position position = myHintHint.getPreferredPosition(); + int shift = BalloonImpl.getPointerLength(position); + switch (position) { + case below: + actualPoint.y += shift; + break; + case above: + actualPoint.y -= (shift + size.height); + break; + case atLeft: + actualPoint.x -= (shift + size.width); + break; + case atRight: + actualPoint.y += shift; + break; } } @@ -203,7 +242,17 @@ public class LightweightHint extends UserDataHolderBase implements Hint { if (hintHint.isAwtTooltip()) { Dimension size = component.getPreferredSize(); Dimension paneSize = pane.getSize(); - return size.width < paneSize.width && size.height < paneSize.height; + + Point target = desiredLocation.getPointOn(pane).getPoint(); + Balloon.Position pos = hintHint.getPreferredPosition(); + int pointer = BalloonImpl.getPointerLength(pos) + BalloonImpl.getNormalInset(); + if (pos == Balloon.Position.above || pos == Balloon.Position.below) { + boolean hieghtFit = target.y - size.height - pointer > 0 || target.y + size.height + pointer < paneSize.height; + return hieghtFit && size.width + pointer < paneSize.width; + } else { + boolean widthFit = target.x - size.width - pointer > 0 || target.x + size.width + pointer < paneSize.width; + return widthFit && size.height + pointer < paneSize.height; + } } else { final Rectangle lpRect = new Rectangle(pane.getLocationOnScreen().x, pane.getLocationOnScreen().y, pane.getWidth(), pane.getHeight()); Rectangle componentRect = new Rectangle(desiredLocation.getScreenPoint().x, @@ -296,7 +345,9 @@ public class LightweightHint extends UserDataHolderBase implements Hint { private void updateBounds(int x, int y, boolean updateLocation) { setSize(myComponent.getPreferredSize()); if (updateLocation) { - setLocation(new RelativePoint(myParentComponent, new Point(x, y))); + Point point = new Point(x, y); + fixActualPoint(point); + setLocation(new RelativePoint(myParentComponent, point)); } } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index 87d293e51546..ad17e1a026f7 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -16,7 +16,6 @@ package com.intellij.ui.popup; import com.intellij.codeInsight.hint.HintUtil; -import com.intellij.ide.ui.UISettings; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.JBAwtEventQueue; @@ -27,7 +26,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.impl.ShadowBorderPainter; import com.intellij.openapi.ui.popup.*; import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; @@ -50,17 +48,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.border.EmptyBorder; import java.awt.*; import java.awt.event.*; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import static com.intellij.openapi.ui.impl.ShadowBorderPainter.*; - public class AbstractPopup implements JBPopup { private static final Logger LOG = Logger.getInstance("#com.intellij.ui.popup.AbstractPopup"); @@ -196,7 +190,7 @@ public class AbstractPopup implements JBPopup { myProject = project; myComponent = component; - myPopupBorder = PopupBorder.Factory.create(true); + myPopupBorder = PopupBorder.Factory.create(true, showShadow); myShadowed = showShadow; myPaintShadow = showShadow && !SystemInfo.isMac && !movable && !resizable && Registry.is("ide.popup.dropShadow"); myContent = createContentPanel(resizable, myPopupBorder, isToDrawMacCorner() && resizable); @@ -301,7 +295,7 @@ public class AbstractPopup implements JBPopup { @NotNull protected MyContentPanel createContentPanel(final boolean resizable, PopupBorder border, boolean isToDrawMacCorner) { - return new MyContentPanel(resizable, border, isToDrawMacCorner, myPaintShadow); + return new MyContentPanel(resizable, border, isToDrawMacCorner); } public static boolean isToDrawMacCorner() { @@ -1030,40 +1024,15 @@ public class AbstractPopup implements JBPopup { public static class MyContentPanel extends JPanel { private final boolean myResizable; private final boolean myDrawMacCorner; - private final boolean myPaintShadow; public MyContentPanel(final boolean resizable, final PopupBorder border, boolean drawMacCorner) { - this(resizable, border, drawMacCorner, false); - } - - public MyContentPanel(final boolean resizable, final PopupBorder border, boolean drawMacCorner, boolean shadowed) { super(new BorderLayout()); myResizable = resizable; myDrawMacCorner = drawMacCorner; - myPaintShadow = shadowed && !UISettings.isRemoteDesktopConnected(); - if (myPaintShadow) { - setOpaque(false); - setBorder(new EmptyBorder(POPUP_TOP_SIZE, POPUP_SIDE_SIZE, POPUP_BOTTOM_SIZE, POPUP_SIDE_SIZE) { - @Override - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - border.paintBorder(c, g, - x + POPUP_SIDE_SIZE - 1, - y + POPUP_TOP_SIZE - 1, - width - 2 * POPUP_SIDE_SIZE + 2, - height - POPUP_TOP_SIZE - POPUP_BOTTOM_SIZE + 2); - } - }); - } - else { - setBorder(border); - } + setBorder(border); } public void paint(Graphics g) { - if (myPaintShadow) { - paintShadow(g); - } - super.paint(g); if (myResizable && myDrawMacCorner) { @@ -1073,21 +1042,6 @@ public class AbstractPopup implements JBPopup { this); } } - - private void paintShadow(final Graphics g) { - BufferedImage capture = null; - try { - final Point onScreen = getLocationOnScreen(); - capture = new Robot().createScreenCapture( - new Rectangle(onScreen.x, onScreen.y, getWidth() + 2 * POPUP_SIDE_SIZE, getHeight() + POPUP_TOP_SIZE + POPUP_BOTTOM_SIZE)); - final BufferedImage shadow = ShadowBorderPainter.createPopupShadow(this, getWidth(), getHeight()); - ((Graphics2D)capture.getGraphics()).drawImage(shadow, null, null); - } - catch (Exception e) { - LOG.info(e); - } - if (capture != null) g.drawImage(capture, 0, 0, null); - } } public boolean isCancelOnClickOutside() { diff --git a/platform/util/src/com/intellij/ui/PopupBorder.java b/platform/util/src/com/intellij/ui/PopupBorder.java index 1eff0a877522..675a7edb52a2 100644 --- a/platform/util/src/com/intellij/ui/PopupBorder.java +++ b/platform/util/src/com/intellij/ui/PopupBorder.java @@ -29,9 +29,9 @@ public interface PopupBorder extends Border { private Factory() { } - public static PopupBorder create(boolean active) { + public static PopupBorder create(boolean active, boolean windowWithShadow) { final BaseBorder border = - SystemInfo.isMac ? new BaseBorder() : new BaseBorder(true, CaptionPanel.getBorderColor(true), CaptionPanel.getBorderColor(false)); + SystemInfo.isMac && windowWithShadow ? new BaseBorder() : new BaseBorder(true, CaptionPanel.getBorderColor(true), CaptionPanel.getBorderColor(false)); border.setActive(active); return border; } From fa14233b7bd494a164219fa1396fc3b47a76ea77 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 18:46:16 +0100 Subject: [PATCH 79/90] indents --- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index f7baddd2cfe9..983e113d15ac 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1230,7 +1230,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { c.ipady = 2; c.fill = GridBagConstraints.HORIZONTAL; final JPanel ad = new JPanel(new BorderLayout()); - ad.setBorder(new MatteBorder(1, 0, 0, 0, Color.lightGray)); + ad.setBorder(BorderFactory.createCompoundBorder(new MatteBorder(1, 0, 0, 0, Color.lightGray), new EmptyBorder(0, 2, 0, 7))); ad.setOpaque(false); if (items.size() > maxAutopopupItems) { From 537ee9cfcb5094087e9a4066c01f74bff9deac79 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 17 Feb 2011 18:21:19 +0100 Subject: [PATCH 80/90] Substitution for PsiDisjunctionType --- .../intellij/psi/impl/PsiSubstitutorImpl.java | 23 +++++++++++++++---- .../advHighlighting7/MultiCatch.java | 9 +++++--- .../intellij/psi/util/TypeConversionUtil.java | 9 ++++---- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java index a7676dc247f2..14527352e906 100644 --- a/java/java-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -18,6 +18,8 @@ package com.intellij.psi.impl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import gnu.trove.THashMap; import gnu.trove.TObjectHashingStrategy; @@ -25,10 +27,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author ik, dsl @@ -99,11 +98,13 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { } private abstract static class SubstitutionVisitorBase extends PsiTypeVisitorEx { + @Override public PsiType visitType(PsiType type) { LOG.assertTrue(false); return null; } + @Override public PsiType visitWildcardType(PsiWildcardType wildcardType) { final PsiType bound = wildcardType.getBound(); if (bound == null) { @@ -135,10 +136,12 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { return PsiWildcardType.createUnbounded(wildcardType.getManager()); } + @Override public PsiType visitPrimitiveType(PsiPrimitiveType primitiveType) { return primitiveType; } + @Override public PsiType visitArrayType(PsiArrayType arrayType) { final PsiType componentType = arrayType.getComponentType(); final PsiType substitutedComponentType = componentType.accept(this); @@ -147,6 +150,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { return new PsiArrayType(substitutedComponentType); } + @Override public PsiType visitEllipsisType(PsiEllipsisType ellipsisType) { final PsiType componentType = ellipsisType.getComponentType(); final PsiType substitutedComponentType = componentType.accept(this); @@ -155,15 +159,26 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { return new PsiEllipsisType(substitutedComponentType); } + @Override public PsiType visitTypeVariable(final PsiTypeVariable var) { return var; } + @Override public PsiType visitBottom(final Bottom bottom) { return bottom; } + @Override public abstract PsiType visitClassType(PsiClassType classType); + + @Override + public PsiType visitDisjunctionType(PsiDisjunctionType disjunctionType) { + final List substituted = ContainerUtil.map(disjunctionType.getDisjunctions(), new Function() { + @Override public PsiType fun(PsiType psiType) { return psiType.accept(SubstitutionVisitorBase.this); } + }); + return new PsiDisjunctionType(substituted, disjunctionType.getManager()); + } } private final SubstitutionVisitor myAddingBoundsSubstitutionVisitor = new SubstitutionVisitor(SubstituteKind.ADD_BOUNDS); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/MultiCatch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/MultiCatch.java index 69cf037ebaae..705ecd8a6550 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/MultiCatch.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/MultiCatch.java @@ -5,9 +5,10 @@ abstract class C { private static class E2 extends E { } private static class E3 extends E { } private static class RE extends RuntimeException { } - private interface I { } - private static class IE1 extends E implements I { } - private static class IE2 extends E implements I { } + private interface I { } + private static class IE1 extends E implements I { } + private static class IE2 extends E implements I { } + private static class F { F(X x) { } } abstract void f() throws E1, E2; abstract void g() throws IE1, IE2; @@ -18,6 +19,8 @@ abstract class C { try { f(); } catch (E2 | E1 e) { } catch (E e) { } catch (RE e) { } try { f(); } catch (E1 | E e) { E ee = e; } try { g(); } catch (IE1 | IE2 e) { E ee = e; I ii = e; } + try { g(); } catch (IE1 | IE2 e) { F f = new F<>(e); } + try { g(); } catch (IE1 | IE2 e) { new F>(e); } try { f(); } catch (E1 | E2 | E3 e) { } try { f(); } catch (E3 | E e) { } diff --git a/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java b/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java index feb7c854bd8e..bbe345501d62 100644 --- a/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/openapi/src/com/intellij/psi/util/TypeConversionUtil.java @@ -24,6 +24,7 @@ import com.intellij.psi.*; import com.intellij.psi.infos.ClassCandidateInfo; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; +import com.intellij.util.Function; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; @@ -1166,11 +1167,9 @@ public class TypeConversionUtil { @Override public PsiType visitDisjunctionType(PsiDisjunctionType disjunctionType) { - final List original = disjunctionType.getDisjunctions(); - final List erased = new ArrayList(original.size()); - for (PsiType psiType : original) { - erased.add(erasure(psiType, beforeSubstitutor)); - } + final List erased = ContainerUtil.map(disjunctionType.getDisjunctions(), new Function() { + @Override public PsiType fun(PsiType psiType) { return erasure(psiType, beforeSubstitutor); } + }); return new PsiDisjunctionType(erased, disjunctionType.getManager()); } }); From ca1bdc825d472787d793874e32bf17246d59e59d Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 17 Feb 2011 21:11:44 +0300 Subject: [PATCH 81/90] IDEA-65266 Pressing Ctrl+P hid text under cursor + other hint fixes - 2 --- .../intellij/codeInsight/hint/ParameterInfoComponent.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java index fd82f3913f66..5c459cde6457 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java @@ -313,11 +313,9 @@ class ParameterInfoComponent extends JPanel{ Dimension normalPreferredSize = super.getPreferredSize(); // some fonts (for example, Arial Black Cursiva) have NORMAL characters wider than BOLD characters - Dimension d = new Dimension(Math.max(boldPreferredSize.width, normalPreferredSize.width), - Math.max(boldPreferredSize.height, normalPreferredSize.height)); - System.out.println("d = " + d); - return d; + return new Dimension(Math.max(boldPreferredSize.width, normalPreferredSize.width), + Math.max(boldPreferredSize.height, normalPreferredSize.height)); } } } From 06a34227826c9082df0a06b3779d89cb840a42e1 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Thu, 17 Feb 2011 21:28:48 +0300 Subject: [PATCH 82/90] IDEA-63634 Correct method parameters hint processing --- platform/platform-impl/src/com/intellij/ui/BalloonImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index 0241f7886fcd..c13aca602281 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -786,7 +786,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi @Override public Point getShiftedPoint(Point targetPoint, int shift) { - return new Point(targetPoint.x, targetPoint.y - shift); + return new Point(targetPoint.x, targetPoint.y + shift); } @Override From 3c2db3502af86cfc83b6ee68f9a0d24330534597 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 17 Feb 2011 19:16:48 +0100 Subject: [PATCH 83/90] @NotNull --- .../com/intellij/testFramework/fixtures/TempDirTestFixture.java | 2 +- .../fixtures/impl/LightTempDirTestFixtureImpl.java | 2 +- .../testFramework/fixtures/impl/TempDirTestFixtureImpl.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/TempDirTestFixture.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/TempDirTestFixture.java index dd2ffcc03a7a..faa86b4415ee 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/TempDirTestFixture.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/TempDirTestFixture.java @@ -28,7 +28,7 @@ import java.io.IOException; */ public interface TempDirTestFixture extends IdeaTestFixture { - VirtualFile copyFile(VirtualFile file, String targetPath); + VirtualFile copyFile(@NotNull VirtualFile file, String targetPath); VirtualFile copyAll(String dataDir, String targetDir); diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightTempDirTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightTempDirTestFixtureImpl.java index ad0934eb4242..9a9aefddc574 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightTempDirTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/LightTempDirTestFixtureImpl.java @@ -54,7 +54,7 @@ public class LightTempDirTestFixtureImpl extends BaseFixture implements TempDirT } @Override - public VirtualFile copyFile(final VirtualFile file, final String targetPath) { + public VirtualFile copyFile(@NotNull final VirtualFile file, final String targetPath) { final String path = PathUtil.getParentPath(targetPath); return ApplicationManager.getApplication().runWriteAction(new Computable() { @Override diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/TempDirTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/TempDirTestFixtureImpl.java index 0ed70e8aca83..c0d4a4176917 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/TempDirTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/TempDirTestFixtureImpl.java @@ -40,7 +40,7 @@ public class TempDirTestFixtureImpl extends BaseFixture implements TempDirTestFi private File myTempDir; @Override - public VirtualFile copyFile(VirtualFile file, String targetPath) { + public VirtualFile copyFile(@NotNull VirtualFile file, String targetPath) { try { createTempDirectory(); VirtualFile tempDir = From 1dbdb1377c088732bf1870668e4e63339a4ec231 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 17 Feb 2011 19:51:15 +0100 Subject: [PATCH 84/90] first stab at an inspection to detect identical 'catch' blocks in a 'try' statement (quickfix coming soon) --- .../util/duplicates/DuplicatesFinder.java | 21 ++-- .../refactoring/util/duplicates/Match.java | 12 ++- .../siyeh/InspectionGadgetsBundle.properties | 4 +- .../src/com/siyeh/ig/BaseInspection.java | 7 ++ .../com/siyeh/ig/BaseInspectionVisitor.java | 9 +- .../com/siyeh/ig/InspectionGadgetsPlugin.java | 1 + .../TryWithIdenticalCatchesInspection.java | 95 +++++++++++++++++++ .../TryWithIdenticalCatches.html | 7 ++ .../TryIdenticalCatches.java | 35 +++++++ .../TryWithIdenticalCatchesTest.java | 35 +++++++ 10 files changed, 213 insertions(+), 13 deletions(-) create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesInspection.java create mode 100644 plugins/InspectionGadgets/src/inspectionDescriptions/TryWithIdenticalCatches.html create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesTest.java diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java index 65f2783627ac..fb1f1494d5ed 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java +++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java @@ -34,6 +34,7 @@ import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.IntArrayList; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -49,12 +50,12 @@ public class DuplicatesFinder { private final List myOutputParameters; private final List myPatternAsList; private boolean myMultipleExitPoints = false; - private final ReturnValue myReturnValue; + @Nullable private final ReturnValue myReturnValue; public DuplicatesFinder(PsiElement[] pattern, InputVariables parameters, - ReturnValue returnValue, - List outputParameters + @Nullable ReturnValue returnValue, + @NotNull List outputParameters ) { myReturnValue = returnValue; LOG.assertTrue(pattern.length > 0); @@ -109,6 +110,14 @@ public class DuplicatesFinder { return result; } + @Nullable + public Match isDuplicate(PsiElement element, boolean ignoreParameterTypes) { + annotatePattern(); + Match match = isDuplicateFragment(element, ignoreParameterTypes); + deannotatePattern(); + return match; + } + private void annotatePattern() { for (final PsiElement patternComponent : myPattern) { patternComponent.accept(new JavaRecursiveElementWalkingVisitor() { @@ -146,7 +155,7 @@ public class DuplicatesFinder { private void findPatternOccurrences(List array, PsiElement scope) { PsiElement[] children = scope.getChildren(); for (PsiElement child : children) { - final Match match = isDuplicateFragment(child); + final Match match = isDuplicateFragment(child, false); if (match != null) { array.add(match); continue; @@ -157,7 +166,7 @@ public class DuplicatesFinder { @Nullable - private Match isDuplicateFragment(PsiElement candidate) { + private Match isDuplicateFragment(PsiElement candidate, boolean ignoreParameterTypes) { if (PsiTreeUtil.isAncestor(myPattern[0], candidate, false)) return null; PsiElement sibling = candidate; ArrayList candidates = new ArrayList(); @@ -188,7 +197,7 @@ public class DuplicatesFinder { } } - final Match match = new Match(candidates.get(0), candidates.get(candidates.size() - 1)); + final Match match = new Match(candidates.get(0), candidates.get(candidates.size() - 1), ignoreParameterTypes); for (int i = 0; i < myPattern.length; i++) { if (!matchPattern(myPattern[i], candidates.get(i), candidates, match)) return null; } diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java index c2383b7cec7b..7686ec98a965 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java +++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java @@ -48,16 +48,18 @@ public final class Match { private final PsiElement myMatchStart; private final PsiElement myMatchEnd; private final Map> myParameterValues = new HashMap>(); - private final Map> myParameterOccurences = new HashMap>(); + private final Map> myParameterOccurrences = new HashMap>(); private final Map myDeclarationCorrespondence = new HashMap(); private ReturnValue myReturnValue = null; private Ref myInstanceExpression = null; private final Map myChangedParams = new HashMap(); + private final boolean myIgnoreParameterTypes; - Match(PsiElement start, PsiElement end) { + Match(PsiElement start, PsiElement end, boolean ignoreParameterTypes) { LOG.assertTrue(start.getParent() == end.getParent()); myMatchStart = start; myMatchEnd = end; + myIgnoreParameterTypes = ignoreParameterTypes; } @@ -135,14 +137,14 @@ public final class Match { myChangedParams.put(psiVariable, new PsiEllipsisType(parameterType)); } } else { - if (!parameterType.isAssignableFrom(type)) return false; //todo + if (!myIgnoreParameterTypes && !parameterType.isAssignableFrom(type)) return false; //todo } } final List values = new ArrayList(); values.add(value); myParameterValues.put(psiVariable, values); final ArrayList elements = new ArrayList(); - myParameterOccurences.put(psiVariable, elements); + myParameterOccurrences.put(psiVariable, elements); return true; } else { @@ -157,7 +159,7 @@ public final class Match { currentValue.add(value); } } - myParameterOccurences.get(psiVariable).add(value); + myParameterOccurrences.get(psiVariable).add(value); return true; } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index 0a9522cf8c9c..86d8cc95e568 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1843,4 +1843,6 @@ package.dot.html.delete.command=package.html deletion package.dot.html.may.be.package.info.convert.quickfix=Convert to package-info.java package.dot.html.convert.command=package.html to package-info.java conversion choose.super.class.to.ignore=Choose class -ignore.anonymous.inner.classes=Ignore anonymous inner classes \ No newline at end of file +ignore.anonymous.inner.classes=Ignore anonymous inner classes +try.with.identical.catches.display.name=Identical 'catch' branches in 'try' statement +try.with.identical.catches.problem.descriptor=Identical 'catch' branches in 'try' statement #loc diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspection.java index 0607fd78b62c..5deb22cc2a72 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspection.java @@ -24,7 +24,9 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElementVisitor; import com.intellij.ui.DocumentAdapter; import com.siyeh.ig.ui.FormattedTextFieldMacFix; @@ -283,4 +285,9 @@ public abstract class BaseInspection extends BaseJavaLocalInspectionTool { inspectionGadgetsPlugin = null; } } + + @Nullable + public TextRange getProblemTextRange(PsiElement element) { + return null; + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspectionVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspectionVisitor.java index c365f9e72c54..e93b09e95c3a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspectionVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/BaseInspectionVisitor.java @@ -16,6 +16,7 @@ package com.siyeh.ig; import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -167,7 +168,13 @@ public abstract class BaseInspectionVisitor extends JavaElementVisitor{ fix.setOnTheFly(onTheFly); } final String description = inspection.buildErrorString(infos); - holder.registerProblem(location, description, fixes); + TextRange range = inspection.getProblemTextRange(location); + if (range != null) { + holder.registerProblem(location, range, description, fixes); + } + else { + holder.registerProblem(location, description, fixes); + } } @NotNull diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java index f16ffba98be5..dea51ebec133 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/InspectionGadgetsPlugin.java @@ -833,6 +833,7 @@ public class InspectionGadgetsPlugin implements ApplicationComponent, m_inspectionClasses.add(ThrowFromFinallyBlockInspection.class); m_inspectionClasses.add(TooBroadCatchInspection.class); m_inspectionClasses.add(TooBroadThrowsInspection.class); + m_inspectionClasses.add(TryWithIdenticalCatchesInspection.class); m_inspectionClasses.add(UncheckedExceptionClassInspection.class); m_inspectionClasses.add(UnusedCatchParameterInspection.class); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesInspection.java new file mode 100644 index 000000000000..0bbceef35b6c --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesInspection.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.errorhandling; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.extractMethod.InputVariables; +import com.intellij.refactoring.util.duplicates.DuplicatesFinder; +import com.intellij.refactoring.util.duplicates.Match; +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.BaseInspectionVisitor; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; + +/** + * @author yole + */ +public class TryWithIdenticalCatchesInspection extends BaseInspection { + @NotNull + @Override + protected String buildErrorString(Object... infos) { + return InspectionGadgetsBundle.message("try.with.identical.catches.problem.descriptor"); + } + + @Override + public BaseInspectionVisitor buildVisitor() { + return new TryWithIdenticalCatchesVisitor(); + } + + @Nls + @NotNull + @Override + public String getDisplayName() { + return InspectionGadgetsBundle.message("try.with.identical.catches.display.name"); + } + + @Override + public TextRange getProblemTextRange(PsiElement element) { + if (element instanceof PsiCatchSection) { + PsiJavaToken rParenth = ((PsiCatchSection)element).getRParenth(); + if (rParenth != null) { + return new TextRange(0, rParenth.getTextOffset() + 1 - element.getTextOffset()); + } + } + return null; + } + + private static class TryWithIdenticalCatchesVisitor extends BaseInspectionVisitor { + @Override + public void visitTryStatement(PsiTryStatement statement) { + super.visitTryStatement(statement); + if (!PsiUtil.isLanguageLevel7OrHigher(statement)) { + return; + } + PsiCatchSection[] catchSections = statement.getCatchSections(); + boolean[] duplicates = new boolean[catchSections.length]; + for (int i = 0; i < catchSections.length; i++) { + if (duplicates[i]) continue; + InputVariables inputVariables = new InputVariables(Collections.singletonList(catchSections[i].getParameter()), + statement.getProject(), + new LocalSearchScope(catchSections[i].getCatchBlock()), + false); + DuplicatesFinder finder = new DuplicatesFinder(new PsiElement[] { catchSections [i].getCatchBlock() }, + inputVariables, null, Collections.emptyList()); + for (int j = 0; j < catchSections.length; j++) { + if (i == j || duplicates[j]) continue; + Match match = finder.isDuplicate(catchSections[j].getCatchBlock(), true); + if (match != null) { + registerError(catchSections[j]); + duplicates[i] = true; + duplicates[j] = true; + } + } + } + } + } +} diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/TryWithIdenticalCatches.html b/plugins/InspectionGadgets/src/inspectionDescriptions/TryWithIdenticalCatches.html new file mode 100644 index 000000000000..887abc484396 --- /dev/null +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/TryWithIdenticalCatches.html @@ -0,0 +1,7 @@ + + +This inspection reports identical 'catch' sections in 'try' blocks under JDK 7. A quickfix is provided to collapse the sections into +a multi-catch section. +Powered by InspectionGadgets + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java new file mode 100644 index 000000000000..bb3049b3e80e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java @@ -0,0 +1,35 @@ +package com.siyeh.igtest.errorhandling.try_identical_catches; + +class TryIdenticalCatches { + public void notIdentical() { + try { + + } + catch(NumberFormatException e) { + log(e); + } + catch(RuntimeException e) { + throw e; + } + } + + public void identical(boolean value) { + try { + if (value) { + throw new ClassNotFoundException(); + } + else { + throw new NumberFormatException(); + } + } + catch(ClassNotFoundException cnfe) { + log(cnfe); + } + catch(NumberFormatException nfe) { + log(nfe); + } + } + + private void log(Exception e) { + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesTest.java new file mode 100644 index 000000000000..69771c0cf90d --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.errorhandling; + +import com.intellij.openapi.application.PluginPathManager; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; + +/** + * @author yole + */ +public class TryWithIdenticalCatchesTest extends LightCodeInsightFixtureTestCase { + public void test() { + myFixture.enableInspections(TryWithIdenticalCatchesInspection.class); + myFixture.configureByFile("com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java"); + myFixture.checkHighlighting(true, false, false); + } + + @Override + protected String getBasePath() { + return PluginPathManager.getPluginHomePathRelative("InspectionGadgets") + "/test"; + } +} From a038ba9c4f937a8888288a1050be28b25213a1e1 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 17 Feb 2011 20:13:02 +0100 Subject: [PATCH 85/90] quickfix to collapse identical catch sections into multi-catch --- .../TryWithIdenticalCatchesInspection.java | 45 ++++++++++++++++++- .../TryIdenticalCatches.after.java | 32 +++++++++++++ .../TryIdenticalCatches.java | 2 +- .../TryWithIdenticalCatchesTest.java | 5 +++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.after.java diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesInspection.java index 0bbceef35b6c..bfe4f41616b5 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesInspection.java @@ -15,6 +15,8 @@ */ package com.siyeh.ig.errorhandling; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.search.LocalSearchScope; @@ -22,9 +24,11 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.extractMethod.InputVariables; import com.intellij.refactoring.util.duplicates.DuplicatesFinder; import com.intellij.refactoring.util.duplicates.Match; +import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.InspectionGadgetsFix; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -63,6 +67,11 @@ public class TryWithIdenticalCatchesInspection extends BaseInspection { return null; } + @Override + protected InspectionGadgetsFix buildFix(Object... infos) { + return new CollapseCatchSectionsFix((Integer) infos[0]); + } + private static class TryWithIdenticalCatchesVisitor extends BaseInspectionVisitor { @Override public void visitTryStatement(PsiTryStatement statement) { @@ -84,7 +93,7 @@ public class TryWithIdenticalCatchesInspection extends BaseInspection { if (i == j || duplicates[j]) continue; Match match = finder.isDuplicate(catchSections[j].getCatchBlock(), true); if (match != null) { - registerError(catchSections[j]); + registerError(catchSections[j], i); duplicates[i] = true; duplicates[j] = true; } @@ -92,4 +101,38 @@ public class TryWithIdenticalCatchesInspection extends BaseInspection { } } } + + private static class CollapseCatchSectionsFix extends InspectionGadgetsFix { + private final int myCollapseIntoIndex; + + public CollapseCatchSectionsFix(int collapseIntoIndex) { + myCollapseIntoIndex = collapseIntoIndex; + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { + PsiCatchSection section = (PsiCatchSection) descriptor.getPsiElement(); + PsiTryStatement stmt = (PsiTryStatement) section.getParent(); + PsiCatchSection[] catchSections = stmt.getCatchSections(); + if (myCollapseIntoIndex >= catchSections.length) { + return; // something has gone stale + } + PsiCatchSection collapseInto = catchSections[myCollapseIntoIndex]; + PsiParameter parameter1 = collapseInto.getParameter(); + PsiParameter parameter2 = section.getParameter(); + if (parameter1 == null || parameter2 == null) { + return; + } + String text = "try { } catch(" + parameter1.getTypeElement().getText() + " | " + parameter2.getTypeElement().getText() + " e) { }"; + PsiTryStatement newTryCatch = (PsiTryStatement)JavaPsiFacade.getElementFactory(project).createStatementFromText(text, stmt); + parameter1.getTypeElement().replace(newTryCatch.getCatchSections() [0].getParameter().getTypeElement()); + section.delete(); + } + + @NotNull + @Override + public String getName() { + return"Collapse catch blocks into multi-catch"; + } + } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.after.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.after.java new file mode 100644 index 000000000000..79dcbcb6e65b --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.after.java @@ -0,0 +1,32 @@ +package com.siyeh.igtest.errorhandling.try_identical_catches; + +class TryIdenticalCatches { + public void notIdentical() { + try { + + } + catch(NumberFormatException e) { + log(e); + } + catch(RuntimeException e) { + throw e; + } + } + + public void identical(boolean value) { + try { + if (value) { + throw new ClassNotFoundException(); + } + else { + throw new NumberFormatException(); + } + } + catch(ClassNotFoundException | NumberFormatException cnfe) { + log(cnfe); + } + } + + private void log(Exception e) { + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java index bb3049b3e80e..1e6712046875 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java @@ -25,7 +25,7 @@ class TryIdenticalCatches { catch(ClassNotFoundException cnfe) { log(cnfe); } - catch(NumberFormatException nfe) { + catch(NumberFormatException nfe) { log(nfe); } } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesTest.java index 69771c0cf90d..24d77d236ebf 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/errorhandling/TryWithIdenticalCatchesTest.java @@ -15,6 +15,7 @@ */ package com.siyeh.ig.errorhandling; +import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.application.PluginPathManager; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; @@ -26,6 +27,10 @@ public class TryWithIdenticalCatchesTest extends LightCodeInsightFixtureTestCase myFixture.enableInspections(TryWithIdenticalCatchesInspection.class); myFixture.configureByFile("com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.java"); myFixture.checkHighlighting(true, false, false); + IntentionAction intention = myFixture.findSingleIntention("Collapse catch blocks into multi-catch"); + assertNotNull(intention); + myFixture.launchAction(intention); + myFixture.checkResultByFile("com/siyeh/igtest/errorhandling/try_identical_catches/TryIdenticalCatches.after.java"); } @Override From 8f0160e68f3ad263829f9cf6aadbe74886542307 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 19:07:56 +0100 Subject: [PATCH 86/90] diagnostics --- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 983e113d15ac..4efa582c0521 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -342,6 +342,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { if (!ApplicationManager.getApplication().isUnitTestMode()) { ApplicationManager.getApplication().assertIsDispatchThread(); } + assert !myDisposed; final Pair,Iterable>> snapshot = myModel.getModelSnapshot(); From 1cc5e6339bfee2b5edaa147f740ae4ababaf46e3 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 19:48:41 +0100 Subject: [PATCH 87/90] IDEA-65583: insert import when completing a class reference with existing generics on tab, replace the generics, if any --- .../completion/ConstructorInsertHandler.java | 12 ++++++++++++ .../completion/JavaClassNameInsertHandler.java | 17 ++++++++++------- .../completion/JavaCompletionContributor.java | 9 +++++++++ .../normal/ClassNameWithGenericsTab2.java | 8 ++++++++ .../normal/ClassNameWithGenericsTab2_after.java | 8 ++++++++ .../completion/normal/ImportInGenericType.java | 5 +++++ .../normal/ImportInGenericType_after.java | 7 +++++++ .../completion/NormalCompletionTest.groovy | 2 ++ 8 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/ClassNameWithGenericsTab2.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/ClassNameWithGenericsTab2_after.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/ImportInGenericType.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/ImportInGenericType_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index bea298445334..37d9c74d9e08 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -4,6 +4,7 @@ import com.intellij.codeInsight.generation.GenerateMembersUtil; import com.intellij.codeInsight.generation.OverrideImplementUtil; import com.intellij.codeInsight.generation.PsiGenerationInfo; import com.intellij.codeInsight.generation.PsiMethodMember; +import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupElementDecorator; import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.featureStatistics.FeatureUsageTracker; @@ -34,6 +35,8 @@ class ConstructorInsertHandler implements InsertHandler= 0 && plEnd >= 0) { + context.getDocument().deleteString(plStart, plEnd); + PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); + } + } + insertParentheses(context, delegate, delegate.getObject(), withTail && isAbstract); DefaultInsertHandler.addImportForItem(context, delegate); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java index 4f265740cc16..19a7ae421770 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameInsertHandler.java @@ -79,13 +79,7 @@ class JavaClassNameInsertHandler implements InsertHandler 0) { + if (PsiTreeUtil.getParentOfType(position, PsiDocTag.class) != null && ref.isReferenceTo(psiClass)) { return; } } @@ -132,6 +126,15 @@ class JavaClassNameInsertHandler implements InsertHandler 0) { + return false; + } + final PsiElement prevElement = FilterPositionUtil.searchNonSpaceNonCommentBack(ref); if (prevElement != null && prevElement.getParent() instanceof PsiNewExpression) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 81807cd7b863..5c834c965a1b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -536,6 +536,15 @@ public class JavaCompletionContributor extends CompletionContributor { final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset(file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false); if (ref != null && !(ref instanceof PsiReferenceExpression)) { context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";"); + + if (JavaSmartCompletionContributor.AFTER_NEW.accepts(ref)) { + final PsiReferenceParameterList paramList = ref.getParameterList(); + if (paramList != null && paramList.getTextLength() > 0) { + context.getOffsetMap().addOffset(ConstructorInsertHandler.PARAM_LIST_START, paramList.getTextRange().getStartOffset()); + context.getOffsetMap().addOffset(ConstructorInsertHandler.PARAM_LIST_END, paramList.getTextRange().getEndOffset()); + } + } + return; } diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithGenericsTab2.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithGenericsTab2.java new file mode 100644 index 000000000000..20b2f662d368 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithGenericsTab2.java @@ -0,0 +1,8 @@ +import java.util.ArrayList; +import java.util.List; + +public class Foo { + public static void main(String[] args) { + List set = new ArrayList(); + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithGenericsTab2_after.java b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithGenericsTab2_after.java new file mode 100644 index 000000000000..afc79f2b3279 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ClassNameWithGenericsTab2_after.java @@ -0,0 +1,8 @@ +import java.util.ArrayList; +import java.util.List; + +public class Foo { + public static void main(String[] args) { + List set = new ArrayList(); + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/ImportInGenericType.java b/java/java-tests/testData/codeInsight/completion/normal/ImportInGenericType.java new file mode 100644 index 000000000000..07c2a4b0437f --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ImportInGenericType.java @@ -0,0 +1,5 @@ +public class Foo { + public static void main(String[] args) { + Set + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/ImportInGenericType_after.java b/java/java-tests/testData/codeInsight/completion/normal/ImportInGenericType_after.java new file mode 100644 index 000000000000..3303a67472d4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ImportInGenericType_after.java @@ -0,0 +1,7 @@ +import java.util.Set; + +public class Foo { + public static void main(String[] args) { + Set + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index 4d5e6e857e79..b32981e99d55 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -676,6 +676,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { public void testReturningTypeVariable() throws Throwable { doTest(); } public void testReturningTypeVariable2() throws Throwable { doTest(); } public void testReturningTypeVariable3() throws Throwable { doTest(); } + public void testImportInGenericType() throws Throwable { doTest(); } public void testCaseTailType() throws Throwable { doTest(); } @@ -808,6 +809,7 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { public void testClassNameWithInnersTab() throws Throwable { doTest('\t') } public void testClassNameWithGenericsTab() throws Throwable {doTest('\t') } + public void testClassNameWithGenericsTab2() throws Throwable {doTest('\t') } public void testLiveTemplatePrefixTab() throws Throwable {doTest('\t') } From f437580a066001026d97ba5d826c81dece55bbd3 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 19:50:05 +0100 Subject: [PATCH 88/90] tab/enter in hint mode should choose the first item --- .../src/com/intellij/codeInsight/lookup/impl/LookupImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 4efa582c0521..c9085877ff6b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -389,7 +389,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable { if (!model.isEmpty()) { myList.setFixedCellWidth(Math.max(myLookupTextWidth + myCellRenderer.getIconIndent(), myAdComponent.getPreferredSize().width)); - if (isFocused() && (!isExactPrefixItem(model.iterator().next()) || mySelectionTouched)) { + if (isFocused() && (!isExactPrefixItem(model.iterator().next()) || mySelectionTouched) && !isHintMode()) { restoreSelection(oldSelected, hasPreselected, oldInvariant); } else { From a6b90a29aaad05662887f99bfc7a5420545095be Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Feb 2011 21:15:58 +0100 Subject: [PATCH 89/90] diagnosing NCDFE --- .../util/src/com/intellij/openapi/util/Disposer.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/openapi/util/Disposer.java b/platform/util/src/com/intellij/openapi/util/Disposer.java index 5bf7c49b4097..741916c7f9b8 100644 --- a/platform/util/src/com/intellij/openapi/util/Disposer.java +++ b/platform/util/src/com/intellij/openapi/util/Disposer.java @@ -30,7 +30,16 @@ import java.util.Map; @SuppressWarnings({"SSBasedInspection"}) public class Disposer { - private static final ObjectTree ourTree = new ObjectTree(); + private static final ObjectTree ourTree; + + static { + try { + ourTree = new ObjectTree(); + } + catch (NoClassDefFoundError e) { + throw new RuntimeException("loader=" + Disposer.class.getClassLoader(), e); + } + } private static final ObjectTreeAction ourDisposeAction = new ObjectTreeAction() { public void execute(final Disposable each) { From 74a8f43e8b9bbd15326f892dac902796227665d7 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 18 Feb 2011 10:35:35 +0300 Subject: [PATCH 90/90] IDEA-65622: Generated ant script does not run pre/post ant tasks --- .../ant/artifacts/ArtifactsGenerator.java | 13 ++- .../compiler/ant/ChunkBuildExtension.java | 4 + plugins/ant/src/META-INF/plugin.xml | 1 + .../artifacts/AntArtifactBuildExtension.java | 87 +++++++++++++++++++ ...ifactPostprocessingPropertiesProvider.java | 4 + ...tifactPreProcessingPropertiesProvider.java | 4 + 6 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactBuildExtension.java diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactsGenerator.java b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactsGenerator.java index e10c152397a4..57b54a7405f1 100644 --- a/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactsGenerator.java +++ b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactsGenerator.java @@ -15,10 +15,7 @@ */ package com.intellij.compiler.ant.artifacts; -import com.intellij.compiler.ant.BuildProperties; -import com.intellij.compiler.ant.Comment; -import com.intellij.compiler.ant.GenerationOptions; -import com.intellij.compiler.ant.Generator; +import com.intellij.compiler.ant.*; import com.intellij.compiler.ant.taskdefs.*; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; @@ -158,6 +155,7 @@ public class ArtifactsGenerator { final String outputPath = BuildProperties.propertyRef(myContext.getArtifactOutputProperty(artifact)); artifactTarget.add(new Mkdir(outputPath)); + generateTasksForArtifacts(artifact, artifactTarget, true); final DirectoryAntCopyInstructionCreator creator = new DirectoryAntCopyInstructionCreator(outputPath); @@ -170,9 +168,16 @@ public class ArtifactsGenerator { for (Generator tag : copyInstructions) { artifactTarget.add(tag); } + generateTasksForArtifacts(artifact, artifactTarget, false); return artifactTarget; } + private void generateTasksForArtifacts(Artifact artifact, Target artifactTarget, final boolean preprocessing) { + for (ChunkBuildExtension extension : ChunkBuildExtension.EP_NAME.getExtensions()) { + extension.generateTasksForArtifact(myResolvingContext.getProject(), artifact, preprocessing, artifactTarget); + } + } + public List getCleanTargetNames() { final List targets = new ArrayList(); for (Artifact artifact : myAllArtifacts) { diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java index eb896db7ffe7..d0318e1d9ac3 100644 --- a/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java +++ b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java @@ -20,6 +20,7 @@ import com.intellij.ExtensionPoints; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; +import com.intellij.packaging.artifacts.Artifact; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; @@ -44,6 +45,9 @@ public abstract class ChunkBuildExtension { public void generateProperties(final PropertyFileGenerator generator, final Project project, final GenerationOptions options) { } + public void generateTasksForArtifact(Project project, Artifact artifact, boolean preprocessing, CompositeGenerator generator) { + } + public List getCleanTargetNames(Project project, GenerationOptions genOptions) { return Collections.emptyList(); } diff --git a/plugins/ant/src/META-INF/plugin.xml b/plugins/ant/src/META-INF/plugin.xml index d1b3915d0432..fcbbeab06305 100644 --- a/plugins/ant/src/META-INF/plugin.xml +++ b/plugins/ant/src/META-INF/plugin.xml @@ -16,6 +16,7 @@ + diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactBuildExtension.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactBuildExtension.java new file mode 100644 index 000000000000..89e301020cda --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactBuildExtension.java @@ -0,0 +1,87 @@ +/* + * Copyright 2000-2011 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.lang.ant.config.impl.artifacts; + +import com.intellij.compiler.ant.*; +import com.intellij.compiler.ant.taskdefs.AntCall; +import com.intellij.compiler.ant.taskdefs.Import; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ArtifactManager; +import com.intellij.packaging.artifacts.ArtifactPropertiesProvider; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + +/** + * @author nik + */ +public class AntArtifactBuildExtension extends ChunkBuildExtension { + @Override + public void generateProjectTargets(Project project, GenerationOptions genOptions, CompositeGenerator generator) { + final Artifact[] artifacts = ArtifactManager.getInstance(project).getSortedArtifacts(); + Set filesToImport = new LinkedHashSet(); + for (Artifact artifact : artifacts) { + for (Boolean value : Arrays.asList(true, false)) { + final AntArtifactProperties properties = getProperties(artifact, value); + if (properties != null) { + filesToImport.add(properties.getFileUrl()); + } + } + } + for (String url : filesToImport) { + final String path = VfsUtil.urlToPath(url); + final String relativePath = GenerationUtils.toRelativePath(path, BuildProperties.getProjectBaseDir(project), BuildProperties.getProjectBaseDirProperty(), genOptions); + generator.add(new Import(relativePath)); + } + } + + @Override + public void generateTasksForArtifact(Project project, Artifact artifact, boolean preprocessing, CompositeGenerator generator) { + final AntArtifactProperties properties = getProperties(artifact, preprocessing); + if (properties != null) { + generator.add(new AntCall(properties.getTargetName())); + } + } + + @Nullable + private static AntArtifactProperties getProperties(Artifact artifact, boolean preprocessing) { + final ArtifactPropertiesProvider provider; + if (preprocessing) { + provider = AntArtifactPreProcessingPropertiesProvider.getInstance(); + } + else { + provider = AntArtifactPostprocessingPropertiesProvider.getInstance(); + } + final AntArtifactProperties properties = (AntArtifactProperties)artifact.getProperties(provider); + return properties != null && properties.isEnabled() ? properties : null; + } + + @NotNull + @Override + public String[] getTargets(ModuleChunk chunk) { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + @Override + public void process(Project project, ModuleChunk chunk, GenerationOptions genOptions, CompositeGenerator generator) { + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactPostprocessingPropertiesProvider.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactPostprocessingPropertiesProvider.java index 4ff35bef72f4..cc62f0990467 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactPostprocessingPropertiesProvider.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactPostprocessingPropertiesProvider.java @@ -24,6 +24,10 @@ import org.jetbrains.annotations.NotNull; * @author nik */ public class AntArtifactPostprocessingPropertiesProvider extends ArtifactPropertiesProvider { + public static AntArtifactPostprocessingPropertiesProvider getInstance() { + return EP_NAME.findExtension(AntArtifactPostprocessingPropertiesProvider.class); + } + protected AntArtifactPostprocessingPropertiesProvider() { super("ant-postprocessing"); } diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactPreProcessingPropertiesProvider.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactPreProcessingPropertiesProvider.java index cf0a73956c7b..be29f129dd86 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactPreProcessingPropertiesProvider.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/artifacts/AntArtifactPreProcessingPropertiesProvider.java @@ -24,6 +24,10 @@ import org.jetbrains.annotations.NotNull; * @author nik */ public class AntArtifactPreProcessingPropertiesProvider extends ArtifactPropertiesProvider { + public static AntArtifactPreProcessingPropertiesProvider getInstance() { + return EP_NAME.findExtension(AntArtifactPreProcessingPropertiesProvider.class); + } + public AntArtifactPreProcessingPropertiesProvider() { super("ant-preprocessing"); }