From 7d674700709dd5cb1e5a5bd93379f740a397e8c4 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 12 May 2011 18:39:59 +0200 Subject: [PATCH 01/21] prefix matching should depend on the actual prefix in the editor, not on the one that the completion was invoked with (IDEA-69525) --- .../completion/JavaAutoPopupTest.groovy | 8 +++ .../completion/PrefixMatchingWeigher.java | 7 ++- .../impl/CompletionServiceImpl.java | 37 +++++++++---- .../completion/impl/CompletionSorterImpl.java | 8 +-- .../lookup/CachingComparingClassifier.java | 52 +++++++++++++++++++ .../lookup/ComparingClassifier.java | 16 ++---- 6 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java 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 2dbaa5f3098e..619f98c24566 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -774,5 +774,13 @@ public class UTest { assert myFixture.lookupElementStrings == ['new', 'nextWord'] } + public void testUpdatePrefixMatchingOnTyping() { + myFixture.addClass("class CertificateEncodingException {}") + myFixture.addClass("class CertificateException {}") + myFixture.configureByText 'a.java', 'class Foo {}' + type 'CertificateExce' + assert myFixture.lookupElementStrings == ['CertificateException', 'CertificateEncodingException'] + } + } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java index 05e452a2fddd..a688fc1157df 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java @@ -25,7 +25,12 @@ import org.jetbrains.annotations.NotNull; */ public class PrefixMatchingWeigher extends CompletionWeigher { - public Comparable weigh(@NotNull final LookupElement item, @NotNull final CompletionLocation location) { + @Override + public Comparable weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) { + throw new UnsupportedOperationException("Not implemented"); + } + + public static int getPrefixMatchingDegree(LookupElement item, CompletionLocation location) { final String prefix = location.getCompletionParameters().getLookup().itemPattern(item); final int setting = CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index a87472cfc4c2..cc9761728e43 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -16,10 +16,7 @@ package com.intellij.codeInsight.completion.impl; import com.intellij.codeInsight.completion.*; -import com.intellij.codeInsight.lookup.Classifier; -import com.intellij.codeInsight.lookup.ClassifierFactory; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementWeigher; +import com.intellij.codeInsight.lookup.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; @@ -262,13 +259,31 @@ public class CompletionServiceImpl extends CompletionService{ } for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) { - sorter = sorter.weigh(new LookupElementWeigher(weigher.toString()) { - @NotNull - @Override - public Comparable weigh(@NotNull LookupElement element) { - return new NegatingComparable(weigher.weigh(element, location)); - } - }); + final String id = weigher.toString(); + if ("prefix".equals(id)) { + sorter = sorter.withClassifier(new ClassifierFactory(id) { + @Override + public Classifier createClassifier(Classifier next) { + return new ComparingClassifier(next, id) { + @NotNull + @Override + public Comparable getWeight(LookupElement element) { + return -PrefixMatchingWeigher.getPrefixMatchingDegree(element, location); + } + }; + } + }); + } + else { + sorter = sorter.weigh(new LookupElementWeigher(id) { + @NotNull + @Override + public Comparable weigh(@NotNull LookupElement element) { + return new NegatingComparable(weigher.weigh(element, location)); + } + }); + } + } return sorter.withClassifier("priority", true, new ClassifierFactory("liftShorter") { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionSorterImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionSorterImpl.java index a82f8b9b40ef..38985e0b0020 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionSorterImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionSorterImpl.java @@ -39,13 +39,7 @@ public class CompletionSorterImpl extends CompletionSorter { return new ClassifierFactory(id) { @Override public Classifier createClassifier(Classifier next) { - return new ComparingClassifier(next, id) { - @NotNull - @Override - public Comparable getWeight(LookupElement element) { - return weigher.weigh(element); - } - }; + return new CachingComparingClassifier(next, weigher); } }; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java new file mode 100644 index 000000000000..d87b317e3e5c --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/CachingComparingClassifier.java @@ -0,0 +1,52 @@ +/* + * 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.codeInsight.lookup; + +import com.intellij.util.containers.StripedLockConcurrentHashMap; +import gnu.trove.TObjectHashingStrategy; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +/** +* @author peter +*/ +public class CachingComparingClassifier extends ComparingClassifier { + private final Map myWeights = new StripedLockConcurrentHashMap(TObjectHashingStrategy.IDENTITY); + private final LookupElementWeigher myWeigher; + + public CachingComparingClassifier(Classifier next, LookupElementWeigher weigher) { + super(next, weigher.toString()); + myWeigher = weigher; + } + + @NotNull + @Override + public final Comparable getWeight(LookupElement t) { + final Comparable weight = myWeights.get(t); + if (weight == null) { + throw new AssertionError(myName + "; " + myWeights.containsKey(t) + "; element=" + t); + } + return weight; + } + + @Override + public void addElement(LookupElement t) { + myWeights.put(t, myWeigher.weigh(t)); + super.addElement(t); + } + +} 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 6f2a0989329a..c0e1630d7d12 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/ComparingClassifier.java @@ -18,19 +18,16 @@ package com.intellij.codeInsight.lookup; import com.intellij.openapi.application.ApplicationManager; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.StripedLockConcurrentHashMap; -import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; import java.util.*; /** -* @author peter -*/ + * @author peter + */ public abstract class ComparingClassifier extends Classifier { - private final Map myWeights = new StripedLockConcurrentHashMap(TObjectHashingStrategy.IDENTITY); private final Classifier myNext; - private final String myName; + protected final String myName; public ComparingClassifier(Classifier next, String name) { myNext = next; @@ -40,19 +37,14 @@ public abstract class ComparingClassifier extends Classifier { @NotNull public abstract Comparable getWeight(T t); - @Override public void addElement(T t) { - myWeights.put(t, getWeight(t)); myNext.addElement(t); } private TreeMap> groupByWeights(List source) { TreeMap> map = new TreeMap>(); for (T t : source) { - final Comparable weight = myWeights.get(t); - if (weight == null) { - throw new AssertionError(myName + "; " + myWeights.containsKey(t) + "; element=" + t); - } + final Comparable weight = getWeight(t); List list = map.get(weight); if (list == null) { map.put(weight, list = new SmartList()); From d4b9d2b8704cf1f294f30c623c24b6d71d56a66a Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 12 May 2011 18:47:16 +0200 Subject: [PATCH 02/21] remove assertion --- .../com/intellij/lang/ant/dom/AntDomFileReferenceSet.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReferenceSet.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReferenceSet.java index 210da1e0d000..0c5dd2f7cbb2 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReferenceSet.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomFileReferenceSet.java @@ -129,8 +129,9 @@ public class AntDomFileReferenceSet extends FileReferenceSet { else { basedir = containingProject.getContextAntProject().getProjectBasedirPath(); } - assert basedir != null; - root = LocalFileSystem.getInstance().findFileByPath(basedir); + if (basedir != null) { + root = LocalFileSystem.getInstance().findFileByPath(basedir); + } } } From ec9d787272150c84f81d63429dcf53a742be543b Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 12 May 2011 21:41:52 +0200 Subject: [PATCH 03/21] IDEA-69609 (Unnice handling of single quotes when transforming concatenation to String.format()) --- .../ReplaceConcatenationWithFormatStringIntention.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java index 6527d1725c64..865f3f5db8ba 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java @@ -150,7 +150,8 @@ public class ReplaceConcatenationWithFormatStringIntention type.equalsToText("char"))) { if (length > 2) { formatString.append( - text.substring(1, length - 1).replace("%", "%%")); + text.substring(1, length - 1).replace("%", "%%") + .replace("\\'", "'")); } } else { formatString.append(text); From 4ec18504b14b4ec6d5f3b00267ec8ac64461f157 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 13 May 2011 10:21:56 +0400 Subject: [PATCH 04/21] IDEA-69618 Dir diff window could be closed on pressing Escape --- .../src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java index ef7ce597f6f9..020b3c6e0a45 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java @@ -35,6 +35,7 @@ public class DirDiffFrame extends FrameWrapper { Disposer.register(this, myPanel); setComponent(myPanel.getPanel()); setProject(project); + closeOnEsc(); } From 54cf22bee043a9d32b6620db2fc76329fb8c85eb Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 13 May 2011 11:31:21 +0400 Subject: [PATCH 05/21] presentation for comparison modes --- .../intellij/ide/diff/DirDiffSettings.java | 6 ++- .../dir/actions/ChangeCompareModeAction.java | 3 +- .../dir/actions/ChangeCompareModeGroup.java | 37 +++++++++++++++---- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/diff/DirDiffSettings.java b/platform/platform-api/src/com/intellij/ide/diff/DirDiffSettings.java index 735946932023..6ace126a4ea2 100644 --- a/platform/platform-api/src/com/intellij/ide/diff/DirDiffSettings.java +++ b/platform/platform-api/src/com/intellij/ide/diff/DirDiffSettings.java @@ -55,6 +55,10 @@ public class DirDiffSettings { public static enum CompareMode { CONTENT, // the most honest, the slowest. Compares size, if equal compares contents. Ignores timestamps SIZE, // Compares size only - TIMESTAMP // Compares size, if equal compares timestamps + TIMESTAMP; // Compares size, if equal compares timestamps + + public String getPresentableName() { + return StringUtil.capitalize(name().toLowerCase()); + } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/actions/ChangeCompareModeAction.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/actions/ChangeCompareModeAction.java index b0bd920963f7..5d6c842bf121 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/actions/ChangeCompareModeAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/actions/ChangeCompareModeAction.java @@ -19,7 +19,6 @@ import com.intellij.ide.diff.DirDiffSettings; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.diff.impl.dir.DirDiffTableModel; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Icons; import com.intellij.util.ui.EmptyIcon; @@ -37,7 +36,7 @@ class ChangeCompareModeAction extends AnAction { private final DirDiffSettings.CompareMode myMode; ChangeCompareModeAction(DirDiffTableModel model, DirDiffSettings.CompareMode mode) { - super(StringUtil.capitalize(mode.name().toLowerCase())); + super(mode.getPresentableName()); myModel = model; myMode = mode; } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/actions/ChangeCompareModeGroup.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/actions/ChangeCompareModeGroup.java index d785078ef1de..00386818ebc5 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/actions/ChangeCompareModeGroup.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/actions/ChangeCompareModeGroup.java @@ -16,12 +16,16 @@ package com.intellij.openapi.diff.impl.dir.actions; import com.intellij.ide.diff.DirDiffSettings; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.diff.impl.dir.DirDiffTableModel; +import com.intellij.ui.IdeBorderFactory; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.awt.*; import java.util.ArrayList; /** @@ -29,20 +33,39 @@ import java.util.ArrayList; */ public class ChangeCompareModeGroup extends ComboBoxAction { private final DefaultActionGroup myGroup; + private DirDiffSettings mySettings; public ChangeCompareModeGroup(DirDiffTableModel model) { - getTemplatePresentation().setText("Compare by"); + mySettings = model.getSettings(); + getTemplatePresentation().setText(mySettings.compareMode.getPresentableName()); + final ArrayList actions = new ArrayList(); if (model.getSettings().showCompareModes) { - final ArrayList actions = new ArrayList(); for (DirDiffSettings.CompareMode mode : DirDiffSettings.CompareMode.values()) { actions.add(new ChangeCompareModeAction(model, mode)); } - myGroup = new DefaultActionGroup(actions.toArray(new ChangeCompareModeAction[actions.size()])); - } else { - getTemplatePresentation().setEnabled(false); - getTemplatePresentation().setVisible(false); - myGroup = new DefaultActionGroup(); } + else { + getTemplatePresentation().setVisible(false); + getTemplatePresentation().setEnabled(false); + } + myGroup = new DefaultActionGroup(actions.toArray(new ChangeCompareModeAction[actions.size()])); + } + + @Override + public void update(AnActionEvent e) { + super.update(e); + getTemplatePresentation().setText(mySettings.compareMode.getPresentableName()); + e.getPresentation().setText(mySettings.compareMode.getPresentableName()); + } + + @Override + public JComponent createCustomComponent(Presentation presentation) { + JPanel panel = new JPanel(new BorderLayout()); + final JLabel label = new JLabel("Compare by:"); + panel.add(label, BorderLayout.WEST); + panel.add(super.createCustomComponent(presentation).getComponent(0), BorderLayout.CENTER); + panel.setBorder(IdeBorderFactory.createEmptyBorder(2, 6, 2, 0)); + return panel; } @NotNull From c15863363b858f769e756765bf2e27bec2ad9a27 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 13 May 2011 11:32:47 +0400 Subject: [PATCH 06/21] search component customization --- .../src/com/intellij/ui/FilterComponent.java | 62 +++++++++++--- .../src/com/intellij/ui/SearchTextField.java | 80 ++++++++++++------- 2 files changed, 100 insertions(+), 42 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/FilterComponent.java b/platform/platform-api/src/com/intellij/ui/FilterComponent.java index 7ca76f6918c7..37b5249c1e75 100644 --- a/platform/platform-api/src/com/intellij/ui/FilterComponent.java +++ b/platform/platform-api/src/com/intellij/ui/FilterComponent.java @@ -28,16 +28,39 @@ import java.awt.event.KeyEvent; import java.util.List; /** - * User: anna - * Date: 16-Dec-2005 + * @author Anna Kozlova + * @author Konstantin Bulenkov */ public abstract class FilterComponent extends JPanel { private final SearchTextFieldWithStoredHistory myFilter; private final Alarm myUpdateAlarm = new Alarm(); + private boolean myOnTheFly; public FilterComponent(@NonNls String propertyName, int historySize) { + this(propertyName, historySize, true); + } + + public FilterComponent(@NonNls String propertyName, int historySize, boolean onTheFlyUpdate) { super(new BorderLayout()); - myFilter = new SearchTextFieldWithStoredHistory(propertyName); + myOnTheFly = onTheFlyUpdate; + myFilter = new SearchTextFieldWithStoredHistory(propertyName) { + @Override + protected Runnable createItemChosenCallback(JList list) { + final Runnable callback = super.createItemChosenCallback(list); + return new Runnable() { + @Override + public void run() { + callback.run(); + filter(); + } + }; + } + + @Override + protected Component getPopupLocationComponent() { + return FilterComponent.this.getPopupLocationComponent(); + } + }; myFilter.getTextEditor().addKeyListener(new KeyAdapter() { //to consume enter in combo box - do not process this event by default button from DialogWrapper public void keyPressed(final KeyEvent e) { @@ -45,6 +68,8 @@ public abstract class FilterComponent extends JPanel { e.consume(); myFilter.addCurrentTextToHistory(); filter(); + } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + onEscape(e); } } }); @@ -61,21 +86,31 @@ public abstract class FilterComponent extends JPanel { public void changedUpdate(DocumentEvent e) { onChange(); } - - public void onChange() { - myUpdateAlarm.cancelAllRequests(); - myUpdateAlarm.addRequest(new Runnable(){ - public void run() { - onlineFilter(); - } - }, 100, ModalityState.stateForComponent(myFilter)); - } }); myFilter.setHistorySize(historySize); add(myFilter, BorderLayout.CENTER); } + protected JComponent getPopupLocationComponent() { + return myFilter; + } + + public JTextField getTextEditor() { + return myFilter.getTextEditor(); + } + + private void onChange() { + if (myOnTheFly) { + myUpdateAlarm.cancelAllRequests(); + myUpdateAlarm.addRequest(new Runnable(){ + public void run() { + onlineFilter(); + } + }, 100, ModalityState.stateForComponent(myFilter)); + } + } + public void setHistorySize(int historySize){ myFilter.setHistorySize(historySize); } @@ -84,6 +119,9 @@ public abstract class FilterComponent extends JPanel { myFilter.reset(); } + protected void onEscape(KeyEvent e) { + } + public String getFilter(){ return myFilter.getText(); } diff --git a/platform/platform-api/src/com/intellij/ui/SearchTextField.java b/platform/platform-api/src/com/intellij/ui/SearchTextField.java index f2f477eafb39..facaea970998 100644 --- a/platform/platform-api/src/com/intellij/ui/SearchTextField.java +++ b/platform/platform-api/src/com/intellij/ui/SearchTextField.java @@ -88,6 +88,16 @@ public class SearchTextField extends JPanel { } }); add(myTextField, BorderLayout.CENTER); + myTextField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_DOWN) { + if (myPopup == null || !myPopup.isVisible()) { + showPopup(); + } + } + } + }); if (hasNativeLeopardSearchControl()) { myTextField.putClientProperty("JTextField.variant", "search"); @@ -318,13 +328,8 @@ public class SearchTextField extends JPanel { } } - protected void showPopup() { - if (myPopup == null) { - final JList list = new JBList(myModel); - if (myListener != null) { - removeKeyListener(myListener); - } - final Runnable chooseRunnable = new Runnable() { + protected Runnable createItemChosenCallback(final JList list) { + return new Runnable() { public void run() { final String value = (String)list.getSelectedValue(); getTextEditor().setText(value != null ? value : ""); @@ -334,35 +339,50 @@ public class SearchTextField extends JPanel { } } }; - myListener = new KeyAdapter() { - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_DOWN) { - if (list.getSelectedIndex() < list.getModel().getSize() - 1) { - list.setSelectedIndex(list.getSelectedIndex() + 1); - } - } - else if (e.getKeyCode() == KeyEvent.VK_UP) { - if (list.getSelectedIndex() > 0) { - list.setSelectedIndex(list.getSelectedIndex() - 1); - } - } - else if (e.getKeyCode() == KeyEvent.VK_ENTER) { - if (list.getSelectedIndex() > -1) { - chooseRunnable.run(); - } - } - } - }; - addKeyboardListener(myListener); + } + + protected void showPopup() { + //removeKeyListener(myListener); + if (myPopup == null) { + final JList list = new JBList(myModel); + //if (myListener != null) { + // removeKeyListener(myListener); + //} + final Runnable chooseRunnable = createItemChosenCallback(list); + //myListener = new KeyAdapter() { + // public void keyPressed(KeyEvent e) { + // if (e.getKeyCode() == KeyEvent.VK_DOWN) { + // if (list.getSelectedIndex() < list.getModel().getSize() - 1) { + // list.setSelectedIndex(list.getSelectedIndex() + 1); + // } + // } + // else if (e.getKeyCode() == KeyEvent.VK_UP) { + // if (list.getSelectedIndex() > 0) { + // list.setSelectedIndex(list.getSelectedIndex() - 1); + // } + // } + // else if (e.getKeyCode() == KeyEvent.VK_ENTER) { + // if (list.getSelectedIndex() > -1) { + // chooseRunnable.run(); + // } + // } + // } + //}; + //addKeyboardListener(myListener); myPopup = JBPopupFactory.getInstance().createListPopupBuilder(list) .setMovable(false) - .setRequestFocus(false) + .setRequestFocus(true) .setItemChoosenCallback(chooseRunnable).createPopup(); - - if (isShowing()) myPopup.showUnderneathOf(this); + if (isShowing()) { + myPopup.showUnderneathOf(getPopupLocationComponent()); + } } } + protected Component getPopupLocationComponent() { + return this; + } + private void togglePopup() { if (myPopup == null) { showPopup(); From 62e3f58b8f9c4a8b6376bf809a62d362ec8fc0e2 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 13 May 2011 11:33:21 +0400 Subject: [PATCH 07/21] fix IDEA-69332 (better search control) --- .../openapi/diff/impl/dir/DirDiffPanel.form | 16 ++---- .../openapi/diff/impl/dir/DirDiffPanel.java | 53 ++++++++++++------- .../diff/impl/dir/DirDiffTableModel.java | 2 +- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.form b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.form index 2acf1935aa0f..594947afb736 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.form +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.form @@ -113,31 +113,21 @@ - + - + - + - - - - - - - - - - diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java index 75ff1b0075f2..a892af632073 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffPanel.java @@ -28,15 +28,18 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.ui.FilterComponent; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBLoadingPanel; 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.TableColumn; import javax.swing.table.TableColumnModel; +import javax.swing.text.JTextComponent; import java.awt.*; import java.awt.event.*; import java.util.concurrent.Callable; @@ -58,7 +61,9 @@ public class DirDiffPanel implements Disposable { private JBLabel mySourceDirLabel; private JPanel myToolBarPanel; private JPanel myRootPanel; - private JTextField myFilter; + private JPanel myFilterPanel; + private JBLabel myFilterLabel; + private FilterComponent myFilter; private final DirDiffTableModel myModel; public JLabel myErrorLabel; private final DirDiffWindow myDiffWindow; @@ -199,6 +204,24 @@ public class DirDiffPanel implements Disposable { }); myRootPanel.removeAll(); myRootPanel.add(loadingPanel, BorderLayout.CENTER); + myFilter = new FilterComponent("dir.diff.filter", 15, false) { + @Override + public void filter() { + fireFilterUpdated(); + } + + @Override + protected void onEscape(KeyEvent e) { + e.consume(); + focusTable(); + } + + @Override + protected JComponent getPopupLocationComponent() { + return UIUtil.findComponentOfType(super.getPopupLocationComponent(), JTextComponent.class); + } + }; + myModel.addModelListener(new DirDiffModelListener() { @Override public void updateStarted() { @@ -210,22 +233,12 @@ public class DirDiffPanel implements Disposable { myFilter.setEnabled(true); } }); - - myFilter.setText(settings.getFilter()); - oldFilter = myFilter.getText(); - myFilter.addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - e.consume(); - fireFilterUpdated(); - } - else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - e.consume(); - focusTable(); - } - } - }); + myFilter.getTextEditor().setColumns(10); + myFilter.setFilter(settings.getFilter()); + //oldFilter = myFilter.getText(); + oldFilter = myFilter.getFilter(); + myFilterPanel.add(myFilter, BorderLayout.CENTER); + myFilterLabel.setLabelFor(myFilter); final Callable srcChooser = myModel.getSourceDir().getElementChooser(project); final Callable trgChooser = myModel.getTargetDir().getElementChooser(project); if (srcChooser != null) { @@ -286,12 +299,12 @@ public class DirDiffPanel implements Disposable { }); } - public JTextField getFilter() { - return myFilter; + public String getFilter() { + return myFilter.getFilter(); } private void fireFilterUpdated() { - final String newFilter = myFilter.getText(); + final String newFilter = myFilter.getFilter(); if (!StringUtil.equals(oldFilter, newFilter)) { oldFilter = newFilter; myModel.getSettings().setFilter(newFilter); diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java index 2f47c1d055d9..a74cd9649ef1 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffTableModel.java @@ -128,7 +128,7 @@ public class DirDiffTableModel extends AbstractTableModel implements Disposable } public void updateFromUI() { - getSettings().setFilter(myPanel.getFilter().getText()); + getSettings().setFilter(myPanel.getFilter()); } private static String prepareText(String text) { From 6782d9cbf7b3846ba3bbcaa3da17d1215fa93121 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 13 May 2011 11:49:18 +0400 Subject: [PATCH 08/21] help id --- .../openapi/diff/impl/dir/DirDiffDialog.java | 5 +++++ .../openapi/diff/impl/dir/DirDiffFrame.java | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java index c0abf9a99f74..b29f9742b0d5 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffDialog.java @@ -70,4 +70,9 @@ public class DirDiffDialog extends DialogWrapper { protected Action[] createActions() { return new Action[]{}; } + + @Override + protected String getHelpId() { + return "reference.dialogs.diff.folder"; + } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java index 020b3c6e0a45..3718056b827f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/dir/DirDiffFrame.java @@ -15,10 +15,14 @@ */ package com.intellij.openapi.diff.impl.dir; +import com.intellij.ide.DataManager; import com.intellij.ide.diff.DirDiffSettings; +import com.intellij.openapi.actionSystem.DataProvider; +import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.FrameWrapper; import com.intellij.openapi.util.Disposer; +import org.jetbrains.annotations.NonNls; import java.awt.*; @@ -36,6 +40,15 @@ public class DirDiffFrame extends FrameWrapper { setComponent(myPanel.getPanel()); setProject(project); closeOnEsc(); + DataManager.registerDataProvider(myPanel.getPanel(), new DataProvider() { + @Override + public Object getData(@NonNls String dataId) { + if (PlatformDataKeys.HELP_ID.is(dataId)) { + return "reference.dialogs.diff.folder"; + } + return null; + } + }); } From a802b858a586d517318a7d8787f153207333de71 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 13 May 2011 12:49:45 +0400 Subject: [PATCH 09/21] fix TC plugin update --- .../src/com/intellij/openapi/util/io/FileUtil.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 3690ce20398f..e302ea7edab9 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -357,13 +357,13 @@ public class FileUtil { return createTempFile(dir, prefix, suffix, create, true); } - public static File createTempFile(@NonNls final File dir, @NotNull @NonNls String prefix, @NonNls String suffix, final boolean create, boolean removeOnExit) throws IOException { + public static File createTempFile(@NonNls final File dir, @NotNull @NonNls String prefix, @NonNls String suffix, final boolean create, boolean deleteOnExit) throws IOException { File file = doCreateTempFile(prefix, suffix, dir); file.delete(); if (create) { file.createNewFile(); } - if (removeOnExit) { + if (deleteOnExit) { file.deleteOnExit(); } return file; @@ -371,10 +371,17 @@ public class FileUtil { @NotNull public static File createTempFile(@NotNull @NonNls String prefix, @NonNls String suffix) throws IOException{ + return createTempFile(prefix, suffix, false); //false until TeamCity fixes its plugin + } + + @NotNull + public static File createTempFile(@NotNull @NonNls String prefix, @NonNls String suffix, boolean deleteOnExit) throws IOException { File file = doCreateTempFile(prefix, suffix); file.delete(); file.createNewFile(); - file.deleteOnExit(); + if (deleteOnExit) { + file.deleteOnExit(); + } return file; } From 7b7bcda775b4060900962f2bb6ae1f8c49b4561c Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Fri, 13 May 2011 13:33:59 +0400 Subject: [PATCH 10/21] NavBar is always shown on the top --- .../NavBarRootPaneExtension.java | 93 +++++++++++-------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java index 4b3b06b72ee2..38dbc8daf723 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java @@ -20,6 +20,7 @@ */ package com.intellij.ide.navigationToolbar; +import com.intellij.ide.ui.LafManager; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.actionSystem.*; @@ -27,6 +28,7 @@ import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.IdeRootPaneNorthExtension; import com.intellij.openapi.wm.impl.IdeFrameImpl; @@ -186,48 +188,56 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension { } private JComponent buildNavBarPanel() { - final JComponent result = new JPanel(new BorderLayout()) { + final Ref panel = new Ref(null); + final Runnable updater = new Runnable() { + String laf; + @Override + public void run() { + if (LafManager.getInstance().getCurrentLookAndFeel().getName().equals(laf)) return; + laf = LafManager.getInstance().getCurrentLookAndFeel().getName(); + panel.get().removeAll(); + myScrollPane = null; + myCloseIcon = null; + if (myNavigationBar != null && !Disposer.isDisposed(myNavigationBar)) { + Disposer.dispose(myNavigationBar); + } + myNavigationBar = new NavBarPanel(myProject); + myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar); + myNavigationBar.getModel().setFixedComponent(true); + + myScrollPane = ScrollPaneFactory.createScrollPane(myNavigationBar); + myScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); + myScrollPane.setHorizontalScrollBar(null); + myScrollPane.setBorder(null); + + myScrollPane.setOpaque(false); + myScrollPane.getViewport().setOpaque(false); + + panel.get().setBackground(UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground()); + panel.get().setOpaque(!UIUtil.isUnderAquaLookAndFeel() || UISettings.getInstance().SHOW_MAIN_TOOLBAR); + panel.get().setBorder(UIUtil.isUnderAquaLookAndFeel() ? BorderFactory.createEmptyBorder(2, 0, 2, 4) : new NavBarBorder(true, 0)); + myNavigationBar.setBorder(null); + panel.get().add(myScrollPane, BorderLayout.CENTER); + if (!SystemInfo.isMac) { + myCloseIcon = new JLabel(CROSS_ICON); + myCloseIcon.addMouseListener(new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + UISettings.getInstance().SHOW_NAVIGATION_BAR = false; + uiSettingsChanged(UISettings.getInstance()); + } + }); + panel.get().add(myCloseIcon, BorderLayout.EAST); + } + } + }; + + panel.set(new JPanel(new BorderLayout()) { @Override public void updateUI() { super.updateUI(); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - removeAll(); - myScrollPane = null; - myCloseIcon = null; - if (myNavigationBar != null && !Disposer.isDisposed(myNavigationBar)) { - Disposer.dispose(myNavigationBar); - } - myNavigationBar = new NavBarPanel(myProject); - myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar); - myNavigationBar.getModel().setFixedComponent(true); - - myScrollPane = ScrollPaneFactory.createScrollPane(myNavigationBar); - myScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); - myScrollPane.setHorizontalScrollBar(null); - myScrollPane.setBorder(null); - - myScrollPane.setOpaque(false); - myScrollPane.getViewport().setOpaque(false); - - setBackground(UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground()); - setOpaque(!UIUtil.isUnderAquaLookAndFeel() || UISettings.getInstance().SHOW_MAIN_TOOLBAR); - setBorder(UIUtil.isUnderAquaLookAndFeel() ? BorderFactory.createEmptyBorder(2, 0, 2, 4) : new NavBarBorder(true, 0)); - myNavigationBar.setBorder(null); - add(myScrollPane, BorderLayout.CENTER); - if (!SystemInfo.isMac) { - myCloseIcon = new JLabel(CROSS_ICON); - myCloseIcon.addMouseListener(new MouseAdapter() { - public void mouseClicked(final MouseEvent e) { - UISettings.getInstance().SHOW_NAVIGATION_BAR = false; - uiSettingsChanged(UISettings.getInstance()); - } - }); - add(myCloseIcon, BorderLayout.EAST); - } - } - }); + if (UISettings.getInstance().SHOW_NAVIGATION_BAR) { + SwingUtilities.invokeLater(updater); + } } @Override @@ -292,9 +302,10 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension { closePreferredSize.width, closePreferredSize.height); } } - }; + }); - return result; + updater.run(); + return panel.get(); } public void uiSettingsChanged(final UISettings settings) { From 09753f71d0986823910675310d2883de5f823982 Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Fri, 13 May 2011 14:02:53 +0400 Subject: [PATCH 11/21] find: select text in field when it gets focus. Remove any selection in editor after replace-all. --- .../lang-impl/src/com/intellij/find/EditorSearchComponent.java | 2 ++ platform/lang-impl/src/com/intellij/find/FindUtil.java | 1 + 2 files changed, 3 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java index d5a9598d4efc..c109c6a4cde7 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchComponent.java @@ -625,6 +625,8 @@ public class EditorSearchComponent extends JPanel implements DataProvider, Selec } public void requestFocus() { + mySearchField.setSelectionStart(0); + mySearchField.setSelectionEnd(mySearchField.getText().length()); requestFocus(mySearchField); } diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index 8f962fdde31b..e571082fa986 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -583,6 +583,7 @@ public class FindUtil { public void run() { document.setText(newText); editor.getCaretModel().moveToOffset(finalCaretOffset); + editor.getSelectionModel().removeSelection(); } }); } From 86f90a87e28e1e318266d6f8f187cc2af637dbc6 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 13 May 2011 12:06:44 +0400 Subject: [PATCH 12/21] http://ea.jetbrains.com/browser/ea_problems/26472 --- .../codeInsight/navigation/NavigationGutterIconBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/dom-openapi/src/com/intellij/codeInsight/navigation/NavigationGutterIconBuilder.java b/xml/dom-openapi/src/com/intellij/codeInsight/navigation/NavigationGutterIconBuilder.java index 633dfa0b619e..60efe1dec69c 100644 --- a/xml/dom-openapi/src/com/intellij/codeInsight/navigation/NavigationGutterIconBuilder.java +++ b/xml/dom-openapi/src/com/intellij/codeInsight/navigation/NavigationGutterIconBuilder.java @@ -237,7 +237,7 @@ public class NavigationGutterIconBuilder { final List list = new ArrayList(targets.size()); for (final T target : targets) { for (final PsiElement psiElement : myConverter.fun(target)) { - if (elements.add(psiElement)) { + if (elements.add(psiElement) && psiElement.isValid()) { list.add(manager.createSmartPsiElementPointer(psiElement)); } } From fbc0b7c37306d75a11decc5cb8f0a8720d58d557 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 13 May 2011 12:07:10 +0400 Subject: [PATCH 13/21] http://ea.jetbrains.com/browser/ea_problems/22963 --- .../daemon/impl/GeneralHighlightingPass.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java index 89f0839ea62e..50b973f19aeb 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/GeneralHighlightingPass.java @@ -227,22 +227,18 @@ public class GeneralHighlightingPass extends ProgressableTextEditorHighlightingP myHighlights.addAll(toApplyInside); gotHighlights.clear(); gotHighlights.addAll(outsideResult); - + final long modificationStamp = myDocument.getModificationStamp(); UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - if (myProject.isDisposed()) return; + if (myProject.isDisposed() || modificationStamp != myDocument.getModificationStamp()) return; MarkupModel markupModel = myDocument.getMarkupModel(myProject); UpdateHighlightersUtil.setHighlightersInRange(myProject, myDocument, priorityIntersection, getColorsScheme(), toApplyInside, (MarkupModelEx)markupModel, Pass.UPDATE_ALL); - } - }); - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - if (myProject.isDisposed() || myEditor == null) return; - new ShowAutoImportPass(myProject, myFile, myEditor).applyInformationToEditor(); + if (myEditor != null) { + new ShowAutoImportPass(myProject, myFile, myEditor).applyInformationToEditor(); + } } }); } From 18d8cd3b5d2ee000d6cfbe12fa38657e68eff05c Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 May 2011 13:05:49 +0400 Subject: [PATCH 14/21] skip test roots if generate javadoc was disabled for them (IDEA-65736) --- .../javadoc/JavadocConfiguration.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java b/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java index 8b6b91e6673d..f8125312fef4 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java +++ b/java/java-impl/src/com/intellij/javadoc/JavadocConfiguration.java @@ -39,10 +39,7 @@ import com.intellij.openapi.projectRoots.JavaSdkType; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.ex.PathUtilEx; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.OrderEnumerator; -import com.intellij.openapi.roots.SourceFolder; +import com.intellij.openapi.roots.*; import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; @@ -62,6 +59,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; +import java.util.List; /** * @author Eugene Zhuravlev @@ -280,13 +278,21 @@ public class JavadocConfiguration implements ModuleRunProfile, JDOMExternalizabl } writer.println("-sourcepath"); final PathsList pathsList = OrderEnumerator.orderEntries(myProject).withoutSdk().withoutLibraries().getSourcePathsList(); - final String sourcePath = StringUtil.join(pathsList.getPathList(), new Function() { - @Override - public String fun(String path) { - return FileUtil.toSystemIndependentName(path); + final List files = pathsList.getRootDirs(); + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); + final StringBuilder sourcePath = new StringBuilder(); + boolean start = true; + for (VirtualFile file : files) { + if (!myGenerationOptions.isIncludeTestSource() && fileIndex.isInTestSourceContent(file)) continue; + if (start) { + start = false; } - }, File.pathSeparator); - writer.println(GeneralCommandLine.quote(sourcePath)); + else { + sourcePath.append(File.pathSeparator); + } + sourcePath.append(file.getPath()); + } + writer.println(GeneralCommandLine.quote(sourcePath.toString())); } finally { writer.close(); From 861d938bb30506f3ef1ec1a663edc5df027059cf Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 May 2011 14:42:22 +0400 Subject: [PATCH 15/21] implementations presentation --- .../codeInsight/hint/ImplementationViewComponent.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java index da823c2d2b8d..2d95399c78a0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java @@ -41,6 +41,7 @@ import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.ui.IdeBorderFactory; @@ -117,7 +118,8 @@ public class ImplementationViewComponent extends JPanel { for (PsiElement element : elements) { PsiFile file = getContainingFile(element); if (file == null) continue; - files.add(new FileDescriptor(file, element.getParent())); + final PsiElement parent = element.getParent(); + files.add(new FileDescriptor(file, parent == file ? element : parent)); candidates.add(element.getNavigationElement()); } myElements = PsiUtilBase.toPsiElementArray(candidates); From 14c4a5f62b5f94380cf373c525b87f133da94fa8 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 May 2011 15:24:38 +0400 Subject: [PATCH 16/21] do not restart javadoc parser with the same input stream (IDEA-69558) --- .../codeInsight/documentation/AbstractExternalFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/AbstractExternalFilter.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/AbstractExternalFilter.java index 2aac13d32b30..f39ec3fa35d8 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/AbstractExternalFilter.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/AbstractExternalFilter.java @@ -228,9 +228,9 @@ public abstract class AbstractExternalFilter { String charset = null; do { read = buf.readLine(); - if (read != null && read.contains("charset")) { + /*if (read != null && read.contains("charset")) { charset = read; - } + }*/ } while (read != null && read.toUpperCase().indexOf(startSection) == -1); From 5ed5dc417907b7d28a5ecbb1ed964c38dcf0d1ac Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 13 May 2011 13:28:26 +0200 Subject: [PATCH 17/21] speedup ant execution from IDEA: use only stderr stream to log ant messages --- .../rt/ant/execution/IdeaAntLogger2.java | 10 ++--- .../rt/ant/execution/IdeaInputHandler.java | 40 ++++++++++++------- .../ant/config/execution/OutputParser2.java | 10 +++-- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java index 843bb9c1b48f..f30025eeb12b 100644 --- a/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java +++ b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java @@ -26,7 +26,6 @@ import java.io.PrintWriter; import java.io.StringWriter; public final class IdeaAntLogger2 extends DefaultLogger { - static SegmentedOutputStream ourOut; static SegmentedOutputStream ourErr; public static final char MESSAGE_CONTENT = 'M'; public static final char EXCEPTION_CONTENT = 'X'; @@ -116,19 +115,16 @@ public final class IdeaAntLogger2 extends DefaultLogger { } public static void guardStreams() { - if (ourErr != null && ourOut != null) return; - PrintStream out = System.out; + if (ourErr != null) { + return; + } PrintStream err = System.err; - ourOut = new SegmentedOutputStream(out); ourErr = new SegmentedOutputStream(err); - System.setOut(new PrintStream(ourOut)); System.setErr(new PrintStream(ourErr)); - ourOut.sendStart(); ourErr.sendStart(); } private void send(PacketWriter packet) { - packet.sendThrough(ourOut); packet.sendThrough(ourErr); } diff --git a/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaInputHandler.java b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaInputHandler.java index 67c3f148ffd8..3a1120acd320 100644 --- a/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaInputHandler.java +++ b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaInputHandler.java @@ -30,32 +30,42 @@ import java.util.Vector; */ public class IdeaInputHandler implements InputHandler { public void handleInput(InputRequest request) throws BuildException { - String prompt = request.getPrompt(); - if (prompt == null) throw new BuildException("Prompt is null"); - SegmentedOutputStream out = IdeaAntLogger2.ourOut; - SegmentedOutputStream err = IdeaAntLogger2.ourErr; - if (out == null || err == null) + final String prompt = request.getPrompt(); + if (prompt == null) { + throw new BuildException("Prompt is null"); + } + final SegmentedOutputStream err = IdeaAntLogger2.ourErr; + if (err == null) { throw new BuildException("Selected InputHandler should be used by Intellij IDEA"); - PacketWriter packet = PacketFactory.ourInstance.createPacket(IdeaAntLogger2.INPUT_REQUEST); + } + final PacketWriter packet = PacketFactory.ourInstance.createPacket(IdeaAntLogger2.INPUT_REQUEST); packet.appendLimitedString(prompt); if (request instanceof MultipleChoiceInputRequest) { Vector choices = ((MultipleChoiceInputRequest)request).getChoices(); if (choices != null && choices.size() > 0) { int count = choices.size(); packet.appendLong(count); - for (int i = 0; i < count; i++) + for (int i = 0; i < count; i++) { packet.appendLimitedString((String)choices.elementAt(i)); - } else packet.appendLong(0); - } else packet.appendLong(0); - packet.sendThrough(out); + } + } + else { + packet.appendLong(0); + } + } + else { + packet.appendLong(0); + } packet.sendThrough(err); try { - byte[] replayLength = readBytes(4); - int length = ((int)replayLength[0] << 24) | ((int)replayLength[1] << 16) | ((int)replayLength[2] << 8) | replayLength[3]; - byte[] replay = readBytes(length); - String input = new String(replay); + final byte[] replayLength = readBytes(4); + final int length = ((int)replayLength[0] << 24) | ((int)replayLength[1] << 16) | ((int)replayLength[2] << 8) | replayLength[3]; + final byte[] replay = readBytes(length); + final String input = new String(replay); request.setInput(input); - if (!request.isInputValid()) throw new BuildException("Invalid input: " + input); + if (!request.isInputValid()) { + throw new BuildException("Invalid input: " + input); + } } catch (IOException e) { throw new BuildException(e); diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/OutputParser2.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/OutputParser2.java index 6b2b629dde2b..700d97b362c0 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/execution/OutputParser2.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/OutputParser2.java @@ -16,7 +16,10 @@ package com.intellij.lang.ant.config.execution; import com.intellij.execution.junit.JUnitProcessHandler; -import com.intellij.execution.junit2.segments.*; +import com.intellij.execution.junit2.segments.DeferredActionsQueue; +import com.intellij.execution.junit2.segments.DeferredActionsQueueImpl; +import com.intellij.execution.junit2.segments.InputConsumer; +import com.intellij.execution.junit2.segments.SegmentReader; import com.intellij.execution.process.OSProcessHandler; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.lang.ant.config.AntBuildFile; @@ -85,9 +88,8 @@ final class OutputParser2 extends OutputParser implements PacketProcessor, Input final AntBuildMessageView errorView, final ProgressIndicator progress, final AntBuildFile buildFile) { - OutputParser2 parser = new OutputParser2(myProject, handler, errorView, progress, buildFile.getName()); - DeferredActionsQueue queue = new DeferredActionsQueueImpl(); - handler.getOut().setPacketDispatcher(parser, queue); + final OutputParser2 parser = new OutputParser2(myProject, handler, errorView, progress, buildFile.getName()); + final DeferredActionsQueue queue = new DeferredActionsQueueImpl(); handler.getErr().setPacketDispatcher(parser, queue); return parser; } From 64704cb4309052c0bf8a63631c4b17a5c54bba61 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 13 May 2011 15:09:34 +0400 Subject: [PATCH 18/21] less often isCancelled check (one time in 10ms in ProgressManager) --- .../daemon/impl/LocalInspectionsPass.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index 1b628d2db4fb..e251fa62fd99 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -73,7 +73,6 @@ import java.util.concurrent.ConcurrentMap; */ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass implements DumbAware { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.LocalInspectionsPass"); - private static final int NUM_ELEMENTS_PER_CHECK_CANCELLED = 5; public static final TextRange EMPTY_PRIORITY_RANGE = TextRange.EMPTY_RANGE; private final int myStartOffset; private final int myEndOffset; @@ -255,7 +254,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass } } }; - PsiElementVisitor visitor = createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements, indicator); + PsiElementVisitor visitor = createVisitorAndAcceptElements(tool, holder, isOnTheFly, session, elements); synchronized (init) { init.add(Trinity.create(tool, holder, visitor)); @@ -277,8 +276,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass @NotNull ProblemsHolder holder, boolean isOnTheFly, @NotNull LocalInspectionToolSession session, - @NotNull List elements, - @NotNull ProgressIndicator indicator) { + @NotNull List elements) { PsiElementVisitor visitor = tool.buildVisitor(holder, isOnTheFly, session); //noinspection ConstantConditions if(visitor == null) { @@ -288,7 +286,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass : "The visitor returned from LocalInspectionTool.buildVisitor() must not be recursive. "+tool; tool.inspectionStarted(session, isOnTheFly); - acceptElements(elements, visitor, indicator); + acceptElements(elements, visitor); return visitor; } @@ -310,7 +308,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass ProblemsHolder holder = trinity.second; PsiElementVisitor elementVisitor = trinity.third; - acceptElements(elements, elementVisitor, indicator); + acceptElements(elements, elementVisitor); advanceProgress(1); @@ -329,11 +327,12 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass inspectInjectedPsi(elements, tools, isOnTheFly, indicator, iManager, false); } - private static void acceptElements(@NotNull List elements, @NotNull PsiElementVisitor elementVisitor, @NotNull ProgressIndicator indicator) { + private static void acceptElements(@NotNull List elements, + @NotNull PsiElementVisitor elementVisitor) { for (int i = 0, elementsSize = elements.size(); i < elementsSize; i++) { PsiElement element = elements.get(i); element.accept(elementVisitor); - if (i % NUM_ELEMENTS_PER_CHECK_CANCELLED == 0) indicator.checkCanceled(); + ProgressManager.checkCanceled(); } } @@ -669,7 +668,7 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass }; LocalInspectionToolSession injSession = new LocalInspectionToolSession(injectedPsi, 0, injectedPsi.getTextLength()); - createVisitorAndAcceptElements(tool, holder, isOnTheFly, injSession, elements, indicator); + createVisitorAndAcceptElements(tool, holder, isOnTheFly, injSession, elements); tool.inspectionFinished(injSession,holder); List problems = holder.getResults(); if (problems != null && !problems.isEmpty()) { From fed09bd4f2d739d511c2f65f99fb41371ea17f16 Mon Sep 17 00:00:00 2001 From: anna Date: Fri, 13 May 2011 16:04:33 +0400 Subject: [PATCH 19/21] restart javadoc parser over new input stream; correct encoding detection (IDEA-69558; IDEA-67183) --- .../documentation/AbstractExternalFilter.java | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/AbstractExternalFilter.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/AbstractExternalFilter.java index f39ec3fa35d8..6c9db5b43234 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/AbstractExternalFilter.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/AbstractExternalFilter.java @@ -69,6 +69,7 @@ public abstract class AbstractExternalFilter { @NonNls private static final String DT = "
"; private static final Pattern CHARSET_META_PATTERN = Pattern.compile("", Pattern.CASE_INSENSITIVE); + private final HttpConfigurable myHttpConfigurable = HttpConfigurable.getInstance(); protected static abstract class RefConvertor { private final Pattern mySelector; @@ -209,6 +210,10 @@ public abstract class AbstractExternalFilter { } protected void doBuildFromStream(String surl, Reader input, StringBuffer data) throws IOException { + doBuildFromStream(surl, input, data, true); + } + + protected void doBuildFromStream(String surl, Reader input, StringBuffer data, boolean search4Encoding) throws IOException { BufferedReader buf = new BufferedReader(input); Matcher anchorMatcher = ourAnchorsuffix.matcher(surl); @NonNls String startSection = ""; @@ -225,20 +230,30 @@ public abstract class AbstractExternalFilter { data.append(HTML); String read; - String charset = null; + String contentEncoding = null; do { read = buf.readLine(); - /*if (read != null && read.contains("charset")) { - charset = read; - }*/ + if (read != null && search4Encoding && read.contains("charset")) { + String foundEncoding = parseContentEncoding(read); + if (foundEncoding != null) { + contentEncoding = foundEncoding; + } + } } while (read != null && read.toUpperCase().indexOf(startSection) == -1); - if (input instanceof MyReader && charset != null) { - String contentEncoding = parseContentEncoding(charset); - if (contentEncoding != null) { //restart page parsing with correct encoding - input = new MyReader(((MyReader)input).getInputStream(), contentEncoding); - buf = new BufferedReader(input); + if (input instanceof MyReader && contentEncoding != null) { + if (contentEncoding != null && !contentEncoding.equals("UTF-8") && !contentEncoding.equals(((MyReader)input).getEncoding())) { //restart page parsing with correct encoding + Reader stream; + try { + stream = getReaderByUrl(surl, myHttpConfigurable, new ProgressIndicatorBase()); + } + catch (ProcessCanceledException e) { + return; + } + data.delete(0, data.length()); + doBuildFromStream(surl, new MyReader(((MyReader)stream).getInputStream(), contentEncoding), data, false); + return; } } From 763c3f25046ce884941d186740c3a95bdb6c3a39 Mon Sep 17 00:00:00 2001 From: Kirill Kalishev Date: Fri, 13 May 2011 18:20:20 +0400 Subject: [PATCH 20/21] [xena] IDEA-67350 Cant read notifications (white text on yellow background) [rev=anna.kozlova] --- .../com/intellij/ide/IdeTooltipManager.java | 2 +- .../ide/ui/AppearanceConfigurable.java | 28 ------------------- .../com/intellij/ide/ui/AppearancePanel.form | 16 +---------- 3 files changed, 2 insertions(+), 44 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java index fd407c1f8cc8..a6ed2e366e44 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java @@ -431,7 +431,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener } private boolean useGraphite(boolean awtHint) { - return !isUseSystemLook() && awtHint; + return false; } public void hide(IdeTooltip tooltip) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java index 196f69314acb..d47529d0defe 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java @@ -21,7 +21,6 @@ import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -57,10 +56,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab myComponent.myLafComboBox.setModel(new DefaultComboBoxModel(LafManager.getInstance().getInstalledLookAndFeels())); myComponent.myLafComboBox.setRenderer(new MyLafComboBoxRenderer(myComponent.myLafComboBox.getRenderer())); - myComponent.myTooltipMode.setModel(new DefaultComboBoxModel(new Object[]{"default", "graphite", "system"})); - myComponent.myTooltipMode.setRenderer(new MyTooltipModeRenderer(myComponent.myTooltipMode.getRenderer())); - myComponent.myTooltipMode.setSelectedItem(Registry.stringValue("ide.tooltip.mode")); - myComponent.myEnableAlphaModeCheckBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { boolean state = myComponent.myEnableAlphaModeCheckBox.isSelected(); @@ -153,10 +148,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab } } - if (myComponent.myTooltipMode.getSelectedItem() != null && !myComponent.myTooltipMode.getSelectedItem().equals(Registry.stringValue("ide.tooltip.mode"))) { - update = true; - Registry.get("ide.tooltip.mode").setValue(myComponent.myTooltipMode.getSelectedItem().toString()); - } if (shouldUpdateUI) { lafManager.updateUI(); @@ -202,7 +193,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab myComponent.myLafComboBox.setSelectedItem(LafManager.getInstance().getCurrentLookAndFeel()); myComponent.myOverrideLAFFonts.setSelected(settings.OVERRIDE_NONIDEA_LAF_FONTS); myComponent.myDisableMnemonics.setSelected(settings.DISABLE_MNEMONICS); - myComponent.myTooltipMode.setSelectedItem(Registry.stringValue("ide.tooltip.mode")); boolean alphaModeEnabled = WindowManagerEx.getInstanceEx().isAlphaModeSupported(); if (alphaModeEnabled) { @@ -257,8 +247,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab isModified |= ratio != settings.ALPHA_MODE_RATIO; } - isModified |= myComponent.myTooltipMode.getSelectedItem() != null && !myComponent.myTooltipMode.getSelectedItem().equals(Registry.stringValue("ide.tooltip.mode")); - return isModified; } @@ -285,21 +273,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab } } - private static final class MyTooltipModeRenderer extends ListCellRendererWrapper { - public MyTooltipModeRenderer(final ListCellRenderer listCellRenderer) { - super(listCellRenderer); - } - - @Override - public void customize(final JList list, final String value, final int index, final boolean selected, final boolean cellHasFocus) { - String s = value; - if (s != null && s.length() > 1) { - s = s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); - } - setText(s); - } - } - private static class MyComponent { private JPanel myPanel; private JComboBox myFontCombo; @@ -324,7 +297,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab private JCheckBox myHideIconsInQuickNavigation; private JCheckBox myCbDisplayIconsInMenu; private JCheckBox myDisableMnemonics; - private JComboBox myTooltipMode; public MyComponent() { ActionListener updater = new ActionListener() { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form index 2d864aa94279..5fd3eade0677 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form +++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form @@ -35,7 +35,7 @@ - + @@ -61,20 +61,6 @@ - - - - - - - - - - - - - - From 5128d8c736fedc9a14120fb54277ebe35b7ec64f Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 13 May 2011 16:37:42 +0200 Subject: [PATCH 21/21] IDEA-13197 ("Convert to MessageFormat.format" / "Convert to String.format" should not run inside annotation parameter) for "Replace + with StringBuffer" and "Replace + with String.format()" --- .../siyeh/IntentionPowerPackBundle.properties | 9 ++++--- ...oncatenatedStringToClipboardIntention.java | 6 ++--- ...oncatenationWithFormatStringIntention.java | 2 +- ...oncatenationWithStringBufferIntention.java | 19 +++++++++++--- .../SimpleStringConcatenationPredicate.java | 26 +++++++++++++++++-- 5 files changed, 49 insertions(+), 13 deletions(-) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 167383937143..2025851ab4b5 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -47,8 +47,9 @@ remove.unnecessary.parentheses.intention.name=Remove unnecessary parentheses remove.unnecessary.parentheses.intention.family.name=Remove Unnecessary Parentheses merge.if.and.intention.name=Merge nested 'if's merge.if.and.intention.family.name=Merge Nested Ifs to ANDed Condition -replace.concatenation.with.string.buffer.intention.name=Replace '+' with '.append()' -replace.concatenation.with.string.buffer.intention.family.name=Replace + with StringBuffer.append() +replace.concatenation.with.string.buffer.intention.name=Replace '+' with 'StringBuffer.append()' +replace.concatenation.with.string.builder.intention.name=Replace '+' with 'StringBuilder.append()' +replace.concatenation.with.string.buffer.intention.family.name=Replace + with StringBuilder.append() remove.conditional.intention.name=Simplify '?:' remove.conditional.intention.family.name=Remove Pointless Conditional move.comment.to.separate.line.intention.name=Move comment to separate line @@ -121,8 +122,8 @@ wrap.vararg.arguments.with.explicit.array.intention.name=Wrap vararg arguments w wrap.vararg.arguments.with.explicit.array.intention.family.name=Wrap Vararg Arguments with Explicit Array Creation extract.while.loop.condition.to.if.statement.intention.name=Extract condition to internal 'if' statement extract.while.loop.condition.to.if.statement.intention.family.name=Extract While Loop Condition to Internal If Statement -replace.concatenation.with.format.string.intention.name=Replace '+' with 'String.format()' call -replace.concatenation.with.format.string.intention.family.name=Replace String Concatenation with String.format() Call +replace.concatenation.with.format.string.intention.name=Replace '+' with 'String.format()' +replace.concatenation.with.format.string.intention.family.name=Replace String Concatenation with String.format() copy.concatenated.string.to.clipboard.intention.name=Copy String concatenation text to the clipboard copy.concatenated.string.to.clipboard.intention.family.name=Copy String Concatenation Text to the Clipboard flip.expression.intention.family.name=Flip Binary Expression diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java index a79dccd80c04..730cd0649435 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/CopyConcatenatedStringToClipboardIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 Bas Leijdekkers + * Copyright 2008-2011 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ public class CopyConcatenatedStringToClipboardIntention extends Intention { @Override @NotNull protected PsiElementPredicate getElementPredicate() { - return new SimpleStringConcatenationPredicate(); + return new SimpleStringConcatenationPredicate(false); } @Override @@ -85,4 +85,4 @@ public class CopyConcatenatedStringToClipboardIntention extends Intention { } } } -} \ No newline at end of file +} diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java index 865f3f5db8ba..ff4318730190 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithFormatStringIntention.java @@ -31,7 +31,7 @@ public class ReplaceConcatenationWithFormatStringIntention @Override @NotNull protected PsiElementPredicate getElementPredicate() { - return new SimpleStringConcatenationPredicate(); + return new SimpleStringConcatenationPredicate(true); } @Override diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntention.java index 3ad5fa884003..8e16a1c2cad4 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/ReplaceConcatenationWithStringBufferIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,19 +18,32 @@ package com.siyeh.ipp.concatenation; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; +import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ipp.base.Intention; +import com.siyeh.ipp.base.MutablyNamedIntention; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ConcatenationUtils; import com.siyeh.ipp.psiutils.ParenthesesUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -public class ReplaceConcatenationWithStringBufferIntention extends Intention { +public class ReplaceConcatenationWithStringBufferIntention extends MutablyNamedIntention { + + @Override + protected String getTextForElement(PsiElement element) { + if (PsiUtil.isLanguageLevel5OrHigher(element)) { + return IntentionPowerPackBundle.message( + "replace.concatenation.with.string.builder.intention.name"); + } else { + return IntentionPowerPackBundle.message( + "replace.concatenation.with.string.buffer.intention.name"); + } + } @Override @NotNull public PsiElementPredicate getElementPredicate() { - return new SimpleStringConcatenationPredicate(); + return new SimpleStringConcatenationPredicate(true); } @Override diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/SimpleStringConcatenationPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/SimpleStringConcatenationPredicate.java index 3549a2807ea6..12b00a3feba2 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/SimpleStringConcatenationPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/concatenation/SimpleStringConcatenationPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,8 @@ */ package com.siyeh.ipp.concatenation; -import com.intellij.psi.PsiElement; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ConcatenationUtils; import com.siyeh.ipp.psiutils.ErrorUtil; @@ -23,10 +24,31 @@ import com.siyeh.ipp.psiutils.ErrorUtil; class SimpleStringConcatenationPredicate implements PsiElementPredicate{ + private final boolean excludeConcatentationsInsideAnnotations; + + public SimpleStringConcatenationPredicate(boolean excludeConcatentationsInsideAnnotations) { + this.excludeConcatentationsInsideAnnotations = excludeConcatentationsInsideAnnotations; + } + public boolean satisfiedBy(PsiElement element){ if(!ConcatenationUtils.isConcatenation(element)){ return false; } + if (excludeConcatentationsInsideAnnotations && isInsideAnnotation(element)) { + return false; + } return !ErrorUtil.containsError(element); } + + private static boolean isInsideAnnotation(PsiElement element) { + for (int i = 0; i < 20 && element instanceof PsiBinaryExpression; i++) { + // optimization: don't check deep string concatenation more than 20 levels up. + element = element.getParent(); + if (element instanceof PsiNameValuePair || + element instanceof PsiArrayInitializerMemberValue) { + return true; + } + } + return false; + } }