From 01ca5672d0092aa7aab4f2c0523039ec1b2fcfe5 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 9 Jun 2015 20:45:20 +0300 Subject: [PATCH 01/38] less bright red for tests status --- .../com/intellij/openapi/progress/util/ColorProgressBar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java index d3a78da89bdc..ca6a973668b4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ColorProgressBar.java @@ -37,7 +37,7 @@ public class ColorProgressBar extends JComponent { private static final Dimension PREFERRED_SIZE = new Dimension(146, 17); public static final Color GREEN = new JBColor(new Color(0x6cad74), new Color(0x4a8c53)); - public static final Color RED = new JBColor(new Color(0xb81708), new Color(0xdb5c5c)); + public static final Color RED = new JBColor(new Color(0xd67b76), new Color(0xb25050)); public static final Color BLUE = new JBColor(new Color(1, 68, 208), JBColor.blue); public static final Color YELLOW = new JBColor(new Color(0xa67a21), new Color(0x91703a)); private static final Color SHADOW1 = new JBColor(Gray._190, UIUtil.getBorderColor()) ; From 327861766066f2a33a06410cf0fa541fdbbf7bff Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 9 Jun 2015 19:44:09 +0300 Subject: [PATCH 02/38] extract flatten() --- .../intellij/util/containers/JBIterable.java | 75 +++++++++++-------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/JBIterable.java b/platform/util/src/com/intellij/util/containers/JBIterable.java index be76a2c699d2..479e2a74e723 100644 --- a/platform/util/src/com/intellij/util/containers/JBIterable.java +++ b/platform/util/src/com/intellij/util/containers/JBIterable.java @@ -92,38 +92,6 @@ public abstract class JBIterable implements Iterable { }; } - @NotNull - public static JBIterable from(@Nullable Iterable iterable, final Function> fun) { - if (iterable == null) return empty(); - final Iterable thatIt = iterable; - return new JBIterable() { - @Override - public Iterator iterator() { - final Iterator it = thatIt.iterator(); - return new Iterator() { - Iterator cur; - @Override - public boolean hasNext() { - while ((cur == null || !cur.hasNext()) && it.hasNext()) { - cur = fun.fun(it.next()).iterator(); - } - return cur != null && cur.hasNext(); - } - - @Override - public E next() { - return cur.next(); - } - - @Override - public void remove() { - cur.remove(); - } - }; - } - }; - } - /** * Returns a fluent iterable containing {@code elements} in the specified order. */ @@ -190,7 +158,7 @@ public abstract class JBIterable implements Iterable { } public final JBIterable append(@Nullable Iterable other, @NotNull Function> fun) { - return other == null ? this : this == EMPTY ? from(other, fun) : append(from(other, fun)); + return other == null ? this : this == EMPTY ? from(other).flatten(fun) : append(from(other).flatten(fun)); } /** @@ -302,6 +270,47 @@ public abstract class JBIterable implements Iterable { }); } + /** + * Returns a fluent iterable that applies {@code function} to each element of this + * fluent iterable and concats the produced iterables in one. + *

+ *

The returned fluent iterable's iterator supports {@code remove()} if an underlying iterable's + * iterator does. After a successful {@code remove()} call, this fluent iterable no longer + * contains the corresponding element. + */ + @NotNull + public JBIterable flatten(final Function> function) { + if (this == EMPTY) return empty(); + final Iterable thatIt = myIterable; + return new JBIterable() { + @Override + public Iterator iterator() { + final Iterator it = thatIt.iterator(); + return new Iterator() { + Iterator cur; + + @Override + public boolean hasNext() { + while ((cur == null || !cur.hasNext()) && it.hasNext()) { + cur = function.fun(it.next()).iterator(); + } + return cur != null && cur.hasNext(); + } + + @Override + public T next() { + return cur.next(); + } + + @Override + public void remove() { + cur.remove(); + } + }; + } + }; + } + /** * Returns the first element in this fluent iterable or null. */ From f0d2784af47d857d5a3ec3f21db378be6e85adf9 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 9 Jun 2015 22:41:46 +0300 Subject: [PATCH 03/38] parents(node) iterable --- .../src/com/intellij/psi/SyntaxTraverser.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/platform/core-api/src/com/intellij/psi/SyntaxTraverser.java b/platform/core-api/src/com/intellij/psi/SyntaxTraverser.java index d802165510e8..55ebbcfa73fa 100644 --- a/platform/core-api/src/com/intellij/psi/SyntaxTraverser.java +++ b/platform/core-api/src/com/intellij/psi/SyntaxTraverser.java @@ -80,6 +80,35 @@ public abstract class SyntaxTraverser extends FilteredTraverser parents(@Nullable final T element) { + return new JBIterable() { + @Override + public Iterator iterator() { + return new Iterator() { + T cur = element; + + @Override + public boolean hasNext() { + return cur != null; + } + + @Override + public T next() { + T result = cur; + cur = parent(cur); + return result; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }; + } + private abstract static class FirstNextTraverser extends SyntaxTraverser { public FirstNextTraverser(Meta meta) { @@ -161,7 +190,8 @@ public abstract class SyntaxTraverser extends FilteredTraverser Date: Tue, 9 Jun 2015 22:44:28 +0300 Subject: [PATCH 04/38] ShowExpressionTypeAction: extension point & providers --- .../codeInsight/hint/JavaTypeProvider.java | 51 ++++++++ .../intellij/lang/ExpressionTypeProvider.java | 35 +++++ .../lang/LanguageExpressionTypes.java | 28 ++++ .../hint/ShowExpressionTypeHandler.java | 123 ++++++++++++++++++ .../actions/ShowExpressionTypeAction.java | 47 +++++++ .../src/messages/ActionsBundle.properties | 2 + .../src/META-INF/LangExtensionPoints.xml | 3 + .../src/idea/Keymap_Default.xml | 3 + .../src/idea/LangActions.xml | 1 + resources/src/META-INF/IdeaPlugin.xml | 1 + 10 files changed, 294 insertions(+) create mode 100644 java/java-impl/src/com/intellij/codeInsight/hint/JavaTypeProvider.java create mode 100644 platform/lang-api/src/com/intellij/lang/ExpressionTypeProvider.java create mode 100644 platform/lang-api/src/com/intellij/lang/LanguageExpressionTypes.java create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/hint/ShowExpressionTypeHandler.java create mode 100644 platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowExpressionTypeAction.java diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/JavaTypeProvider.java b/java/java-impl/src/com/intellij/codeInsight/hint/JavaTypeProvider.java new file mode 100644 index 000000000000..17306f0c9159 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/hint/JavaTypeProvider.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.hint; + +import com.intellij.lang.ExpressionTypeProvider; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiType; +import com.intellij.psi.SyntaxTraverser; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author gregsh + */ +public class JavaTypeProvider extends ExpressionTypeProvider { + @NotNull + @Override + public String getInformationHint(@NotNull PsiExpression element) { + PsiType type = element.getType(); + String text = type == null ? "" : type.getCanonicalText(); + return StringUtil.escapeXml(text); + } + + @NotNull + @Override + public String getErrorHint() { + return "No expression found"; + } + + @NotNull + @Override + public List getExpressionsAt(@NotNull PsiElement elementAt) { + return SyntaxTraverser.psiTraverser().parents(elementAt).filter(PsiExpression.class).toList(); + } +} diff --git a/platform/lang-api/src/com/intellij/lang/ExpressionTypeProvider.java b/platform/lang-api/src/com/intellij/lang/ExpressionTypeProvider.java new file mode 100644 index 000000000000..163dc3f4d0c0 --- /dev/null +++ b/platform/lang-api/src/com/intellij/lang/ExpressionTypeProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.lang; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author gregsh + */ +public abstract class ExpressionTypeProvider { + @NotNull + public abstract String getInformationHint(@NotNull T element); + + @NotNull + public abstract String getErrorHint(); + + @NotNull + public abstract List getExpressionsAt(@NotNull PsiElement elementAt); +} diff --git a/platform/lang-api/src/com/intellij/lang/LanguageExpressionTypes.java b/platform/lang-api/src/com/intellij/lang/LanguageExpressionTypes.java new file mode 100644 index 000000000000..1e4b4a3299d1 --- /dev/null +++ b/platform/lang-api/src/com/intellij/lang/LanguageExpressionTypes.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @author max + */ +package com.intellij.lang; + +public class LanguageExpressionTypes extends LanguageExtension { + public static final LanguageExpressionTypes INSTANCE = new LanguageExpressionTypes(); + + private LanguageExpressionTypes() { + super("com.intellij.codeInsight.typeInfo"); + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowExpressionTypeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowExpressionTypeHandler.java new file mode 100644 index 000000000000..2eaeb0509595 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ShowExpressionTypeHandler.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.codeInsight.hint; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.TargetElementUtil; +import com.intellij.lang.ExpressionTypeProvider; +import com.intellij.lang.Language; +import com.intellij.lang.LanguageExpressionTypes; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.project.DumbService; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pass; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.IntroduceTargetChooser; +import com.intellij.util.Function; +import com.intellij.util.ObjectUtils; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.JBIterable; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; +import java.util.Set; + +public class ShowExpressionTypeHandler implements CodeInsightActionHandler { + + @Override + public boolean startInWriteAction() { + return false; + } + + public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) { + ApplicationManager.getApplication().assertIsDispatchThread(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + PsiElement elementAt = file.findElementAt( + TargetElementUtil.adjustOffset(file, editor.getDocument(), editor.getCaretModel().getOffset())); + if (elementAt == null) return; + + Language language = elementAt.getLanguage(); + final Set handlers = getHandlers(project, language, file.getViewProvider().getBaseLanguage()); + if (handlers.isEmpty()) return; + + TextRange range = EditorUtil.getSelectionInAnyMode(editor); + final Map map = ContainerUtil.newLinkedHashMap(); + for (ExpressionTypeProvider handler : handlers) { + for (PsiElement element : ((ExpressionTypeProvider)handler).getExpressionsAt(elementAt)) { + if (!element.getTextRange().contains(range)) continue; + map.put(element, handler); + } + } + Pass callback = new Pass() { + @Override + public void pass(@NotNull PsiElement expression) { + //noinspection unchecked + ExpressionTypeProvider provider = ObjectUtils.assertNotNull(map.get(expression)); + final String informationHint = provider.getInformationHint(expression); + TextRange range = expression.getTextRange(); + editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + HintManager.getInstance().showInformationHint(editor, informationHint); + } + }); + } + }; + if (map.isEmpty()) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + String errorHint = ObjectUtils.assertNotNull(ContainerUtil.getFirstItem(handlers)).getErrorHint(); + HintManager.getInstance().showErrorHint(editor, errorHint); + } + }); + } + else if (map.size() == 1) { + callback.pass(ObjectUtils.assertNotNull(ContainerUtil.getFirstItem(map.keySet()))); + } + else { + IntroduceTargetChooser.showChooser( + editor, ContainerUtil.newArrayList(map.keySet()), callback, + new Function() { + @Override + public String fun(@NotNull PsiElement expression) { + return expression.getText(); + } + } + ); + } + } + + @NotNull + public static Set getHandlers(final Project project, Language... languages) { + return JBIterable.of(languages).flatten(new Function>() { + @Override + public Iterable fun(Language language) { + return DumbService.getInstance(project).filterByDumbAwareness(LanguageExpressionTypes.INSTANCE.allForLanguage(language)); + } + }).addAllTo(ContainerUtil.newLinkedHashSet()); + } + +} + diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowExpressionTypeAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowExpressionTypeAction.java new file mode 100644 index 000000000000..dff9046a4f4f --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowExpressionTypeAction.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.codeInsight.hint.actions; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.codeInsight.actions.BaseCodeInsightAction; +import com.intellij.codeInsight.hint.ShowExpressionTypeHandler; +import com.intellij.lang.Language; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiUtilCore; +import org.jetbrains.annotations.NotNull; + +public class ShowExpressionTypeAction extends BaseCodeInsightAction implements DumbAware { + public ShowExpressionTypeAction() { + setEnabledInModalContext(true); + } + + @NotNull + @Override + protected CodeInsightActionHandler getHandler() { + return new ShowExpressionTypeHandler(); + } + + @Override + protected boolean isValidForFile(@NotNull Project project, @NotNull Editor editor, @NotNull final PsiFile file) { + Language language = PsiUtilCore.getLanguageAtOffset(file, editor.getCaretModel().getOffset()); + return !ShowExpressionTypeHandler.getHandlers(project, language, file.getViewProvider().getBaseLanguage()).isEmpty(); + } + +} \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 51b020b50bfa..249689fe7bcb 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -392,6 +392,8 @@ action.ShowSiblings.text=Show Siblings action.ShowSiblings.description=Show a popup window with the symbol siblings content action.ParameterInfo.text=_Parameter Info action.ParameterInfo.description=Show parameters of the method call at caret +action.TypeInfo.text=_Type Info +action.TypeInfo.description=Show type of the selected expression action.EditorContextInfo.text=_Context Info action.EditorContextInfo.description=Show the current method or class declaration when it is not visible action.ShowErrorDescription.text=E_rror Description diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 01cb8aced2b7..9ccd239588a7 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -556,6 +556,9 @@ + + + diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml index 0ef4d0fba164..df5b99edcf95 100644 --- a/platform/platform-resources/src/idea/Keymap_Default.xml +++ b/platform/platform-resources/src/idea/Keymap_Default.xml @@ -422,6 +422,9 @@ + + + diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 36671e305f56..229a96b53fe6 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -165,6 +165,7 @@ + diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index d9ed97e9257a..0a8c97f22364 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1028,6 +1028,7 @@ + From b616b5adb5550be5e88b66e0e11a51bcc8e354ac Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 10 Jun 2015 02:27:01 +0200 Subject: [PATCH 05/38] Yosemite checkboxes --- .../intellij/ide/ui/laf/icons/checkboxMac.png | Bin 0 -> 1112 bytes .../intellij/ide/ui/laf/icons/checkboxMac@2x.png | Bin 0 -> 1375 bytes .../ide/ui/laf/icons/checkboxSelectedMac.png | Bin 0 -> 1310 bytes .../ide/ui/laf/icons/checkboxSelectedMac@2x.png | Bin 0 -> 1821 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxMac.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxMac@2x.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxSelectedMac.png create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxSelectedMac@2x.png diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxMac.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxMac.png new file mode 100644 index 0000000000000000000000000000000000000000..ffa5e0bdd0e1c9ea498d92072f71f103677b82f3 GIT binary patch literal 1112 zcmaJ=TSyd97@jbfuFA4f{j5gNm4>QcHOb_0lafG$}L5TC~H5V$M_h&B&T@p=#>zX9+tPAW85Wka(^AS9#836Y< zympbI-MEi&&>pXk@om7J$R;U2>7?uw!+KmS<-~Izfub2wCmZD&bFq*WAQBMjEJ-Gl zNk`J<(2OpUW*CN~oTSrfM;>-FtwJGXSIz1?0|!jekaZ|)DsC|f9a=985Gd2%B`Eql zt!n1lgc?Ss1f8TElvPsRk>~&Kswnf`CX9kV`TmpGjHPuzMuDmI8X_88XSEedXM+Y1 zpk~B0tta2bNJ4{}nb34R7|eDJ=LJz#t-CCS=h?7oLO~Tlm9?cv79FMDnNyKtn>%#FNn3|py((v2Ml=^kQxn5!Lwzv za^YM&1^IGVsc;tILt4ZAYuNcKq#)}!FI{BJiyx>+@dlE%aC!AA^eiUATzxDx zJ@fq5(gA9D@!MB6TT^&wHe!2uvb;H-E?QH6X0q*bX*|qco7z+M?*8^gYbPpU1J^b= zoq2uj*mY%m^6K2l59w_$hIb$LA3ERvX43#ZTDJbZyz1e>k7GZu!6P9zzwF8Wv+GJI zKGPH1vZ8VG!qb_N*@_3{@e{@J&^}mhyHPA$+1u`h&nj;(Svdw|`P99`KNlxneZM3R zJ;lZoOR5GpJpS^{Ra-T8uB!iyc_DUjxE8jLY~4FLIFY$IQ*{>`8Qw%K_&Rmedh6j( K3wOC;$G|V_Fm!GJ literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxMac@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxMac@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..938152d98623eb9f26d201b18660fc5fd769adef GIT binary patch literal 1375 zcmeAS@N?(olHy`uVBq!ia0vp^G9b*s1|*Ak?@s|zk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m^Cs(B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxOgGuU&_u!9QqR!T z%-qskN5Kfl*Eg`xH!{#Qu(UEYwlXkMfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz{qpj1 zy>er{{GxPyLrY6beFGzXBO_g)3fZE`@j@w*YQzUNJP7fB~jokyxN_sAmB35=^15FMg%Dxp39RB|)hO_hL1;IHa;5 zRX-@TIKQ+g85nVC${?!>telHd6HD@oLh|!-V4)b0kzbNuoRMFk;OqX$Y%oHnEGfM+QS7&1bb3;o*LswHL6IUZwLq|(f z3u9AD17~BHUYGpj(%jU%5}4i;gkBSzdO-;yw*Y9fOKMSOS!#+~QGTuh*yC22SlnV_ zY+`QgWa^MGl-2$;Cn z+D_ZUz`%Ic)5S5Q;?|pKr?UMmEn_DpM3Ie z(at?LbIhbHIriVrcUychPiyL`=S4gFy_Oms*u|8v_~MGMReP5QXrz4L7U@6!kzL*9 z5%1+1J9V)ISF^qb>4@Dgjr|{#$QEHX+mx%7>1T~yQ0P<<*Fu&S4;`_^HFo}g>+UD8 zu`)G=mzqe~ZkTw`TET2eniB`7jX0M?(f<41!B@8FoK6UfO??}+GGvj5ic+J&l)YsK zKU7Q$YB)d9YObGeLH&B8nLMn`jyJt*{$y9=-6{oGT&3v%y7aVusK1%g+xcINW|4_AGCEvFh8Z6})T_ zMFM$dvqdkPyq|pXNwn46Y0U=bC-j}?$!(ELn6<1nZ1vS?N!vHv&CA|=(Z2OFL uJ9r)2;};)Ie$Ic3V{_5YoTR_u4U7zbLKKa>UovomiabwOKbLh*2~7Zh`{>{R literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxSelectedMac.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxSelectedMac.png new file mode 100644 index 0000000000000000000000000000000000000000..e1b7450c220a2e73360439c1dfc6addd99e31dfa GIT binary patch literal 1310 zcmeAS@N?(olHy`uVBq!ia0vp^d?3uh1|;P@bT0xa$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWuD@%xak-5hW46K32*3xq68pHF_1f1wh>l3^w)^1&PVosU-?Y zsp*+{wo31J?^jaDOtDo8H}y5}EpSfF$n>ZxN)4{^3rViZPPR-@vbR&PsjvbXkegbP zs8ErclUHn2VXFi-*9yo63F|8l;|;8yV;tSX!AHTNxNBK!Fm_wxX0Ys~{IQs9ivwtx`rwNr9EVetCJh zUb(Seeo?xG?WUP)qwZeFo6%mkOz;^d;tf|AVqJOz-6iAnjT zCALaHmqNUdTL3pUuNWFkzyQ;)NG#Ad)H48i38v837r)ZnT)67ulAu(Cd$Af^98y`3 zsvneEoL^d$42-xmWsp?`R?bDKi6!|(A^G_^uuu%h$S=t+&d4uNaCQcVnu2d)a%LV# z46Mi3*UB@mxFj(zIn~p}Rtac|US?*Bm5H&5xv`U}iGjJHnW3SpsgsGTk*lGjrKyFn zsilFlF-)&ZesXDUYF-IUZwf-MDNenh&i-XfO%|1%x!o?TA1B`|q9KwetHW2{7GU zG;d#pz-fKnBN7V|9V8j}cLhXsdHsCr`m;rN%5KruT<%Fej4C{OiE(H3&&;^Ru%P*} zAInJ|XYb1;uTM%eA6nXSGGu1zdwvaJaSN}L20YA5-WuF8sBTjGIQA%Okc2nDP5wdoed>tsl2f@9mAnQH|?<_y$O^NLlz5 zzENWg4K;k3rEL7%;oq{h)#>Uod`piDzW=9jXKzyO!TwLP+iohj?_K(M!G(t7!mq4P z>3jU!d{nGvv1!hk>b3XM*7fkeYn}YHzdu;1h1KiBFXkK8)lMgDo3dh$R-VlJCR6LE zaI8yEwTVe#w)t}Fj;V*;Ps~x4;p3lS=D@S~O>NeWYrXUL-^`J@7$Gw8gv)u6%wCfv hs&2pXPwZ!vVEEdw>XyW{b{0^H<>~6@vd$@?2>^JF(s%#> literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxSelectedMac@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/checkboxSelectedMac@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..10441fbd3921195ddf54598b0e94bc9a4847f10f GIT binary patch literal 1821 zcmaJ?X;2eq7>?Ca0a40PIkc|fFdVrPa#UbK4oDyr1H}ji3CThtB)cRF1R1r3N;w@5 zibvJTP)0;W5g6qV5d;qet*9IdA}uP41*ND(E8U=Af0XXb?)SalywCGq&+cZ21p8Z< zIhbKE7z<$lPlB$?jQ2tl^r^GBUw|(52w#eXLa|7STnAz}N+<>dgc^AqC;{cl)Wj>` zY7AyRP8}viq~aj90@4uVMjwJf1EXjRX0@*YmMh{x1c(9S)LL)sXx(`%pjLWg*V4r# zG0X*3>VQo;FmzLJm||1Bf~Caz`T(m9Y?MF)B67f>Nzm%q25;;%FB{z(kBL}d+69UC z#=cKVDh>g-kPZas1TVaTM5X}@7J*FnVz3yV00p&)BqotU!jo8RI+abL03R+a8cnB+ zWlMO153x|o8>>PPm`x<6q@)m1s02tCM!zytLP zof<~ekQOj9%447;#2brd`o07WJWH$9e`pihFrq;Y6UhXUv7{MCvH1U8HJVv(Jt6@= z=KG(-`mj_OBuYR%l%!LjgNt=ChJx8#9Vka2T^Ix<%ycnC1tE}L1;GH9JKZ$^CzdPJ zTH~SHG)gRH3$=Pgu2q0So;McdA*j_#Hj~F>dC^D=5`#=5llgQ%8lS=^b69jHmChn@ zsWVs}q)5_$T4V;R{D@`Fi8TsB1EZ07piZ3(Dg`=7156jrR?nRaeNMg)SmoTgc+H6= zqR9}A9NPSsF% z2Yo5d%?au4%@`4emDq6B7l!lhm72?NW`qTNOWXCsf_n>n)~GmkdF-WSn*3+sf{_&!;rDX(F5m35uufTZ`M^czf~ufk z`s-i^!?JR}4gOhuz2PqT9!S8c%Q!;nH}6cOhgu$Ph>)uuR76^m6Dvgxo?RopU9Vxw z6Z>-pbQex9Z7HxH1FfiK-H;pGRU3>=|=%H7yi#>X(puCu+DoQPOoR?pO|2Cb9uz>HTk8tk!OjTlw66G$o|X=B z&^5Q{JUo=?+~b}fcZTXTRD34%@w)`Sal>KvoZoJYl-S%2HSfSLHgA*4TysYSt3uD- zw9e>ynsIl?-G>`V$fyh2EvXmOUT)oD`X(XHVh?ri&KFn5$!|raaC}6RG)ia+SM@hl zdReS}b!A~`ZD)7Y-y*YB$*D!x?%T;m6$VOl^t!h8x_-zOk`3$p1u6XC1iH zZQ_e(%`5G1+YWDhd*DuD%~vK%PC5#OjGzmF-WxJgqAnf0p4L_KYlAGkLuOw_gQEjm zab2~=cH2FgaN8&zDu>TY8QY&w%*9Fbp4Xh{&wxTZReiraKYyUAfau$jI4ZLO!J%By zI?I41tDFf#yA#6-k9Dta)^t2gYH%BPi+;BT{2noB`E@s+5zGohB~O-b+UqQ$5V!lj z-u587=F=rnquDXI!bGtAkVkE%O=C$}{gL{5ANSz?sq7x*Lv7xo_Cf7dt1W+sCS?^p z+1=q^;%eGkWd58t=i8VQW1qDSvVHPg;g`eAy=B?sC5>4nHxT~(ugj-+>5|Q*J#{|q z1H&cqmCLKYy*_IDs6`}1HQ_Ln_X%TPlLas2>aEdNxnjxEr=lZgSQ*m1hXRKov%W(M zN{%N0=Ne-y-u+N8oVc^n&f+MI;X3grr{hZe7QvbtPJv6TYxHU_a+b^Fj?A$Aj#CrB hNKpTj{?-(}5p(a-j}bQGlgY*(mXIIJEBA{|{|Dmj&!zwX literal 0 HcmV?d00001 From fa36c518238c70b5482d43a78866b8e074a8f01d Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 10 Jun 2015 02:28:20 +0200 Subject: [PATCH 06/38] Darcula: split paint into drawIcon and drawText --- .../ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java index d8f77d38c8c1..31ca209b4e64 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaCheckBoxUI.java @@ -46,7 +46,6 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI { public synchronized void paint(Graphics g2d, JComponent c) { Graphics2D g = (Graphics2D)g2d; JCheckBox b = (JCheckBox) c; - final ButtonModel model = b.getModel(); final Dimension size = c.getSize(); final Font font = c.getFont(); @@ -72,6 +71,11 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI { final boolean selected = b.isSelected(); final boolean enabled = b.isEnabled(); + drawCheckIcon(c, g, b, iconRect, selected, enabled); + drawText(c, g, b, fm, textRect, text); + } + + protected void drawCheckIcon(JComponent c, Graphics2D g, JCheckBox b, Rectangle iconRect, boolean selected, boolean enabled) { if (selected && b.getSelectedIcon() != null) { b.getSelectedIcon().paintIcon(b, g, iconRect.x + JBUI.scale(4), iconRect.y + JBUI.scale(2)); } else if (!selected && b.getIcon() != null) { @@ -85,7 +89,7 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI { g.translate(x, y); final Paint paint = UIUtil.getGradientPaint(w / 2, 0, b.getBackground().brighter(), - w / 2, h, b.getBackground()); + w / 2, h, b.getBackground()); g.setPaint(paint); final int fillOffset = JBUI.scale(1); g.fillRect(fillOffset, fillOffset, w - 2*fillOffset, h - 2*fillOffset); @@ -123,14 +127,16 @@ public class DarculaCheckBoxUI extends MetalCheckBoxUI { g.translate(-x, -y); config.restore(); } + } + protected void drawText(JComponent c, Graphics2D g, JCheckBox b, FontMetrics fm, Rectangle textRect, String text) { //text if(text != null) { View view = (View) c.getClientProperty(BasicHTML.propertyKey); if (view != null) { view.paint(g, textRect); } else { - g.setColor(model.isEnabled() ? b.getForeground() : getDisabledTextColor()); + g.setColor(b.isEnabled() ? b.getForeground() : getDisabledTextColor()); SwingUtilities2.drawStringUnderlineCharAt(c, g, text, b.getDisplayedMnemonicIndex(), textRect.x, From 88714e29779845b6a6b8f760ac35878bbc65ed65 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 10 Jun 2015 02:28:56 +0200 Subject: [PATCH 07/38] Yosemite like checkbox --- .../laf/intellij/MacIntelliJCheckBoxUI.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java new file mode 100644 index 000000000000..db7cbcd21d36 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJCheckBoxUI.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.ui.laf.intellij; + +import com.intellij.openapi.util.IconLoader; +import com.intellij.util.ui.EmptyIcon; + +import javax.swing.*; +import javax.swing.plaf.ComponentUI; +import java.awt.*; + +/** + * @author Konstantin Bulenkov + */ +public class MacIntelliJCheckBoxUI extends IntelliJCheckBoxUI { + public static final Icon DEFAULT_ICON = EmptyIcon.create(14); + + @SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"}) + public static ComponentUI createUI(JComponent c) { + return new MacIntelliJCheckBoxUI(); + } + + @Override + protected void drawCheckIcon(JComponent c, Graphics2D g, JCheckBox b, Rectangle iconRect, boolean selected, boolean enabled) { + Icon icon; + if (selected) { + icon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/checkboxSelectedMac.png", MacIntelliJCheckBoxUI.class, true); + } else { + icon = IconLoader.findIcon("/com/intellij/ide/ui/laf/icons/checkboxMac.png", MacIntelliJCheckBoxUI.class, true); + } + if (icon != null) { + icon.paintIcon(c, g, iconRect.x, iconRect.y); + } + } + + @Override + public Icon getDefaultIcon() { + return DEFAULT_ICON; + } + + private static boolean isGraphite() { + return false; + } +} From b8536847ea3bea26eaed61f637361b20dbe1d48a Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 10 Jun 2015 02:29:36 +0200 Subject: [PATCH 08/38] register new checkboxes for intellij laf on Mac OS X --- .../src/com/intellij/ide/ui/laf/intellijlaf_mac.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties index e69de29bb2d1..8f312d447606 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties @@ -0,0 +1 @@ +CheckBoxUI=com.intellij.ide.ui.laf.intellij.MacIntelliJCheckBoxUI \ No newline at end of file From 79fc9805ddbe0463cfc1ce0137049ababf22a006 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 10 Jun 2015 02:44:19 +0200 Subject: [PATCH 09/38] Rollback: endless loop and 100% CPU usage for modal dialogs --- .../intellij/ui/components/JBScrollPane.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java index 0e96a7f4340e..1b317f8016b6 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java @@ -35,6 +35,9 @@ public class JBScrollPane extends JScrollPane { private int myViewportBorderWidth = -1; private boolean myHasOverlayScrollbars; + private int myOverriddenVPolicy = -1; + private int myOverriddenHPolicy = -1; + public JBScrollPane(int viewportWidth) { init(false); myViewportBorderWidth = viewportWidth; @@ -128,12 +131,50 @@ public class JBScrollPane extends JScrollPane { return new JBViewport(); } + @Override + public int getHorizontalScrollBarPolicy() { + // See layout() for explanation + //noinspection MagicConstant + return myOverriddenHPolicy != -1 ? myOverriddenHPolicy : super.getHorizontalScrollBarPolicy(); + } + + @Override + public int getVerticalScrollBarPolicy() { + // See layout() for explanation + //noinspection MagicConstant + return myOverriddenVPolicy != -1 ? myOverriddenVPolicy : super.getVerticalScrollBarPolicy(); + } + @SuppressWarnings("deprecation") @Override public void layout() { LayoutManager layout = getLayout(); ScrollPaneLayout scrollLayout = layout instanceof ScrollPaneLayout ? (ScrollPaneLayout)layout : null; + // Logic here is a workaround necessary to support OS X overlaid scrollbars. + + int oldHPolicy = -1; + int oldVPolicy = -1; + if (scrollLayout != null) { + // First, we override scrollbar policy to HORIZONTAL_SCROLLBAR_AS_NEEDED so JScrollPane could correctly lay them out. + // We do so only when policy is ALWAYS so they could be hidden by JScrollPane when necessary. + // Also, we only override when scrollbar is an overlay scrollbar. + // (The related problem is IDEA-123688) + if (isOverlaidScrollbar(getHorizontalScrollBar())) { + oldHPolicy = scrollLayout.getHorizontalScrollBarPolicy(); + if (oldHPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) { + scrollLayout.setHorizontalScrollBarPolicy(myOverriddenHPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED); + } + } + + if (isOverlaidScrollbar(getVerticalScrollBar())) { + oldVPolicy = scrollLayout.getVerticalScrollBarPolicy(); + if (oldVPolicy == VERTICAL_SCROLLBAR_ALWAYS) { + scrollLayout.setVerticalScrollBarPolicy(myOverriddenVPolicy = VERTICAL_SCROLLBAR_AS_NEEDED); + } + } + } + // Now we let JScrollPane layout everything as necessary super.layout(); @@ -144,6 +185,12 @@ public class JBScrollPane extends JScrollPane { this, scrollLayout, myHasOverlayScrollbars // If last time we did relayouting, we should restore it back. ); + + // Now we restore overridden policies as though nothing happened at all. + if (oldHPolicy != -1) scrollLayout.setHorizontalScrollBarPolicy(oldHPolicy); + if (oldVPolicy != -1) scrollLayout.setVerticalScrollBarPolicy(oldVPolicy); + myOverriddenHPolicy = -1; + myOverriddenVPolicy = -1; } else { myHasOverlayScrollbars = false; From 145baab3a758f9fe24046ce56208c8c3375e23f2 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 10 Jun 2015 03:34:12 +0200 Subject: [PATCH 10/38] rollback again --- .../intellij/ui/components/JBScrollPane.java | 47 ------------------- 1 file changed, 47 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java index 1b317f8016b6..0e96a7f4340e 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java @@ -35,9 +35,6 @@ public class JBScrollPane extends JScrollPane { private int myViewportBorderWidth = -1; private boolean myHasOverlayScrollbars; - private int myOverriddenVPolicy = -1; - private int myOverriddenHPolicy = -1; - public JBScrollPane(int viewportWidth) { init(false); myViewportBorderWidth = viewportWidth; @@ -131,50 +128,12 @@ public class JBScrollPane extends JScrollPane { return new JBViewport(); } - @Override - public int getHorizontalScrollBarPolicy() { - // See layout() for explanation - //noinspection MagicConstant - return myOverriddenHPolicy != -1 ? myOverriddenHPolicy : super.getHorizontalScrollBarPolicy(); - } - - @Override - public int getVerticalScrollBarPolicy() { - // See layout() for explanation - //noinspection MagicConstant - return myOverriddenVPolicy != -1 ? myOverriddenVPolicy : super.getVerticalScrollBarPolicy(); - } - @SuppressWarnings("deprecation") @Override public void layout() { LayoutManager layout = getLayout(); ScrollPaneLayout scrollLayout = layout instanceof ScrollPaneLayout ? (ScrollPaneLayout)layout : null; - // Logic here is a workaround necessary to support OS X overlaid scrollbars. - - int oldHPolicy = -1; - int oldVPolicy = -1; - if (scrollLayout != null) { - // First, we override scrollbar policy to HORIZONTAL_SCROLLBAR_AS_NEEDED so JScrollPane could correctly lay them out. - // We do so only when policy is ALWAYS so they could be hidden by JScrollPane when necessary. - // Also, we only override when scrollbar is an overlay scrollbar. - // (The related problem is IDEA-123688) - if (isOverlaidScrollbar(getHorizontalScrollBar())) { - oldHPolicy = scrollLayout.getHorizontalScrollBarPolicy(); - if (oldHPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) { - scrollLayout.setHorizontalScrollBarPolicy(myOverriddenHPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED); - } - } - - if (isOverlaidScrollbar(getVerticalScrollBar())) { - oldVPolicy = scrollLayout.getVerticalScrollBarPolicy(); - if (oldVPolicy == VERTICAL_SCROLLBAR_ALWAYS) { - scrollLayout.setVerticalScrollBarPolicy(myOverriddenVPolicy = VERTICAL_SCROLLBAR_AS_NEEDED); - } - } - } - // Now we let JScrollPane layout everything as necessary super.layout(); @@ -185,12 +144,6 @@ public class JBScrollPane extends JScrollPane { this, scrollLayout, myHasOverlayScrollbars // If last time we did relayouting, we should restore it back. ); - - // Now we restore overridden policies as though nothing happened at all. - if (oldHPolicy != -1) scrollLayout.setHorizontalScrollBarPolicy(oldHPolicy); - if (oldVPolicy != -1) scrollLayout.setVerticalScrollBarPolicy(oldVPolicy); - myOverriddenHPolicy = -1; - myOverriddenVPolicy = -1; } else { myHasOverlayScrollbars = false; From 71a7438e70d28b9550433dd2ba6c1810125cdc28 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 10 Jun 2015 04:26:18 +0200 Subject: [PATCH 11/38] new background for Yosemite LaF --- .../intellij/ide/ui/laf/intellijlaf_mac.properties | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties index 8f312d447606..63c3c43f8653 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties @@ -1 +1,12 @@ -CheckBoxUI=com.intellij.ide.ui.laf.intellij.MacIntelliJCheckBoxUI \ No newline at end of file +intellijlaf.background=ececec +window=ececec + +CheckBoxUI=com.intellij.ide.ui.laf.intellij.MacIntelliJCheckBoxUI + +Panel.background=ececec +PopupMenu.translucentBackground=ececec +Spinner.background=ececec +Spinner.darcula.disabledButtonColor=ececec + +SplitPane.highlight=ececec + From 15e72b9d3f47d97a296098457019a6a0904fdc11 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 10 Jun 2015 04:27:49 +0200 Subject: [PATCH 12/38] use Helvetica Neue with face CondensedBlack --- .../com/intellij/ide/ui/laf/IntelliJLaf.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/IntelliJLaf.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/IntelliJLaf.java index e1e77fb8354f..07f6726ce928 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/IntelliJLaf.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/IntelliJLaf.java @@ -16,8 +16,12 @@ package com.intellij.ide.ui.laf; import com.intellij.ide.ui.laf.darcula.DarculaLaf; +import com.intellij.openapi.util.SystemInfo; +import javax.swing.*; +import javax.swing.plaf.FontUIResource; import javax.swing.plaf.metal.DefaultMetalTheme; +import java.awt.*; /** * @author Konstantin Bulenkov @@ -37,4 +41,20 @@ public class IntelliJLaf extends DarculaLaf { protected DefaultMetalTheme createMetalTheme() { return new IdeaBlueMetalTheme(); } + + @Override + public UIDefaults getDefaults() { + UIDefaults defaults = super.getDefaults(); + if (SystemInfo.isMacOSYosemite) { + installMacOSXFonts(defaults); + } + return defaults; + } + + private static void installMacOSXFonts(UIDefaults defaults) { + FontUIResource font = new FontUIResource("HelveticaNeue-CondensedBlack", Font.PLAIN, 13); + defaults.put("Label.font", font); + defaults.put("CheckBox.font", font); + defaults.put("RadioButton.font", font); + } } From 8370ea059d1c3bd4297ef2e9e1fe1f9c432206dd Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Wed, 10 Jun 2015 09:33:41 +0300 Subject: [PATCH 13/38] don't show useless system error message when unresolved relative URL is clicked at in Quick Doc --- .../codeInsight/documentation/DocumentationManager.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 76b84b664728..995110c7d172 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -954,13 +954,13 @@ public class DocumentationManager extends DockablePopupManager Date: Wed, 10 Jun 2015 11:00:46 +0300 Subject: [PATCH 14/38] supported test.jvm.memory property for community tests --- build/scripts/tests.gant | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/build/scripts/tests.gant b/build/scripts/tests.gant index 0fb3490efb47..f8a4bdc9a0f0 100644 --- a/build/scripts/tests.gant +++ b/build/scripts/tests.gant @@ -23,10 +23,18 @@ if ("GIT_TESTS".equalsIgnoreCase(System.getProperty("idea.test.group"))) { setProperty("cucumber_test_dirs", [["git4idea", "Idea", "${home}/plugins/git4idea/test-features/git4idea", "git4idea"]]) } -def args = [ - "-Xmx450m", - "-Dsun.io.useCanonCaches=false" -] +def args = [] + +def mem = System.getProperty("test.jvm.memory") +if (mem != null) { + args.addAll(mem.split()) +} +else { + args += [ + "-Xmx450m", + "-Dsun.io.useCanonCaches=false" + ] +} if (System.getProperty("os.name").toLowerCase().startsWith("mac")) { String vendor = System.getProperty("java.vm.vendor") From 466ac1c61c19d9f544b7047c7bd81242c9b2f38c Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Wed, 10 Jun 2015 11:14:19 +0300 Subject: [PATCH 15/38] IDEA-141262 Action "Folding Code Block" sometimes does not work properly --- .../folding/impl/CollapseBlockHandler.java | 7 ++++- .../folding/JavaFoldingTest.groovy | 27 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/CollapseBlockHandler.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/CollapseBlockHandler.java index 890268037df3..9b60f1e49d01 100644 --- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/CollapseBlockHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/CollapseBlockHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,11 @@ public class CollapseBlockHandler implements CodeInsightActionHandler { int end = block.getTextRange().getEndOffset(); FoldRegion existing = FoldingUtil.findFoldRegion(editor, start, end); if (existing != null) { + if (existing.isExpanded()) { + existing.setExpanded(false); + editor.getCaretModel().moveToOffset(existing.getEndOffset()); + return; + } previous = existing; if (info.getPsiElement(existing) == null) myPrevious = existing; block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index 7347fe3b190a..78c6299ffb1c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1116,6 +1116,31 @@ class Foo { \t} }"""); } + + public void testCollapseExistingButExpandedBlock() { + String text = '''class Foo { + void m { + if (true) { + System.out.println(); + } + } +} +''' + configure text + + myFixture.editor.caretModel.moveToOffset(text.indexOf("System")) + myFixture.performEditorAction("CollapseBlock") + + myFixture.performEditorAction("ExpandAllRegions") + + myFixture.editor.caretModel.moveToOffset(text.indexOf("System")) + myFixture.performEditorAction("CollapseBlock") + + def topLevelRegions = ((FoldingModelEx)myFixture.editor.foldingModel).fetchTopLevel() + assert topLevelRegions.length == 1 + assert topLevelRegions[0].startOffset == text.indexOf('{', text.indexOf("if")) + assert topLevelRegions[0].endOffset == text.indexOf('}', text.indexOf("if")) + 1 + } private int getFoldRegionsCount() { return myFixture.editor.foldingModel.allFoldRegions.length From 6ce7b09b7aa2efc21580a675f4be6e4b272463ef Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 10 Jun 2015 11:35:21 +0300 Subject: [PATCH 16/38] clean target storages on rebuild --- .../org/jetbrains/jps/incremental/storage/BuildDataManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java index 8a4a4a26e140..7e7bf670fe9b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java @@ -185,7 +185,7 @@ public class BuildDataManager implements StorageOwner { public void clean() throws IOException { try { - myTargetStoragesOwner.close(); + myTargetStoragesOwner.clean(); myTargetStorages.clear(); } finally { From 45d53038e1cd0795f15732e4ac44f89b0d055355 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 10 Jun 2015 11:43:00 +0300 Subject: [PATCH 17/38] wider offset --- .../com/intellij/execution/testframework/ui/TestStatusLine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java index 1ee8013eabb7..f524cb19343f 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/ui/TestStatusLine.java @@ -47,7 +47,7 @@ public class TestStatusLine extends JPanel { progressPanel.setMinimumSize(size); progressPanel.setPreferredSize(size); progressPanel.add(myProgressBar, new GridBagConstraints(0, 0, 0, 0, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, - new Insets(2, 2, 0, 8), 0, 0)); + new Insets(2, 8, 0, 8), 0, 0)); setStatusColor(ColorProgressBar.GREEN); add(myState, BorderLayout.CENTER); myState.append(ExecutionBundle.message("junit.runing.info.starting.label")); From c2cb84abfad8de7a5cf3b4f28455beac6d2695db Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 10 Jun 2015 11:55:01 +0300 Subject: [PATCH 18/38] mark "main" method only --- .../ApplicationRunLineMarkerProvider.java | 2 +- .../navigation/RunLineMarkerTest.java | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/navigation/RunLineMarkerTest.java diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationRunLineMarkerProvider.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationRunLineMarkerProvider.java index 2c8100955bf6..b161cbec1885 100644 --- a/java/execution/impl/src/com/intellij/execution/application/ApplicationRunLineMarkerProvider.java +++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationRunLineMarkerProvider.java @@ -38,7 +38,7 @@ public class ApplicationRunLineMarkerProvider implements LineMarkerProvider { public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) { if (element instanceof PsiClass && PsiMethodUtil.findMainInClass((PsiClass)element) != null) return new RunLineMarkerInfo(element, ApplicationConfigurationType.getInstance().getIcon(), null); - if (element instanceof PsiMethod && PsiMethodUtil.isMainMethod((PsiMethod)element)) + if (element instanceof PsiMethod && "main".equals(((PsiMethod)element).getName()) && PsiMethodUtil.isMainMethod((PsiMethod)element)) return new RunLineMarkerInfo(element, ApplicationConfigurationType.getInstance().getIcon(), null); return null; } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/navigation/RunLineMarkerTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/RunLineMarkerTest.java new file mode 100644 index 000000000000..4b33b4623503 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/navigation/RunLineMarkerTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.navigation; + +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; + +/** + * @author Dmitry Avdeev + */ +public class RunLineMarkerTest extends LightCodeInsightFixtureTestCase { + + public void testRunLineMarker() throws Exception { + myFixture.configureByText("MainTest.java", "public class MainTest {\n" + + " public static void foo(String[] args) {\n" + + " }\n " + + " public static void main(String[] args) {\n" + + " }\n" + + "}"); + assertEquals(0, myFixture.findGuttersAtCaret().size()); + assertEquals(2, myFixture.findAllGutters().size()); + } +} From af11bcfb48d2b8d3af2e71265f24e8237a9cc171 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 10 Jun 2015 12:01:20 +0200 Subject: [PATCH 19/38] reset version string in SdkModificator only if real changes in roots were detected --- .../com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java index 2f8f22913b9a..756b641a0439 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java @@ -312,6 +312,7 @@ public class ProjectJdkImpl extends UserDataHolderBase implements JDOMExternaliz @Override public void rootsChanged() { + resetVersionString(); if (myListeners.isEmpty()) { return; } From 289904bfe7545ef059b1c6e3c4b96092795b3b59 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 8 Jun 2015 17:20:58 +0300 Subject: [PATCH 20/38] comments --- .../psi/impl/smartPointers/SelfElementInfo.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java index 527c87bd01ca..c1fafb9aff17 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java +++ b/platform/core-impl/src/com/intellij/psi/impl/smartPointers/SelfElementInfo.java @@ -145,7 +145,7 @@ public class SelfElementInfo implements SmartPointerElementInfo { mySyncMarkerIsValid = false; } } - myRangeMarker = null; // clear hard ref to avoid leak, hold soft ref for not recreating marker later + myRangeMarker = null; // clear hard ref to avoid leak, but hold soft ref (in myMarkerRef) for not recreating marker too often } @Override @@ -169,11 +169,11 @@ public class SelfElementInfo implements SmartPointerElementInfo { return restoreFileFromVirtual(myVirtualFile, myProject, myLanguage); } - protected static PsiElement findElementInside(@NotNull PsiFile file, - int syncStartOffset, - int syncEndOffset, - @NotNull Class type, - @NotNull Language language) { + static PsiElement findElementInside(@NotNull PsiFile file, + int syncStartOffset, + int syncEndOffset, + @NotNull Class type, + @NotNull Language language) { PsiElement anchor = file.getViewProvider().findElementAt(syncStartOffset, language); if (anchor == null) return null; @@ -266,11 +266,11 @@ public class SelfElementInfo implements SmartPointerElementInfo { }); } - protected int getSyncEndOffset() { + int getSyncEndOffset() { return mySyncEndOffset; } - protected int getSyncStartOffset() { + int getSyncStartOffset() { return mySyncStartOffset; } From 70a5a7a567001b94c73eb1c1a3c7f3abde6fdf8d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 9 Jun 2015 14:09:36 +0300 Subject: [PATCH 21/38] cleanup --- .../openapi/project/ex/ProjectManagerEx.java | 6 +-- .../project/impl/ProjectManagerImpl.java | 48 +++++++++---------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectManagerEx.java b/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectManagerEx.java index ad61d683d3fb..fec084c17432 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectManagerEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/ex/ProjectManagerEx.java @@ -42,11 +42,11 @@ public abstract class ProjectManagerEx extends ProjectManager { @Nullable public abstract Project loadProject(@NotNull String filePath) throws IOException, JDOMException, InvalidDataException; - public abstract boolean openProject(Project project); + public abstract boolean openProject(@NotNull Project project); public abstract boolean isProjectOpened(Project project); - public abstract boolean canClose(Project project); + public abstract boolean canClose(@NotNull Project project); public abstract void saveChangedProjectFile(@NotNull VirtualFile file, @NotNull Project project); @@ -71,5 +71,5 @@ public abstract class ProjectManagerEx extends ProjectManager { } @Nullable - public abstract Project convertAndLoadProject(String filePath) throws IOException; + public abstract Project convertAndLoadProject(@NotNull String filePath) throws IOException; } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index 6650d19f37ca..26afe010c1e6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -75,13 +75,9 @@ import java.io.IOException; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; -@State( - name = "ProjectManager", - storages = { - @Storage( - file = StoragePathMacros.APP_CONFIG + "/project.default.xml" - )} -) +@State(name = "ProjectManager", storages = @Storage( + file = StoragePathMacros.APP_CONFIG + "/project.default.xml" +)) public class ProjectManagerImpl extends ProjectManagerEx implements PersistentStateComponent, ExportableApplicationComponent { private static final Logger LOG = Logger.getInstance(ProjectManagerImpl.class); @@ -89,9 +85,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt private static final Key> LISTENERS_IN_PROJECT_KEY = Key.create("LISTENERS_IN_PROJECT_KEY"); - @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) + @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") private ProjectImpl myDefaultProject; // Only used asynchronously in save and dispose, which itself are synchronized. - @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) + @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") private Element myDefaultProjectRootElement; // Only used asynchronously in save and dispose, which itself are synchronized. private boolean myDefaultProjectConfigurationChanged; @@ -107,7 +103,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt private final AtomicInteger myReloadBlockCount = new AtomicInteger(0); private final ProgressManager myProgressManager; - private volatile boolean myDefaultProjectWasDisposed = false; + private volatile boolean myDefaultProjectWasDisposed; private final Runnable restartApplicationOrReloadProjectTask = new Runnable() { @Override @@ -119,7 +115,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt }; @NotNull - private static List getListeners(Project project) { + private static List getListeners(@NotNull Project project) { List array = project.getUserData(LISTENERS_IN_PROJECT_KEY); if (array == null) return Collections.emptyList(); return array; @@ -222,7 +218,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } } - public static int TEST_PROJECTS_CREATED = 0; + public static int TEST_PROJECTS_CREATED; private static final boolean LOG_PROJECT_LEAKAGE_IN_TESTS = false; private static final int MAX_LEAKY_PROJECTS = 42; @SuppressWarnings("FieldCanBeLocal") private final Map myProjects = new WeakHashMap(); @@ -234,7 +230,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } @Nullable - public Project newProject(final String projectName, @NotNull String filePath, boolean useDefaultProjectSettings, boolean isDummy, + public Project newProject(@Nullable String projectName, @NotNull String filePath, boolean useDefaultProjectSettings, boolean isDummy, boolean optimiseTestLoadSpeed) { filePath = toCanonicalName(filePath); @@ -285,7 +281,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } @NonNls - private static String message(Throwable e) { + @NotNull + private static String message(@NotNull Throwable e) { String message = e.getMessage(); if (message != null) return message; message = e.getLocalizedMessage(); @@ -336,7 +333,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt : new ProjectImpl(this, new File(filePath).getAbsolutePath(), isOptimiseTestLoadSpeed, projectName); } - private static void scheduleDispose(final ProjectImpl project) { + private static void scheduleDispose(@NotNull final ProjectImpl project) { if (project.isDefault()) { return; } @@ -442,7 +439,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } @Override - public boolean openProject(final Project project) { + public boolean openProject(@NotNull final Project project) { if (isLight(project)) { throw new AssertionError("must not open light project"); } @@ -533,7 +530,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt myOpenProjectsArrayCache = myOpenProjects.toArray(new Project[myOpenProjects.size()]); } - private static void waitForFileWatcher(ProgressIndicator indicator) { + private static void waitForFileWatcher(@NotNull ProgressIndicator indicator) { LocalFileSystem fs = LocalFileSystem.getInstance(); if (!(fs instanceof LocalFileSystemImpl)) return; @@ -582,7 +579,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt */ @Override @Nullable - public Project convertAndLoadProject(String filePath) throws IOException { + public Project convertAndLoadProject(@NotNull String filePath) throws IOException { final String fp = toCanonicalName(filePath); final ConversionResult conversionResult = ConversionService.getInstance().convert(fp); if (conversionResult.openingIsCanceled()) { @@ -696,9 +693,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } Collection> causes = new SmartList>(); - Collection> changes; synchronized (myChangedProjectFiles) { - changes = myChangedProjectFiles.remove(project); + Collection> changes = myChangedProjectFiles.remove(project); if (!ContainerUtil.isEmpty(changes)) { for (Pair change : changes) { causes.add(change); @@ -739,6 +735,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } } + @NotNull @Override public Collection closeTestProject(@NotNull Project project) { synchronized (myOpenProjects) { @@ -864,6 +861,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt return true; } + @TestOnly public static boolean isLight(@NotNull Project project) { return ApplicationManager.getApplication().isUnitTestMode() && project.toString().contains("light_temp_"); } @@ -873,7 +871,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt return closeProject(project, true, true, true); } - private void fireProjectClosing(Project project) { + private void fireProjectClosing(@NotNull Project project) { if (LOG.isDebugEnabled()) { LOG.debug("enter: fireProjectClosing()"); } @@ -928,7 +926,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt LOG.assertTrue(removed); } - private void fireProjectOpened(Project project) { + private void fireProjectOpened(@NotNull Project project) { if (LOG.isDebugEnabled()) { LOG.debug("projectOpened"); } @@ -943,7 +941,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } } - private void fireProjectClosed(Project project) { + private void fireProjectClosed(@NotNull Project project) { if (LOG.isDebugEnabled()) { LOG.debug("projectClosed"); } @@ -959,7 +957,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt } @Override - public boolean canClose(Project project) { + public boolean canClose(@NotNull Project project) { if (LOG.isDebugEnabled()) { LOG.debug("enter: canClose()"); } @@ -1057,7 +1055,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt private Project myProject; public VirtualFile[] myFiles; - public UnableToSaveProjectNotification(@NotNull final Project project, final VirtualFile[] readOnlyFiles) { + public UnableToSaveProjectNotification(@NotNull final Project project, @NotNull VirtualFile[] readOnlyFiles) { super("Project Settings", "Could not save project", "Unable to save project files. Please ensure project files are writable and you have permissions to modify them." + " Try to save project again.", NotificationType.ERROR, new NotificationListener() { @Override From 9f1cdd1c3ff379ef28f5f7145fb527a3656f3281 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 9 Jun 2015 14:20:32 +0300 Subject: [PATCH 22/38] proper synchronisation, project leak in tests --- .../project/impl/ProjectManagerImpl.java | 14 +++++-- .../intellij/util/containers/MultiMap.java | 41 +++++++++++++++---- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index 26afe010c1e6..0063bf498f3c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -97,7 +97,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt private final Set myTestProjects = new THashSet(); - private final MultiMap> myChangedProjectFiles = MultiMap.createSet(); + private final MultiMap> myChangedProjectFiles = MultiMap.createWeakSet(); //guarded by myChangedProjectFiles private final SingleAlarm myChangedFilesAlarm; private final List> myChangedApplicationFiles = new SmartList>(); private final AtomicInteger myReloadBlockCount = new AtomicInteger(0); @@ -766,7 +766,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt myChangedApplicationFiles.add(Pair.create(file, storage)); } else { - myChangedProjectFiles.putValue(project, Pair.create(file, storage)); + synchronized (myChangedProjectFiles) { + myChangedProjectFiles.putValue(project, Pair.create(file, storage)); + } } if (storage instanceof StateStorageBase) { @@ -780,7 +782,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt @Override public void reloadProject(@NotNull Project project) { - myChangedProjectFiles.remove(project); + synchronized (myChangedProjectFiles) { + myChangedProjectFiles.remove(project); + } doReloadProject(project); } @@ -844,7 +848,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements PersistentSt myTestProjects.remove(project); } - myChangedProjectFiles.remove(project); + synchronized (myChangedProjectFiles) { + myChangedProjectFiles.remove(project); + } fireProjectClosed(project); diff --git a/platform/util/src/com/intellij/util/containers/MultiMap.java b/platform/util/src/com/intellij/util/containers/MultiMap.java index 4bc55fd5cd5e..585ca68901ae 100644 --- a/platform/util/src/com/intellij/util/containers/MultiMap.java +++ b/platform/util/src/com/intellij/util/containers/MultiMap.java @@ -26,9 +26,9 @@ import java.io.Serializable; import java.util.*; /** - * Consider to use factory methods {@link #createLinked()}, {@link #createSet()}, {@link #createSmart()}, {@link #create(gnu.trove.TObjectHashingStrategy)} instead of override. - * @see com.intellij.util.containers.BidirectionalMultiMap - * @see com.intellij.util.containers.ConcurrentMultiMap + * Consider to use factory methods {@link #createLinked()}, {@link #createSet()}, {@link #createSmart()}, {@link #create(TObjectHashingStrategy)} instead of override. + * @see BidirectionalMultiMap + * @see ConcurrentMultiMap * @author Dmitry Avdeev */ public class MultiMap implements Serializable { @@ -52,8 +52,8 @@ public class MultiMap implements Serializable { return new MultiMap(this); } - public MultiMap(int i, float v) { - myMap = createMap(i, v); + public MultiMap(int initialCapacity, float loadFactor) { + myMap = createMap(initialCapacity, loadFactor); } @NotNull @@ -62,7 +62,7 @@ public class MultiMap implements Serializable { } @NotNull - protected Map> createMap(int initialCapacity, float loadFactor) { + protected Map> createMap(int initialCapacity, float loadFactor) { return new HashMap>(initialCapacity, loadFactor); } @@ -249,7 +249,7 @@ public class MultiMap implements Serializable { @NotNull public static MultiMap emptyInstance() { - @SuppressWarnings({"unchecked"}) final MultiMap empty = EMPTY; + @SuppressWarnings("unchecked") final MultiMap empty = EMPTY; return empty; } @@ -355,6 +355,29 @@ public class MultiMap implements Serializable { }; } + @NotNull + public static MultiMap createWeakSet() { + return new MultiMap() { + @NotNull + @Override + protected Collection createCollection() { + return new SmartHashSet(); + } + + @NotNull + @Override + protected Collection createEmptyCollection() { + return Collections.emptySet(); + } + + @NotNull + @Override + protected Map> createMap() { + return new WeakHashMap>(); + } + }; + } + @NotNull public static MultiMap createWeakKey() { return new MultiMap() { @@ -366,8 +389,8 @@ public class MultiMap implements Serializable { }; } - public static MultiMap create(int i, float v) { - return new MultiMap(i, v); + public static MultiMap create(int initialCapacity, float loadFactor) { + return new MultiMap(initialCapacity, loadFactor); } @Override From 10b3cb1eb2a7c9b1163f4f4a952a1135a25614b8 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 9 Jun 2015 18:12:22 +0300 Subject: [PATCH 23/38] project leak in tests --- .../ExternalSystemShortcutsManager.java | 6 +- .../openapi/keymap/KeymapManager.java | 7 ++- .../ui/switcher/QuickAccessSettings.java | 5 +- .../impl/DockableEditorContainerFactory.java | 4 +- .../fileEditor/impl/EditorsSplitters.java | 56 +++++++++---------- .../impl/FileEditorManagerImpl.java | 10 ++-- .../impl/FilePreviewPanelProvider.java | 11 ++-- .../keymap/impl/KeymapManagerImpl.java | 55 +++++++++++------- .../openapi/wm/impl/StripeButton.java | 8 +-- .../wm/impl/ToolWindowManagerImpl.java | 4 +- .../lang/ant/config/explorer/AntExplorer.java | 3 +- .../maven/tasks/MavenShortcutsManager.java | 14 +++-- 12 files changed, 100 insertions(+), 83 deletions(-) diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalSystemShortcutsManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalSystemShortcutsManager.java index e663c92068b0..d91637ea86c2 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalSystemShortcutsManager.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/project/manage/ExternalSystemShortcutsManager.java @@ -102,7 +102,7 @@ public class ExternalSystemShortcutsManager implements Disposable { KeymapManager keymapManager = KeymapManager.getInstance(); if (keymapManager != null) { listenTo(keymapManager.getActiveKeymap()); - keymapManager.addKeymapManagerListener(this); + keymapManager.addKeymapManagerListener(this, ExternalSystemShortcutsManager.this); } } @@ -129,10 +129,6 @@ public class ExternalSystemShortcutsManager implements Disposable { private void stopListen() { listenTo(null); - KeymapManager keymapManager = KeymapManager.getInstance(); - if (keymapManager != null) { - keymapManager.removeKeymapManagerListener(this); - } } } diff --git a/platform/platform-api/src/com/intellij/openapi/keymap/KeymapManager.java b/platform/platform-api/src/com/intellij/openapi/keymap/KeymapManager.java index 26c1b5047b4d..9556115870ae 100644 --- a/platform/platform-api/src/com/intellij/openapi/keymap/KeymapManager.java +++ b/platform/platform-api/src/com/intellij/openapi/keymap/KeymapManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.intellij.openapi.keymap; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -35,7 +36,11 @@ public abstract class KeymapManager { return ApplicationManager.getApplication().getComponent(KeymapManager.class); } + /** + * @deprecated use {@link KeymapManager#addKeymapManagerListener(KeymapManagerListener, Disposable)} instead + */ public abstract void addKeymapManagerListener(@NotNull KeymapManagerListener listener); + public abstract void addKeymapManagerListener(@NotNull KeymapManagerListener listener, @NotNull Disposable parentDisposable); public abstract void removeKeymapManagerListener(@NotNull KeymapManagerListener listener); } diff --git a/platform/platform-api/src/com/intellij/ui/switcher/QuickAccessSettings.java b/platform/platform-api/src/com/intellij/ui/switcher/QuickAccessSettings.java index d53c21379dde..24e980396c14 100644 --- a/platform/platform-api/src/com/intellij/ui/switcher/QuickAccessSettings.java +++ b/platform/platform-api/src/com/intellij/ui/switcher/QuickAccessSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ public class QuickAccessSettings implements ApplicationComponent, KeymapManagerL }, this); KeymapManager kmMgr = KeymapManager.getInstance(); - kmMgr.addKeymapManagerListener(this); + kmMgr.addKeymapManagerListener(this, this); activeKeymapChanged(kmMgr.getActiveKeymap()); @@ -76,7 +76,6 @@ public class QuickAccessSettings implements ApplicationComponent, KeymapManagerL @Override public void disposeComponent() { - KeymapManager.getInstance().removeKeymapManagerListener(this); Disposer.dispose(this); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorContainerFactory.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorContainerFactory.java index e2340d7f1489..ac84e189fd24 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorContainerFactory.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorContainerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFrame; @@ -71,6 +72,7 @@ public class DockableEditorContainerFactory implements DockContainerFactory.Pers splitters.createCurrentWindow(); } final DockableEditorTabbedContainer container = new DockableEditorTabbedContainer(myProject, splitters, true); + Disposer.register(container, splitters); containerRef.set(container); container.getSplitters().startListeningFocus(); return container; diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java index 6e77c7249dec..7e60e7cee0fa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java @@ -18,6 +18,7 @@ package com.intellij.openapi.fileEditor.impl; import com.intellij.ide.IdeBundle; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.components.ServiceManager; @@ -70,7 +71,7 @@ import java.util.concurrent.CopyOnWriteArraySet; /** * Author: msk */ -public class EditorsSplitters extends IdePanePanel implements UISettingsListener { +public class EditorsSplitters extends IdePanePanel implements UISettingsListener, Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.EditorsSplitters"); private static final String PINNED = "pinned"; private static final String CURRENT_IN_TAB = "current-in-tab"; @@ -84,13 +85,12 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener private final FileEditorManagerImpl myManager; private Element mySplittersElement; // temporarily used during initialization - int myInsideChange = 0; + int myInsideChange; private final MyFocusWatcher myFocusWatcher; private final Alarm myIconUpdaterAlarm = new Alarm(); - private final KeymapManagerListener myKeymapListener; private final UIBuilder myUIBuilder = new UIBuilder(); - public EditorsSplitters(final FileEditorManagerImpl manager, DockManager dockManager, boolean createOwnDockableContainer) { + EditorsSplitters(final FileEditorManagerImpl manager, DockManager dockManager, boolean createOwnDockableContainer) { super(new BorderLayout()); myManager = manager; myFocusWatcher = new MyFocusWatcher(); @@ -102,15 +102,15 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener Disposer.register(manager.getProject(), dockable); dockManager.register(dockable); } - myKeymapListener = new KeymapManagerListener() { + KeymapManagerListener keymapListener = new KeymapManagerListener() { @Override public void activeKeymapChanged(Keymap keymap) { invalidate(); repaint(); } }; - KeymapManager.getInstance().addKeymapManagerListener(myKeymapListener); - UISettings.getInstance().addUISettingsListener(this); + KeymapManager.getInstance().addKeymapManagerListener(keymapListener, this); + UISettings.getInstance().addUISettingsListener(this, this); } public FileEditorManagerImpl getManager() { @@ -127,7 +127,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener repaint (); // revalidate doesn't repaint correctly after "Close All" } - public void startListeningFocus() { + void startListeningFocus() { myFocusWatcher.install(this); } @@ -135,11 +135,10 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener myFocusWatcher.deinstall(this); } + @Override public void dispose() { myIconUpdaterAlarm.cancelAllRequests(); stopListeningFocus(); - KeymapManager.getInstance().removeKeymapManagerListener(myKeymapListener); - UISettings.getInstance().removeUISettingsListener(this); } @Nullable @@ -151,7 +150,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } - protected boolean showEmptyText() { + private boolean showEmptyText() { return myCurrentWindow == null || myCurrentWindow.getFiles().length == 0; } @@ -179,7 +178,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } } - @SuppressWarnings({"HardCodedStringLiteral"}) + @SuppressWarnings("HardCodedStringLiteral") private Element writePanel(final JPanel panel) { final Component comp = panel.getComponent(0); if (comp instanceof Splitter) { @@ -315,7 +314,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } @NotNull public VirtualFile[] getOpenFiles() { - final ArrayListSet files = new ArrayListSet(); + final Set files = new ArrayListSet(); for (final EditorWindow myWindow : myWindows) { final EditorWithProviderComposite[] editors = myWindow.getEditors(); for (final EditorWithProviderComposite editor : editors) { @@ -331,7 +330,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } @NotNull public VirtualFile[] getSelectedFiles() { - final ArrayListSet files = new ArrayListSet(); + final Set files = new ArrayListSet(); for (final EditorWindow window : myWindows) { final VirtualFile file = window.getSelectedFile(); if (file != null) { @@ -397,7 +396,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener }, 200, ModalityState.stateForComponent(this)); } - public void updateFileColor(@NotNull final VirtualFile file) { + void updateFileColor(@NotNull final VirtualFile file) { final Collection windows = findWindows(file); for (final EditorWindow window : windows) { final int index = window.findEditorIndex(window.findFileComposite(file)); @@ -420,14 +419,14 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } } - public void setTabLayoutPolicy(int scrollTabLayout) { + void setTabLayoutPolicy(int scrollTabLayout) { final EditorWindow[] windows = getWindows(); for (int i = 0; i != windows.length; ++ i) { windows[i].setTabLayoutPolicy(scrollTabLayout); } } - public void updateFileName(final VirtualFile updatedFile) { + void updateFileName(final VirtualFile updatedFile) { final EditorWindow[] windows = getWindows(); for (int i = 0; i != windows.length; ++ i) { windows [i].updateFileName(updatedFile); @@ -457,7 +456,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener return frame; } - public boolean isInsideChange() { + boolean isInsideChange() { return myInsideChange > 0; } @@ -468,14 +467,14 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener myCurrentWindow = currentWindow; } - public void updateFileBackgroundColor(@NotNull VirtualFile file) { + void updateFileBackgroundColor(@NotNull VirtualFile file) { final EditorWindow[] windows = getWindows(); for (int i = 0; i != windows.length; ++ i) { windows [i].updateFileBackgroundColor(file); } } - public int getSplitCount() { + int getSplitCount() { if (getComponentCount() > 0) { JPanel panel = (JPanel) getComponent(0); return getSplitCount(panel); @@ -502,7 +501,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } @Nullable - public JBTabs getTabsAt(RelativePoint point) { + JBTabs getTabsAt(RelativePoint point) { Point thisPoint = point.getPoint(this); Component c = SwingUtilities.getDeepestComponentAt(this, thisPoint.x, thisPoint.y); while (c != null) { @@ -515,7 +514,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener return null; } - public boolean isEmptyVisible() { + boolean isEmptyVisible() { EditorWindow[] windows = getWindows(); for (EditorWindow each : windows) { if (!each.isEmptyVisible()) { @@ -526,7 +525,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } @Nullable - public VirtualFile findNextFile(final VirtualFile file) { + private VirtualFile findNextFile(final VirtualFile file) { final EditorWindow[] windows = getWindows(); // TODO: use current file as base for (int i = 0; i != windows.length; ++i) { final VirtualFile[] files = windows[i].getFiles(); @@ -618,7 +617,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener return getCurrentWindow(); } - public void createCurrentWindow() { + void createCurrentWindow() { LOG.assertTrue(myCurrentWindow == null); setCurrentWindow(createEditorWindow()); add(myCurrentWindow.myPanel, BorderLayout.CENTER); @@ -634,7 +633,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener * @param window a window to be set as current * @param requestFocus whether to request focus to the editor currently selected in this window */ - public void setCurrentWindow(@Nullable final EditorWindow window, final boolean requestFocus) { + void setCurrentWindow(@Nullable final EditorWindow window, final boolean requestFocus) { final EditorWithProviderComposite newEditor = window == null ? null : window.getSelectedEditor(); Runnable fireRunnable = new Runnable() { @@ -704,7 +703,7 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener } @NotNull - public List findWindows(final VirtualFile file) { + private List findWindows(final VirtualFile file) { List res = new ArrayList(); for (final EditorWindow window : myWindows) { if (window.findFileComposite(file) != null) { @@ -718,12 +717,13 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener return myWindows.toArray(new EditorWindow [myWindows.size()]); } - @NotNull public EditorWindow[] getOrderedWindows() { + @NotNull + EditorWindow[] getOrderedWindows() { final List res = new ArrayList(); // Collector for windows in tree ordering: class Inner{ - final void collect(final JPanel panel){ + private final void collect(final JPanel panel){ final Component comp = panel.getComponent(0); if (comp instanceof Splitter) { final Splitter splitter = (Splitter)comp; diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java index cb38ec244ddc..6e5a1215fb0f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java @@ -122,7 +122,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec /** * Removes invalid myEditor and updates "modified" status. */ - private final MyEditorPropertyChangeListener myEditorPropertyChangeListener = new MyEditorPropertyChangeListener(); + private final PropertyChangeListener myEditorPropertyChangeListener = new MyEditorPropertyChangeListener(); private final DockManager myDockManager; private DockableEditorContainerFactory myContentFactory; private final EditorHistoryManager myEditorHistoryManager; @@ -288,6 +288,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec panel.setOpaque(false); panel.setBorder(new MyBorder()); mySplitters = new EditorsSplitters(this, myDockManager, true); + Disposer.register(myProject, mySplitters); panel.add(mySplitters, BorderLayout.CENTER); myPanels = panel; } @@ -1511,11 +1512,8 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec @Override public void projectClosed() { - //myFocusWatcher.deinstall(myWindows.getComponent ()); - getMainSplitters().dispose(); - -// Dispose created editors. We do not use use closeEditor method because -// it fires event and changes history. + // Dispose created editors. We do not use use closeEditor method because + // it fires event and changes history. closeAllFiles(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FilePreviewPanelProvider.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FilePreviewPanelProvider.java index 258dbdba72d6..ac569d75b691 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FilePreviewPanelProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FilePreviewPanelProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.intellij.openapi.preview.PreviewPanelProvider; import com.intellij.openapi.preview.PreviewProviderId; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; @@ -38,14 +39,15 @@ public class FilePreviewPanelProvider extends PreviewPanelProvider() { - @NotNull - @Override - public KeymapImpl readScheme(@NotNull Element element) throws InvalidDataException { - KeymapImpl keymap = new KeymapImpl(); - keymap.readExternal(element, getAllIncludingDefaultsKeymaps()); - return keymap; - } + BaseSchemeProcessor schemeProcessor = new BaseSchemeProcessor() { + @NotNull + @Override + public KeymapImpl readScheme(@NotNull Element element) throws InvalidDataException { + KeymapImpl keymap = new KeymapImpl(); + keymap.readExternal(element, getAllIncludingDefaultsKeymaps()); + return keymap; + } - @Override - public Element writeScheme(@NotNull final KeymapImpl scheme) { - return scheme.writeExternal(); - } + @Override + public Element writeScheme(@NotNull final KeymapImpl scheme) { + return scheme.writeExternal(); + } - @NotNull - @Override - public State getState(@NotNull KeymapImpl scheme) { - return scheme.canModify() ? State.POSSIBLY_CHANGED : State.NON_PERSISTENT; - } - }, - RoamingType.PER_USER); + @NotNull + @Override + public State getState(@NotNull KeymapImpl scheme) { + return scheme.canModify() ? State.POSSIBLY_CHANGED : State.NON_PERSISTENT; + } + }; + mySchemesManager = factory.createSchemesManager(KEYMAPS_DIR_PATH, schemeProcessor, RoamingType.PER_USER); Keymap[] keymaps = defaultKeymap.getKeymaps(); String systemDefaultKeymap = WelcomeWizardUtil.getWizardMacKeymap() != null @@ -231,6 +232,18 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat myListeners.add(listener); } + @Override + public void addKeymapManagerListener(@NotNull final KeymapManagerListener listener, @NotNull Disposable parentDisposable) { + pollQueue(); + myListeners.add(listener); + Disposer.register(parentDisposable, new Disposable() { + @Override + public void dispose() { + removeKeymapManagerListener(listener); + } + }); + } + private void pollQueue() { // assume it is safe to remove elements during iteration, as is the case with the COWAL for (KeymapManagerListener listener : myListeners) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java index f199e2a79525..c40d8dc6a0c7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/StripeButton.java @@ -18,6 +18,7 @@ package com.intellij.openapi.wm.impl; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.actions.ActivateToolWindowAction; import com.intellij.ide.ui.UISettings; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.ActionPlaces; @@ -46,7 +47,7 @@ import java.awt.image.BufferedImage; * @author Eugene Belyaev * @author Vladimir Kondratyev */ -public final class StripeButton extends AnchoredButton implements ActionListener { +public final class StripeButton extends AnchoredButton implements ActionListener, Disposable { private final Color ourBackgroundColor = new Color(247, 243, 239); /** @@ -125,7 +126,7 @@ public final class StripeButton extends AnchoredButton implements ActionListener processDrag(e); } }); - KeymapManager.getInstance().addKeymapManagerListener(myKeymapListener); + KeymapManager.getInstance().addKeymapManagerListener(myKeymapListener, this); } @@ -302,8 +303,7 @@ public final class StripeButton extends AnchoredButton implements ActionListener setSelected(info.isVisible() || info.isActive()); } - void dispose() { - KeymapManager.getInstance().removeKeymapManagerListener(myKeymapListener); + public void dispose() { } private void showPopup(final Component component, final int x, final int y) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java index 630816079561..c615417e5413 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1295,7 +1295,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements mySideStack.remove(id); // Destroy stripe button final StripeButton button = getStripeButton(id); - button.dispose(); + Disposer.dispose(button); myId2StripeButton.remove(id); // ToolWindowFocusWatcher watcher = (ToolWindowFocusWatcher)myId2FocusWatcher.remove(id); diff --git a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java index 3ad663b5f6ac..1956fbd7d6c0 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java @@ -890,7 +890,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, final KeymapManagerEx keymapManager = KeymapManagerEx.getInstanceEx(); final Keymap activeKeymap = keymapManager.getActiveKeymap(); listenTo(activeKeymap); - keymapManager.addKeymapManagerListener(this); + keymapManager.addKeymapManagerListener(this, AntExplorer.this); } public void activeKeymapChanged(Keymap keymap) { @@ -918,7 +918,6 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, public void stopListen() { listenTo(null); - KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(this); } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenShortcutsManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenShortcutsManager.java index 357bd87bb1b9..33515005fc9f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenShortcutsManager.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/tasks/MavenShortcutsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,12 +15,12 @@ */ package org.jetbrains.idea.maven.tasks; +import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.KeymapManagerListener; import com.intellij.openapi.keymap.KeymapUtil; -import com.intellij.openapi.keymap.ex.KeymapManagerEx; import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; @@ -49,7 +49,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -public class MavenShortcutsManager extends MavenSimpleProjectComponent { +public class MavenShortcutsManager extends MavenSimpleProjectComponent implements Disposable { private static final String ACTION_ID_PREFIX = "Maven_"; private final AtomicBoolean isInitialized = new AtomicBoolean(); @@ -69,6 +69,11 @@ public class MavenShortcutsManager extends MavenSimpleProjectComponent { myProjectsManager = projectsManager; } + @Override + public void dispose() { + + } + @Override public void initComponent() { if (!isNormalProject()) return; @@ -147,7 +152,7 @@ public class MavenShortcutsManager extends MavenSimpleProjectComponent { public MyKeymapListener() { KeymapManager keymapManager = KeymapManager.getInstance(); listenTo(keymapManager.getActiveKeymap()); - keymapManager.addKeymapManagerListener(this); + keymapManager.addKeymapManagerListener(this, MavenShortcutsManager.this); } @Override @@ -173,7 +178,6 @@ public class MavenShortcutsManager extends MavenSimpleProjectComponent { public void stopListen() { listenTo(null); - KeymapManagerEx.getInstanceEx().removeKeymapManagerListener(this); } } From ea18c27420039a7ebee7551a82a2d7a6a902b0aa Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 9 Jun 2015 18:16:23 +0300 Subject: [PATCH 24/38] optimisation: reduce volatile reads to one down from three --- .../openapi/progress/impl/CoreProgressManager.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/progress/impl/CoreProgressManager.java b/platform/core-impl/src/com/intellij/openapi/progress/impl/CoreProgressManager.java index 3bfde5b825e9..f32466655ba6 100644 --- a/platform/core-impl/src/com/intellij/openapi/progress/impl/CoreProgressManager.java +++ b/platform/core-impl/src/com/intellij/openapi/progress/impl/CoreProgressManager.java @@ -55,12 +55,13 @@ public class CoreProgressManager extends ProgressManager implements Disposable { private static final boolean ENABLED = !"disabled".equals(System.getProperty("idea.ProcessCanceledException")); private final ScheduledFuture myCheckCancelledFuture; - // indicator -> threads which are running under this indicator. guarded by this. + // indicator -> threads which are running under this indicator. guarded by threadsUnderIndicator. private static final Map> threadsUnderIndicator = new THashMap>(); // the active indicator for the thread id private static final ConcurrentLongObjectMap currentIndicators = ContainerUtil.createConcurrentLongObjectMap(); // threads which are running under canceled indicator static final Set threadsUnderCanceledIndicator = ContainerUtil.newConcurrentSet(); + private static volatile boolean thereIsProcessUnderCanceledIndicator; // active (i.e. which have executeProcessUnderProgress() method running) indicators which are not inherited from StandardProgressIndicator. // for them an extra processing thread (see myCheckCancelledFuture) has to be run to call their non-standard checkCanceled() method @@ -89,8 +90,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable { @Override protected void doCheckCanceled() throws ProcessCanceledException { - boolean thereIsCanceledIndicator = !threadsUnderCanceledIndicator.isEmpty(); - if (thereIsCanceledIndicator) { + if (thereIsProcessUnderCanceledIndicator) { final ProgressIndicator progress = getProgressIndicator(); if (progress != null && ENABLED) { progress.checkCanceled(); @@ -421,6 +421,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable { else { threadsUnderCanceledIndicator.remove(currentThread); } + thereIsProcessUnderCanceledIndicator = !threadsUnderCanceledIndicator.isEmpty(); } try { @@ -449,6 +450,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable { else { threadsUnderCanceledIndicator.remove(currentThread); } + thereIsProcessUnderCanceledIndicator = !threadsUnderCanceledIndicator.isEmpty(); } } } @@ -473,6 +475,7 @@ public class CoreProgressManager extends ProgressManager implements Disposable { if (underCancelledIndicator) { threadsUnderCanceledIndicator.add(thread); + thereIsProcessUnderCanceledIndicator = true; } } } From efeb58c62e7e1eb5f017860a50bc58573b4cb668 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 9 Jun 2015 20:21:25 +0300 Subject: [PATCH 25/38] cleanup --- .../src/com/intellij/psi/impl/PsiDocumentManagerBase.java | 6 +++--- .../openapi/editor/event/EditorFactoryListener.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java index c82be8e1b8f3..f8f9ae914f53 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -362,7 +362,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen } } - protected void doCommit(@NotNull final Document document) { + private void doCommit(@NotNull final Document document) { assert !myIsCommitInProgress : "Do not call commitDocument() from inside PSI change listener"; ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override @@ -782,7 +782,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen } char[] fileText = psiFile.textToCharArray(); - @SuppressWarnings({"NonConstantStringShouldBeStringBuffer"}) + @SuppressWarnings("NonConstantStringShouldBeStringBuffer") @NonNls String error = "File '" + psiFile.getName() + "' text mismatch after reparse. " + "File length=" + fileText.length + "; Doc length=" + documentLength + "\n"; int i = 0; diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java index 1d8ddcc2930b..2418a5e6f53a 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/event/EditorFactoryListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull; import java.util.EventListener; /** - * @see {@link com.intellij.openapi.editor.EditorFactory#addEditorFactoryListener(com.intellij.openapi.editor.event.EditorFactoryListener, com.intellij.openapi.Disposable)} + * @see {@link com.intellij.openapi.editor.EditorFactory#addEditorFactoryListener(EditorFactoryListener, com.intellij.openapi.Disposable)} */ public interface EditorFactoryListener extends EventListener { /** From 6f9a0ae6fa9d10e82f43923f660ce270fec64851 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 10 Jun 2015 13:32:12 +0300 Subject: [PATCH 26/38] properties files: don't evaluate base name for files which are not properties files --- .../lang/properties/PropertiesImplUtil.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java index 00feb42ba56e..a61509234792 100644 --- a/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java +++ b/plugins/properties/properties-psi-impl/src/com/intellij/lang/properties/PropertiesImplUtil.java @@ -84,19 +84,20 @@ public class PropertiesImplUtil extends PropertiesUtil { } }); for (final PsiFile psiFile : psiFiles) { + final PropertiesFile propertiesFile = getPropertiesFile(psiFile); + if (propertiesFile == null) { + continue; + } if (baseName.equals(bundleBaseNameManager.getBaseName(psiFile))) { - final PropertiesFile propertiesFile = getPropertiesFile(psiFile); - if (propertiesFile != null) { - if (defaultPropertiesFile == null) { + if (defaultPropertiesFile == null) { + defaultPropertiesFile = propertiesFile; + } else { + final int nameDiff = FileUtil.getNameWithoutExtension(defaultPropertiesFile.getName()).compareTo(FileUtil.getNameWithoutExtension(propertiesFile.getName())); + if (nameDiff > 0) { defaultPropertiesFile = propertiesFile; - } else { - final int nameDiff = FileUtil.getNameWithoutExtension(defaultPropertiesFile.getName()).compareTo(FileUtil.getNameWithoutExtension(propertiesFile.getName())); - if (nameDiff > 0) { - defaultPropertiesFile = propertiesFile; - } else if (nameDiff == 0) { - //means 2 default properties files - return null; - } + } else if (nameDiff == 0) { + //means 2 default properties files + return null; } } } From 1bd5d24e6fc886414a110c068a6d449fa9b23ced Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 10 Jun 2015 11:57:26 +0200 Subject: [PATCH 27/38] Don't try to map code fragment to source name. Often, sourcemaps is not detailed - token is not mapped to token, so, it is not easy to extract identifier from code fragment So, if source map doesn't provide name mappings, we assume that names are not mangled. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GWT mangles name (https://code.google.com/p/google-web-toolkit/issues/detail?id=9106 https://github.com/sdbg/sdbg/issues/6 https://youtrack.jetbrains.com/issue/IDEA-135356), but doesn't add name mappings. So, in this case we implement custom normalize member name. Fix isInLibraryContent (CallFrameView uses it to select appropriate font color) — we must use source file to check, but not script file. IDEA-135094 gwt: support name mappings IDEA-135356 Local variable does not appear in variables list during debug --- .../debugger/JavaScriptDebugAware.java | 23 ++++++++++++++ .../org/jetbrains/debugger/MemberFilter.java | 2 +- .../jetbrains/debugger/MemberFilterBase.java | 2 +- .../MemberFilterWithNameMappings.java | 31 ++++++++++++++++--- .../org/jetbrains/debugger/VariableView.java | 2 +- .../src/org/jetbrains/debugger/Variables.java | 6 ++-- .../debugger/frame/CallFrameView.java | 20 ++++++++++-- 7 files changed, 72 insertions(+), 14 deletions(-) diff --git a/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/JavaScriptDebugAware.java b/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/JavaScriptDebugAware.java index 51eb3dac88b4..b93fb8cf1eb9 100644 --- a/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/JavaScriptDebugAware.java +++ b/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/JavaScriptDebugAware.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.jetbrains.javascript.debugger; import com.intellij.openapi.editor.Document; @@ -71,4 +86,12 @@ public abstract class JavaScriptDebugAware { public PsiElement getNavigationElementForSourcemapInspector(@NotNull PsiFile file) { return null; } + + @Nullable + // return null if unsupported + // cannot be in MemberFilter because creation of MemberFilter could be async + // the problem - GWT mangles name (https://code.google.com/p/google-web-toolkit/issues/detail?id=9106 https://github.com/sdbg/sdbg/issues/6 https://youtrack.jetbrains.com/issue/IDEA-135356), but doesn't add name mappings + public String normalizeMemberName(@NotNull String name) { + return null; + } } \ No newline at end of file diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilter.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilter.java index b25d555d465c..242eef57f613 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilter.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilter.java @@ -27,7 +27,7 @@ public interface MemberFilter { Collection getAdditionalVariables(); @NotNull - String getName(@NotNull Variable variable); + String rawNameToSource(@NotNull Variable variable); @Nullable String sourceNameToRaw(@NotNull String name); diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterBase.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterBase.java index 27ca585710ab..8b9189bf1b02 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterBase.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterBase.java @@ -40,7 +40,7 @@ public abstract class MemberFilterBase implements MemberFilter { @NotNull @Override - public String getName(@NotNull Variable variable) { + public String rawNameToSource(@NotNull Variable variable) { return variable.getName(); } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterWithNameMappings.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterWithNameMappings.java index 5d97eeaebfa8..06bd32a6c1bd 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterWithNameMappings.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/MemberFilterWithNameMappings.java @@ -1,16 +1,31 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.jetbrains.debugger; -import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.Map; public class MemberFilterWithNameMappings extends MemberFilterBase { protected final Map rawNameToSource; - public MemberFilterWithNameMappings(@NotNull Map rawNameToSource) { - this.rawNameToSource = rawNameToSource; + public MemberFilterWithNameMappings(@Nullable Map rawNameToSource) { + this.rawNameToSource = rawNameToSource == null ? Collections.emptyMap() : rawNameToSource; } @Override @@ -20,9 +35,15 @@ public class MemberFilterWithNameMappings extends MemberFilterBase { @NotNull @Override - public String getName(@NotNull Variable variable) { + public String rawNameToSource(@NotNull Variable variable) { String name = variable.getName(); - return ObjectUtils.chooseNotNull(sourceNameToRaw(name), name); + String sourceName = rawNameToSource.get(name); + return sourceName == null ? normalizeMemberName(name) : sourceName; + } + + @NotNull + protected String normalizeMemberName(@NotNull String name) { + return name; } @Nullable diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java index e6462e61cce5..c95a0b34c16d 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java @@ -468,7 +468,7 @@ public final class VariableView extends XNamedValue implements VariableContext { for (int i = notGroupedVariablesOffset; i < variables.size(); i++) { Variable variable = variables.get(i); - groupList.add(new VariableView(memberFilter.getName(variable), variable, this)); + groupList.add(new VariableView(memberFilter.rawNameToSource(variable), variable, this)); } node.addChildren(groupList, true); diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.java index ad38b972d3b6..fa64b11a604f 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/Variables.java @@ -97,7 +97,7 @@ public final class Variables { Comparator comparator = memberFilter.hasNameMappings() ? new Comparator() { @Override public int compare(@NotNull Variable o1, @NotNull Variable o2) { - return naturalCompare(memberFilter.getName(o1), memberFilter.getName(o2)); + return naturalCompare(memberFilter.rawNameToSource(o1), memberFilter.rawNameToSource(o2)); } } : NATURAL_NAME_COMPARATOR; @@ -172,7 +172,7 @@ public final class Variables { @NotNull MemberFilter memberFilter) { ol: for (Variable variable : additionalVariables) { for (Variable frameVariable : variables) { - if (memberFilter.getName(frameVariable).equals(memberFilter.getName(variable))) { + if (memberFilter.rawNameToSource(frameVariable).equals(memberFilter.rawNameToSource(variable))) { continue ol; } } @@ -280,7 +280,7 @@ public final class Variables { VariableContext getterOrSetterContext = null; for (int i = from; i < to; i++) { Variable variable = variables.get(i); - String normalizedName = memberFilter == null ? variable.getName() : memberFilter.getName(variable); + String normalizedName = memberFilter == null ? variable.getName() : memberFilter.rawNameToSource(variable); list.add(new VariableView(normalizedName, variable, variableContext)); if (variable instanceof ObjectProperty) { ObjectProperty property = (ObjectProperty)variable; diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/frame/CallFrameView.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/frame/CallFrameView.java index 05c849709c47..6a123e80bade 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/frame/CallFrameView.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/frame/CallFrameView.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.jetbrains.debugger.frame; import com.intellij.icons.AllIcons; @@ -132,8 +147,7 @@ public final class CallFrameView extends XStackFrame implements VariableContext String fileName = sourceInfo.getFile().getName(); int line = sourceInfo.getLine() + 1; - boolean isInLibraryContent = inLibraryContent; - SimpleTextAttributes textAttributes = isInLibraryContent ? SimpleTextAttributes.GRAYED_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES; + SimpleTextAttributes textAttributes = inLibraryContent ? SimpleTextAttributes.GRAYED_ATTRIBUTES : SimpleTextAttributes.REGULAR_ATTRIBUTES; String functionName = sourceInfo.getFunctionName(); if (functionName == null || (functionName.isEmpty() && callFrame.hasOnlyGlobalScope())) { @@ -141,7 +155,7 @@ public final class CallFrameView extends XStackFrame implements VariableContext } else { if (functionName.isEmpty()) { - component.append("anonymous", isInLibraryContent ? SimpleTextAttributes.GRAYED_ITALIC_ATTRIBUTES : SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES); + component.append("anonymous", inLibraryContent ? SimpleTextAttributes.GRAYED_ITALIC_ATTRIBUTES : SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES); } else { component.append(functionName, textAttributes); From 2cbb5f6091922fa69df13fe329e3503882327091 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 10 Jun 2015 13:38:49 +0300 Subject: [PATCH 28/38] testng inspection to check data providers --- plugins/testng/src/META-INF/plugin.xml | 3 + .../testng/DataProviderReference.java | 92 ++++++++++++++++ .../testng/TestNGReferenceContributor.java | 75 ------------- .../TestNGDataProviderInspection.java | 103 ++++++++++++++++++ .../testng/util/TestNGUtil.java | 16 +++ .../TestNGDataProvider.html | 3 + .../InstanceDataProviderFromForeignClass.java | 10 ++ .../dataProvider/MissedDataProvider.java | 5 + .../TestNGDataProviderInspectionTest.java | 49 +++++++++ 9 files changed, 281 insertions(+), 75 deletions(-) create mode 100644 plugins/testng/src/com/theoryinpractice/testng/DataProviderReference.java create mode 100644 plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGDataProviderInspection.java create mode 100644 plugins/testng/src/inspectionDescriptions/TestNGDataProvider.html create mode 100644 plugins/testng/testData/inspection/dataProvider/InstanceDataProviderFromForeignClass.java create mode 100644 plugins/testng/testData/inspection/dataProvider/MissedDataProvider.java create mode 100644 plugins/testng/testSources/com/theoryinpractice/testng/inspection/TestNGDataProviderInspectionTest.java diff --git a/plugins/testng/src/META-INF/plugin.xml b/plugins/testng/src/META-INF/plugin.xml index f274424eab5f..4a0c38fa8489 100644 --- a/plugins/testng/src/META-INF/plugin.xml +++ b/plugins/testng/src/META-INF/plugin.xml @@ -70,6 +70,9 @@ + diff --git a/plugins/testng/src/com/theoryinpractice/testng/DataProviderReference.java b/plugins/testng/src/com/theoryinpractice/testng/DataProviderReference.java new file mode 100644 index 000000000000..eb2eb8a297b4 --- /dev/null +++ b/plugins/testng/src/com/theoryinpractice/testng/DataProviderReference.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.theoryinpractice.testng; + +import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.lookup.LookupValueFactory; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.theoryinpractice.testng.util.TestNGUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.testng.annotations.DataProvider; + +import java.util.ArrayList; +import java.util.List; + +public class DataProviderReference extends PsiReferenceBase { + + public DataProviderReference(PsiLiteral element) { + super(element, false); + } + + @Nullable + public PsiElement resolve() { + final PsiClass cls = TestNGUtil.getProviderClass(getElement(), PsiUtil.getTopLevelClass(getElement())); + if (cls != null) { + PsiMethod[] methods = cls.getAllMethods(); + @NonNls String val = getValue(); + for (PsiMethod method : methods) { + PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName()); + if (dataProviderAnnotation != null) { + final PsiAnnotationMemberValue dataProviderMethodName = dataProviderAnnotation.findDeclaredAttributeValue("name"); + if (dataProviderMethodName != null && val.equals(StringUtil.unquoteString(dataProviderMethodName.getText()))) { + return method; + } + if (val.equals(method.getName())) { + return method; + } + } + } + } + return null; + } + + @NotNull + public Object[] getVariants() { + final List list = new ArrayList(); + final PsiClass topLevelClass = PsiUtil.getTopLevelClass(getElement()); + final PsiClass cls = TestNGUtil.getProviderClass(getElement(), topLevelClass); + final boolean needToBeStatic = cls != topLevelClass; + if (cls != null) { + final PsiMethod current = PsiTreeUtil.getParentOfType(getElement(), PsiMethod.class); + final PsiMethod[] methods = cls.getAllMethods(); + for (PsiMethod method : methods) { + if (current != null && method.getName().equals(current.getName())) continue; + if (needToBeStatic) { + if (!method.hasModifierProperty(PsiModifier.STATIC)) continue; + } else { + if (cls != method.getContainingClass() && method.hasModifierProperty(PsiModifier.PRIVATE)) continue; + } + final PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName()); + if (dataProviderAnnotation != null) { + final PsiAnnotationMemberValue memberValue = dataProviderAnnotation.findDeclaredAttributeValue("name"); + if (memberValue != null) { + list.add(LookupValueFactory.createLookupValue(StringUtil.unquoteString(memberValue.getText()), null)); + } else { + list.add(LookupValueFactory.createLookupValue(method.getName(), null)); + } + } + } + } + return list.toArray(); + } + + +} diff --git a/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java b/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java index 74bb548fcbbf..90d0873be630 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java +++ b/plugins/testng/src/com/theoryinpractice/testng/TestNGReferenceContributor.java @@ -44,7 +44,6 @@ import com.theoryinpractice.testng.util.TestNGUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.testng.annotations.DataProvider; import java.util.ArrayList; import java.util.List; @@ -82,80 +81,6 @@ public class TestNGReferenceContributor extends PsiReferenceContributor { }); } - private static class DataProviderReference extends PsiReferenceBase { - - public DataProviderReference(PsiLiteral element) { - super(element, false); - } - - @Nullable - public PsiElement resolve() { - final PsiClass cls = getProviderClass(PsiUtil.getTopLevelClass(getElement())); - if (cls != null) { - PsiMethod[] methods = cls.getAllMethods(); - @NonNls String val = getValue(); - for (PsiMethod method : methods) { - PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName()); - if (dataProviderAnnotation != null) { - final PsiAnnotationMemberValue dataProviderMethodName = dataProviderAnnotation.findDeclaredAttributeValue("name"); - if (dataProviderMethodName != null && val.equals(StringUtil.unquoteString(dataProviderMethodName.getText()))) { - return method; - } - if (val.equals(method.getName())) { - return method; - } - } - } - } - return null; - } - - @NotNull - public Object[] getVariants() { - final List list = new ArrayList(); - final PsiClass topLevelClass = PsiUtil.getTopLevelClass(getElement()); - final PsiClass cls = getProviderClass(topLevelClass); - final boolean needToBeStatic = cls != topLevelClass; - if (cls != null) { - final PsiMethod current = PsiTreeUtil.getParentOfType(getElement(), PsiMethod.class); - final PsiMethod[] methods = cls.getAllMethods(); - for (PsiMethod method : methods) { - if (current != null && method.getName().equals(current.getName())) continue; - if (needToBeStatic) { - if (!method.hasModifierProperty(PsiModifier.STATIC)) continue; - } else { - if (cls != method.getContainingClass() && method.hasModifierProperty(PsiModifier.PRIVATE)) continue; - } - final PsiAnnotation dataProviderAnnotation = AnnotationUtil.findAnnotation(method, DataProvider.class.getName()); - if (dataProviderAnnotation != null) { - final PsiAnnotationMemberValue memberValue = dataProviderAnnotation.findDeclaredAttributeValue("name"); - if (memberValue != null) { - list.add(LookupValueFactory.createLookupValue(StringUtil.unquoteString(memberValue.getText()), null)); - } else { - list.add(LookupValueFactory.createLookupValue(method.getName(), null)); - } - } - } - } - return list.toArray(); - } - - private PsiClass getProviderClass(final PsiClass topLevelClass) { - final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(getElement(), PsiAnnotation.class); - if (annotation != null) { - final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dataProviderClass"); - if (value instanceof PsiClassObjectAccessExpression) { - final PsiTypeElement operand = ((PsiClassObjectAccessExpression)value).getOperand(); - final PsiClass psiClass = PsiUtil.resolveClassInType(operand.getType()); - if (psiClass != null) { - return psiClass; - } - } - } - return topLevelClass; - } - } - private static class MethodReference extends PsiReferenceBase { public MethodReference(PsiLiteral element) { diff --git a/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGDataProviderInspection.java b/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGDataProviderInspection.java new file mode 100644 index 000000000000..ed21b1a86fdd --- /dev/null +++ b/plugins/testng/src/com/theoryinpractice/testng/inspection/TestNGDataProviderInspection.java @@ -0,0 +1,103 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.theoryinpractice.testng.inspection; + +import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodQuickFix; +import com.intellij.codeInspection.BaseJavaLocalInspectionTool; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateDescriptor; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.theoryinpractice.testng.DataProviderReference; +import com.theoryinpractice.testng.TestNGFramework; +import com.theoryinpractice.testng.util.TestNGUtil; +import org.jetbrains.annotations.NotNull; +import org.testng.annotations.DataProvider; + +import java.io.IOException; +import java.util.Properties; + +public class TestNGDataProviderInspection extends BaseJavaLocalInspectionTool { + + @NotNull + @Override + public PsiElementVisitor buildVisitor(final @NotNull ProblemsHolder holder, final boolean isOnTheFly) { + return new JavaElementVisitor() { + @Override + public void visitAnnotation(PsiAnnotation annotation) { + if (TestNGUtil.TEST_ANNOTATION_FQN.equals(annotation.getQualifiedName())) { + final PsiAnnotationMemberValue provider = annotation.findDeclaredAttributeValue("dataProvider"); + if (provider != null && !TestNGUtil.isDisabled(annotation)) { + for (PsiReference reference : provider.getReferences()) { + if (reference instanceof DataProviderReference) { + final PsiElement dataProviderMethod = reference.resolve(); + final PsiElement element = reference.getElement(); + final PsiClass topLevelClass = PsiUtil.getTopLevelClass(element); + final PsiClass providerClass = TestNGUtil.getProviderClass(element, topLevelClass); + if (!(dataProviderMethod instanceof PsiMethod)) { + final LocalQuickFix[] fixes; + if (isOnTheFly) { + fixes = new LocalQuickFix[] {createMethodFix(provider, providerClass, topLevelClass)}; + } + else { + fixes = LocalQuickFix.EMPTY_ARRAY; + } + + holder.registerProblem(provider, "Data provider does not exist", fixes); + } else { + final PsiMethod providerMethod = (PsiMethod)dataProviderMethod; + if (providerClass != topLevelClass && !providerMethod.hasModifierProperty(PsiModifier.STATIC)) { + holder.registerProblem(provider, "Data provider from foreign class need to be static"); + } + } + break; + } + } + } + } + } + }; + } + + private static CreateMethodQuickFix createMethodFix(PsiAnnotationMemberValue provider, PsiClass providerClass, PsiClass topLevelClass) { + + FileTemplateDescriptor templateDesc = new TestNGFramework().getParametersMethodFileTemplateDescriptor(); + assert templateDesc != null; + final FileTemplate fileTemplate = FileTemplateManager.getInstance(provider.getProject()).getCodeTemplate(templateDesc.getFileName()); + + String body = ""; + try { + body = fileTemplate.getText(new Properties()); + body = body.replace("${BODY}", ""); + } + catch (IOException ignored) {} + if (StringUtil.isEmptyOrSpaces(body)) { + body = "return new Object[][]{};"; + } + + String signature = "@" + DataProvider.class.getName() + " public "; + if (providerClass == topLevelClass) { + signature += "static "; + } + signature += "Object[][] " + StringUtil.unquoteString(provider.getText()) + "()"; + + return CreateMethodQuickFix.createFix(providerClass, signature, body); + } +} diff --git a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java index a0dae9b674f6..9b3d84080df8 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java +++ b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java @@ -36,6 +36,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.AllClassesSearch; import com.intellij.psi.util.PsiElementFilter; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xml.NanoXmlUtil; @@ -545,4 +546,19 @@ public class TestNGUtil { } return false; } + + public static PsiClass getProviderClass(final PsiElement element, final PsiClass topLevelClass) { + final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(element, PsiAnnotation.class); + if (annotation != null) { + final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dataProviderClass"); + if (value instanceof PsiClassObjectAccessExpression) { + final PsiTypeElement operand = ((PsiClassObjectAccessExpression)value).getOperand(); + final PsiClass psiClass = PsiUtil.resolveClassInType(operand.getType()); + if (psiClass != null) { + return psiClass; + } + } + } + return topLevelClass; + } } diff --git a/plugins/testng/src/inspectionDescriptions/TestNGDataProvider.html b/plugins/testng/src/inspectionDescriptions/TestNGDataProvider.html new file mode 100644 index 000000000000..959e9530188f --- /dev/null +++ b/plugins/testng/src/inspectionDescriptions/TestNGDataProvider.html @@ -0,0 +1,3 @@ + +This inspection checks that data provider method exists and is accessible. + \ No newline at end of file diff --git a/plugins/testng/testData/inspection/dataProvider/InstanceDataProviderFromForeignClass.java b/plugins/testng/testData/inspection/dataProvider/InstanceDataProviderFromForeignClass.java new file mode 100644 index 000000000000..faa7537dc5b3 --- /dev/null +++ b/plugins/testng/testData/inspection/dataProvider/InstanceDataProviderFromForeignClass.java @@ -0,0 +1,10 @@ +public class InstanceDataProviderFromForeignClass { + @org.testng.annotations.Test(dataProvider = "data", dataProviderClass = A.class) + public void test() { + } +} + +class A { + @org.testng.annotations.DataProvider + public Object[][] data () {return null;} +} \ No newline at end of file diff --git a/plugins/testng/testData/inspection/dataProvider/MissedDataProvider.java b/plugins/testng/testData/inspection/dataProvider/MissedDataProvider.java new file mode 100644 index 000000000000..d74c762c0069 --- /dev/null +++ b/plugins/testng/testData/inspection/dataProvider/MissedDataProvider.java @@ -0,0 +1,5 @@ +public class MissedDataProvider { + @org.testng.annotations.Test(dataProvider = "data") + public void test() { + } +} \ No newline at end of file diff --git a/plugins/testng/testSources/com/theoryinpractice/testng/inspection/TestNGDataProviderInspectionTest.java b/plugins/testng/testSources/com/theoryinpractice/testng/inspection/TestNGDataProviderInspectionTest.java new file mode 100644 index 000000000000..b282f3a57717 --- /dev/null +++ b/plugins/testng/testSources/com/theoryinpractice/testng/inspection/TestNGDataProviderInspectionTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.theoryinpractice.testng.inspection; + +import com.intellij.openapi.application.PluginPathManager; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.annotations.NotNull; + +public class TestNGDataProviderInspectionTest extends LightCodeInsightFixtureTestCase { + public void testMissedDataProvider() throws Exception { + + myFixture.testHighlighting(true, false, false, "MissedDataProvider.java"); + } + + public void testInstanceDataProviderFromForeignClass() throws Exception { + myFixture.testHighlighting(true, false, false, "InstanceDataProviderFromForeignClass.java"); + } + + @NotNull + @Override + protected String getTestDataPath() { + return PluginPathManager.getPluginHomePath("testng") + "/testData/inspection/dataProvider/"; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + myFixture.addClass("package org.testng.annotations;\n" + + "public @interface DataProvider {}"); + myFixture.addClass("package org.testng.annotations;\n" + + "public @interface Test { java.lang.String dataProvider() default {};" + + " Class dataProviderClass() default {};" + + "}"); + myFixture.enableInspections(new TestNGDataProviderInspection()); + } +} From faa8cd173938f2f3a58bba010459165cc6502c11 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 10 Jun 2015 14:45:04 +0300 Subject: [PATCH 29/38] javac quirks: change according to javac version instead of language level (IDEA-141312) --- .../compiler/JavacQuirksInspectionVisitor.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java index d120fd80411f..92cbca249a75 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java @@ -19,6 +19,8 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.codeInspection.InspectionsBundle; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.JavaVersionService; import com.intellij.patterns.ElementPattern; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; @@ -70,11 +72,11 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor { @Override public void visitIdentifier(PsiIdentifier identifier) { super.visitIdentifier(identifier); - final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(identifier); - if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { + final JavaSdkVersion version = JavaVersionService.getInstance().getJavaSdkVersion(identifier); + if (version != null && version.isAtLeast(JavaSdkVersion.JDK_1_8)) { if ("_".equals(identifier.getText())) { myHolder.registerProblem(identifier, JavaErrorMessages.message("underscore.identifier"), - languageLevel.isAtLeast(LanguageLevel.JDK_1_9) ? ProblemHighlightType.ERROR : ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + version.isAtLeast(JavaSdkVersion.JDK_1_9) ? ProblemHighlightType.ERROR : ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } } From bdabf14d5d6cb693a0972e84fa1101ca83ce87d2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 10 Jun 2015 14:59:56 +0300 Subject: [PATCH 30/38] new inference: distinguish assignment expressions with eq sign (IDEA-141157) --- .../graphInference/PsiPolyExpressionUtil.java | 2 +- .../lambda/PsiPolyExpressionUtilTest.java | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java index ef697e9e10f9..d206ec4632a2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/PsiPolyExpressionUtil.java @@ -135,7 +135,7 @@ public class PsiPolyExpressionUtil { private static boolean isAssignmentContext(PsiExpression expr, PsiElement context) { return PsiUtil.isCondition(expr, context) || context instanceof PsiReturnStatement || - context instanceof PsiAssignmentExpression || + context instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)context).getOperationTokenType() == JavaTokenType.EQ || context instanceof PsiVariable || context instanceof PsiLambdaExpression; } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java index e1d315e8f999..c4ff30f58fc2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/PsiPolyExpressionUtilTest.java @@ -100,6 +100,23 @@ public class PsiPolyExpressionUtilTest extends LightCodeInsightFixtureTestCase { assertTrue(PsiPolyExpressionUtil.isPolyExpression(psiExpression)); } + public void testConditionalInAssignment() throws Exception { + myFixture.configureByText("Foo.java", "class Foo {" + + " public static void main(String[] args) {\n" + + " Object obj = new Object();\n" + + " String str = \"\";\n" + + " str += args.length == 0 ? obj : args[0];\n" + + " }" + + "}"); + final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); + assertNotNull(elementAtCaret); + final PsiExpression psiExpression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class); + assertInstanceOf(psiExpression, PsiConditionalExpression.class); + assertFalse(PsiPolyExpressionUtil.isPolyExpression(psiExpression)); + } + + + private PsiExpression findExpression(String textWithExpression) { myFixture.configureByText("Foo.java", "import java.util.*;" + "class Foo {" + From 484038e916dc40bf87eca10c77889d79eca96c4d Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 10 Jun 2015 14:08:22 +0200 Subject: [PATCH 31/38] IDEA-141247 Allow to remove multiple Annotation Profiles at once --- .../options/AnnotationProcessorsPanel.java | 26 +++++++++++++++---- .../com/intellij/ui/TreeToolbarDecorator.java | 16 ++++++++++-- .../intellij/util/ui/EditableTreeModel.java | 4 ++- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java index 37a8ceb4ce4d..61ad719aab1a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java +++ b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java @@ -36,6 +36,7 @@ import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBList; import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.SmartList; import com.intellij.util.ui.EditableTreeModel; import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile; @@ -270,14 +271,29 @@ public class AnnotationProcessorsPanel extends JPanel { @Override public void removeNode(TreePath nodePath) { - Object node = nodePath.getLastPathComponent(); - if (node instanceof ProfileNode) { - final ProcessorConfigProfile nodeProfile = ((ProfileNode)node).myProfile; - if (nodeProfile != myDefaultProfile) { + removeNodes(Collections.singleton(nodePath)); + } + + public void removeNodes(Collection paths) { + final List toRemove = new SmartList(); + for (TreePath path : paths) { + Object node = path.getLastPathComponent(); + if (node instanceof ProfileNode) { + final ProcessorConfigProfile nodeProfile = ((ProfileNode)node).myProfile; + if (nodeProfile != myDefaultProfile) { + toRemove.add(nodeProfile); + } + } + } + if (!toRemove.isEmpty()) { + boolean changed = false; + for (ProcessorConfigProfile nodeProfile : toRemove) { if (mySelectedProfile == nodeProfile) { mySelectedProfile = null; } - myModuleProfiles.remove(nodeProfile); + changed |= myModuleProfiles.remove(nodeProfile); + } + if (changed) { ((DataSynchronizable)getRoot()).sync(); final DefaultMutableTreeNode object = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)getRoot(), myDefaultProfile); if (object != null) { diff --git a/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java index 081c4541453c..cda33d1e5381 100644 --- a/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java +++ b/platform/platform-api/src/com/intellij/ui/TreeToolbarDecorator.java @@ -30,8 +30,10 @@ import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.Arrays; /** * @author Konstantin Bulenkov @@ -98,8 +100,18 @@ class TreeToolbarDecorator extends ToolbarDecorator { @Override public void run(AnActionButton button) { myTree.stopEditing(); - final TreePath path = myTree.getSelectionPath(); - model.removeNode(path); + if (myTree.getSelectionModel().getSelectionMode() == TreeSelectionModel.SINGLE_TREE_SELECTION) { + final TreePath path = myTree.getSelectionPath(); + if (path != null) { + model.removeNode(path); + } + } + else { + final TreePath[] paths = myTree.getSelectionPaths(); + if (paths != null && paths.length > 0) { + model.removeNodes(Arrays.asList(paths)); + } + } } }; } diff --git a/platform/util/src/com/intellij/util/ui/EditableTreeModel.java b/platform/util/src/com/intellij/util/ui/EditableTreeModel.java index c254c4631e38..58f51e4b1f03 100644 --- a/platform/util/src/com/intellij/util/ui/EditableTreeModel.java +++ b/platform/util/src/com/intellij/util/ui/EditableTreeModel.java @@ -16,6 +16,7 @@ package com.intellij.util.ui; import javax.swing.tree.TreePath; +import java.util.Collection; /** * @author Konstantin Bulenkov @@ -29,7 +30,8 @@ public interface EditableTreeModel { */ TreePath addNode(TreePath parentOrNeighbour); - void removeNode(TreePath parent); + void removeNode(TreePath path); + void removeNodes(Collection path); void moveNodeTo(TreePath parentOrNeighbour); } From 7851ebc18ed05bb13875d890c54e810c6d400e14 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 10 Jun 2015 14:34:46 +0200 Subject: [PATCH 32/38] reset versionString fix reverted to previous implementation because clearing it in the listener would reset the versionString value explicitly configured via sdkModificator --- .../openapi/projectRoots/impl/ProjectJdkImpl.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java index 756b641a0439..23fe8a6a6b76 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/projectRoots/impl/ProjectJdkImpl.java @@ -221,8 +221,7 @@ public class ProjectJdkImpl extends UserDataHolderBase implements JDOMExternaliz final boolean changes = myHomePath == null? path != null : !myHomePath.equals(path); myHomePath = path; if (changes) { - myVersionString = null; // clear cached value if home path changed - myVersionDefined = false; + resetVersionString(); // clear cached value if home path changed } } @@ -312,7 +311,6 @@ public class ProjectJdkImpl extends UserDataHolderBase implements JDOMExternaliz @Override public void rootsChanged() { - resetVersionString(); if (myListeners.isEmpty()) { return; } @@ -390,7 +388,12 @@ public class ProjectJdkImpl extends UserDataHolderBase implements JDOMExternaliz } public void update() { - myRootContainer.update(); + try { + myRootContainer.update(); + } + finally { + resetVersionString(); + } } @Override From da13f2405184d86c8094dadefce19e436256fe52 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 10 Jun 2015 16:21:46 +0300 Subject: [PATCH 33/38] EA-69221 - IAE: SourcePosition$SourcePositionCache. --- .../engine/DefaultSourcePositionProvider.java | 24 +++++++------------ .../com/intellij/debugger/SourcePosition.java | 11 +++++---- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DefaultSourcePositionProvider.java b/java/debugger/impl/src/com/intellij/debugger/engine/DefaultSourcePositionProvider.java index 41e436ba6c8e..f75b1a27418a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DefaultSourcePositionProvider.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DefaultSourcePositionProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,7 +87,7 @@ public class DefaultSourcePositionProvider extends SourcePositionProvider { if (nearest) { return DebuggerContextUtil.findNearest(context, psiVariable, aClass.getContainingFile()); } - return SourcePosition.createFromOffset(psiVariable.getContainingFile(), psiVariable.getTextOffset()); + return SourcePosition.createFromElement(psiVariable); } else { final DebuggerSession session = context.getDebuggerSession(); @@ -115,13 +115,11 @@ public class DefaultSourcePositionProvider extends SourcePositionProvider { if (aClass != null) { PsiField field = aClass.findFieldByName(fieldName, false); - if (field != null) { - PsiElement element = field.getNavigationElement(); - if (nearest) { - return DebuggerContextUtil.findNearest(context, element, aClass.getContainingFile()); - } - return SourcePosition.createFromOffset(element.getContainingFile(), element.getTextOffset()); + if (field == null) return null; + if (nearest) { + return DebuggerContextUtil.findNearest(context, field.getNavigationElement(), aClass.getContainingFile()); } + return SourcePosition.createFromElement(field); } return null; } @@ -133,20 +131,16 @@ public class DefaultSourcePositionProvider extends SourcePositionProvider { @NotNull DebuggerContextImpl context, boolean nearest) { PsiElement place = PositionUtil.getContextElement(context); - if (place == null) { - return null; - } + if (place == null) return null; PsiVariable psiVariable = JavaPsiFacade.getInstance(project).getResolveHelper().resolveReferencedVariable(descriptor.getName(), place); - if (psiVariable == null) { - return null; - } + if (psiVariable == null) return null; PsiFile containingFile = psiVariable.getContainingFile(); if(containingFile == null) return null; if (nearest) { return DebuggerContextUtil.findNearest(context, psiVariable, containingFile); } - return SourcePosition.createFromOffset(containingFile, psiVariable.getTextOffset()); + return SourcePosition.createFromElement(psiVariable); } } \ No newline at end of file diff --git a/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java b/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java index 5e5ae9251384..831a5fc3c4ae 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java +++ b/java/debugger/openapi/src/com/intellij/debugger/SourcePosition.java @@ -274,7 +274,7 @@ public abstract class SourcePosition implements Navigatable{ } } - public static SourcePosition createFromLineComputable(final PsiFile file, final Computable line) { + public static SourcePosition createFromLineComputable(@NotNull final PsiFile file, final Computable line) { return new SourcePositionCache(file) { @Override protected int calcLine() { @@ -283,7 +283,7 @@ public abstract class SourcePosition implements Navigatable{ }; } - public static SourcePosition createFromLine(final PsiFile file, final int line) { + public static SourcePosition createFromLine(@NotNull final PsiFile file, final int line) { return new SourcePositionCache(file) { @Override protected int calcLine() { @@ -297,9 +297,8 @@ public abstract class SourcePosition implements Navigatable{ }; } - public static SourcePosition createFromOffset(final PsiFile file, final int offset) { + public static SourcePosition createFromOffset(@NotNull final PsiFile file, final int offset) { return new SourcePositionCache(file) { - @Override protected int calcOffset() { return offset; @@ -311,7 +310,8 @@ public abstract class SourcePosition implements Navigatable{ } }; } - + + @Nullable public static SourcePosition createFromElement(PsiElement element) { ApplicationManager.getApplication().assertReadAccessAllowed(); PsiElement navigationElement = element.getNavigationElement(); @@ -324,6 +324,7 @@ public abstract class SourcePosition implements Navigatable{ else { psiFile = navigationElement.getContainingFile(); } + if (psiFile == null) return null; return new SourcePositionCache(psiFile) { @Override protected PsiElement calcPsiElement() { From 4df7e26571815140073bc0ac17fe45032b62c3e1 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Wed, 10 Jun 2015 15:27:33 +0200 Subject: [PATCH 34/38] [after review] use set instead of map --- .../intellij/openapi/vfs/impl/jar/JarHandler.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java index eacadeb4b8d5..ba3989b69375 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandler.java @@ -32,9 +32,9 @@ import com.intellij.openapi.vfs.impl.ZipHandler; import com.intellij.openapi.vfs.newvfs.persistent.FSRecords; import com.intellij.openapi.vfs.newvfs.persistent.FlushingDaemon; import com.intellij.util.CommonProcessors; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.util.io.*; -import gnu.trove.THashMap; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -344,10 +344,10 @@ public class JarHandler extends ZipHandler { } }))); - final List invalidLibraryFilePaths = new ArrayList(); - final List allLibraryFilePaths = new ArrayList(); + final List invalidLibraryFilePaths = ContainerUtil.newArrayList(); + final List allLibraryFilePaths = ContainerUtil.newArrayList(); MultiMap jarSnapshotFileToLibraryFilePaths = new MultiMap(); - Map validLibraryFilePathToJarSnapshotFilePaths = new THashMap(); + Set validLibraryFilePathToJarSnapshotFilePaths = ContainerUtil.newTroveSet(); info.processKeys(new CommonProcessors.CollectProcessor(allLibraryFilePaths)); for(String filePath:allLibraryFilePaths) { @@ -356,7 +356,7 @@ public class JarHandler extends ZipHandler { jarSnapshotFileToLibraryFilePaths.putValue(libraryInfo.mySnapshotPath, filePath); if (new File(filePath).exists()) { - validLibraryFilePathToJarSnapshotFilePaths.put(filePath, libraryInfo.mySnapshotPath); + validLibraryFilePathToJarSnapshotFilePaths.add(filePath); } else { invalidLibraryFilePaths.add(filePath); } @@ -368,7 +368,7 @@ public class JarHandler extends ZipHandler { } for(Map.Entry> e: jarSnapshotFileToLibraryFilePaths.entrySet()) { for(String libraryFilePath:e.getValue()) { - if (validLibraryFilePathToJarSnapshotFilePaths.containsKey(libraryFilePath)) { + if (validLibraryFilePathToJarSnapshotFilePaths.contains(libraryFilePath)) { availableLibrarySnapshots.remove(e.getKey()); break; } From 9b70de80a46a5746a4d820169cfbc0b48e373ef1 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 10 Jun 2015 16:34:08 +0300 Subject: [PATCH 35/38] EA-69139 - ISE: OpenFileDescriptor.navigate --- .../intellij/xdebugger/impl/breakpoints/XBreakpointItem.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java index 479ea7c89ecb..5f096868ff0b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -128,7 +128,7 @@ class XBreakpointItem extends BreakpointItem { @Override public void navigate(boolean requestFocus) { Navigatable navigatable = myBreakpoint.getNavigatable(); - if (navigatable != null) { + if (navigatable != null && navigatable.canNavigate()) { navigatable.navigate(requestFocus); } } From 9f1bfe5f558de948013521f2960540cec5f1c518 Mon Sep 17 00:00:00 2001 From: Alexander Kass Date: Wed, 10 Jun 2015 16:31:08 +0300 Subject: [PATCH 36/38] Darcula: combo box with changed background --- .../com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java index e92e7ffdde6a..ea36ede553c8 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java @@ -351,11 +351,11 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { g.setColor(editor.getBackground()); g.fillRect(xxx, y + 1, 5, H); } else { - g.setColor(UIUtil.getPanelBackground()); + g.setColor(comboBox.getBackground()); g.fillRoundRect(x + 1, y + 1, W, H, R, R); g.setColor(getArrowButtonFillColor(arrowButton.getBackground())); g.fillRoundRect(xxx, y + 1, width - xxx, H, R, R); - g.setColor(UIUtil.getPanelBackground()); + g.setColor(comboBox.getBackground()); g.fillRect(xxx, y + 1, 5, H); } final Color borderColor = getBorderColor();//ColorUtil.shift(UIUtil.getBorderColor(), 4); From fde1f62b67d1cf15b9df8a0d2e05f103671c7486 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 10 Jun 2015 14:03:49 +0200 Subject: [PATCH 37/38] =?UTF-8?q?fix=20chrome=20evaluator=20SourceEntriesP?= =?UTF-8?q?rocessor=20=E2=80=94=20mapping=20can=20cover=20the=20whole=20li?= =?UTF-8?q?ne?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../debugger/sourcemap/MappingList.java | 34 ++++++++++++++++--- .../debugger/sourcemap/SourceMap.java | 18 ++++++++-- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java index 0248b404e227..b1c3722ffc95 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/MappingList.java @@ -1,7 +1,21 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.jetbrains.debugger.sourcemap; import com.intellij.openapi.editor.Document; -import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -161,8 +175,12 @@ public abstract class MappingList { return mappings.get(index); } + public interface MappingsProcessorInLine { + boolean process(@NotNull MappingEntry entry, @Nullable MappingEntry nextEntry); + } + // entries will be processed in this list order - public boolean processMappingsInLine(int line, @NotNull Processor entryProcessor) { + public boolean processMappingsInLine(int line, @NotNull MappingsProcessorInLine entryProcessor) { int low = 0; int high = mappings.size() - 1; while (low <= high) { @@ -176,12 +194,20 @@ public abstract class MappingList { firstIndex--; } + MappingEntry entry = mappings.get(firstIndex); do { - if (!entryProcessor.process(mappings.get(firstIndex))) { + MappingEntry nextEntry = ++firstIndex < mappings.size() ? mappings.get(firstIndex) : null; + if (nextEntry != null && getLine(nextEntry) != line) { + nextEntry = null; + } + + if (!entryProcessor.process(entry, nextEntry)) { return true; } + + entry = nextEntry; } - while (++firstIndex < mappings.size() && getLine(mappings.get(firstIndex)) == line); + while (entry != null); return true; } else if (line > mappingLine) { diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMap.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMap.java index b8618af5381d..46f64afc24e2 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMap.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/sourcemap/SourceMap.java @@ -1,8 +1,22 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.jetbrains.debugger.sourcemap; import com.intellij.openapi.util.NullableLazyValue; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Processor; import com.intellij.util.Url; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -73,7 +87,7 @@ public class SourceMap { public boolean processMappingsInLine(@NotNull List sourceUrls, int sourceLine, - @NotNull Processor mappingProcessor, + @NotNull MappingList.MappingsProcessorInLine mappingProcessor, @Nullable VirtualFile sourceFile, @Nullable NullableLazyValue resolver) { MappingList mappings = findMappingList(sourceUrls, sourceFile, resolver); From 4bcdecf1bdf35e7c3e2e8a627ce1456365ce01e5 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 10 Jun 2015 15:42:44 +0200 Subject: [PATCH 38/38] init IDEA-141043 GWT - Evaluate Expression returns ReferenceError in SuperDevMode. --- .../src/com/jetbrains/javascript/debugger/NameMapper.java | 8 ++++---- .../src/org/jetbrains/debugger/DebugProcessImpl.java | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.java b/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.java index 7fc7bd69aa06..9865a9e6813a 100644 --- a/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.java +++ b/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.java @@ -32,7 +32,7 @@ import static org.jetbrains.rpc.CommandProcessor.LOG; public class NameMapper { public static final String S1 = ",()[]{}="; - private static final CharMatcher NAME_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1 + ".&:")); + protected static final CharMatcher NAME_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1 + ".&:")); // don't trim trailing .&: - could be part of expression private static final CharMatcher OPERATOR_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1)); @@ -75,7 +75,7 @@ public class NameMapper { } String sourceEntryName = sourceEntry.getName(); - String generatedName = extractName(getGeneratedName(generatedDocument, sourceMap, sourceEntry), true); + String generatedName = extractName(getGeneratedName(generatedDocument, sourceMap, sourceEntry)); if (!generatedName.isEmpty()) { String sourceName = sourceEntryName; if (sourceName == null) { @@ -106,8 +106,8 @@ public class NameMapper { } @NotNull - protected String extractName(@NotNull CharSequence rawGeneratedName, boolean isLastToken) { - return trimName(rawGeneratedName, isLastToken); + protected String extractName(@NotNull CharSequence rawGeneratedName) { + return NAME_TRIMMER.trimFrom(rawGeneratedName); } @NotNull diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.java b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.java index 3baf3725f6ee..405de9c33d64 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.java +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.java @@ -296,4 +296,8 @@ public abstract class DebugProcessImpl extends XDebugPro return true; } } + + public void saveResolvedFile(@NotNull Url url, @NotNull VirtualFile file) { + urlToFileCache.putIfAbsent(url, file); + } } \ No newline at end of file