From 33500eaee09e97249758d059de9b6da24c0fbd29 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 15 Sep 2014 17:02:52 +0400 Subject: [PATCH 01/36] =?UTF-8?q?fixed=20PY-13900=20g=20and=20=C9=A1=20are?= =?UTF-8?q?n't=20the=20same,=20so=20highlite=20the=20difference=20in=20the?= =?UTF-8?q?=20editor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../python/inspections/PyNonAsciiCharInspection.java | 12 ++++++++++++ .../PyNonAsciiCharReferenceInspection/test.py | 4 ++++ .../com/jetbrains/python/PythonInspectionsTest.java | 4 ++++ 3 files changed, 20 insertions(+) create mode 100644 python/testData/inspections/PyNonAsciiCharReferenceInspection/test.py diff --git a/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java b/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java index 5fd0e565a6f8..313e1d91455f 100644 --- a/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyNonAsciiCharInspection.java @@ -25,7 +25,9 @@ import com.jetbrains.python.PyBundle; import com.jetbrains.python.PythonFileType; import com.jetbrains.python.inspections.quickfix.AddEncodingQuickFix; import com.jetbrains.python.psi.LanguageLevel; +import com.jetbrains.python.psi.PyReferenceExpression; import com.jetbrains.python.psi.PyStringLiteralExpression; +import com.jetbrains.python.psi.PyTargetExpression; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -95,6 +97,16 @@ public class PyNonAsciiCharInspection extends PyInspection { public void visitPyStringLiteralExpression(PyStringLiteralExpression node) { checkString(node, node.getText()); } + + @Override + public void visitPyReferenceExpression(PyReferenceExpression node) { + checkString(node, node.getText()); + } + + @Override + public void visitPyTargetExpression(PyTargetExpression node) { + checkString(node, node.getText()); + } } public String myDefaultEncoding = "utf-8"; diff --git a/python/testData/inspections/PyNonAsciiCharReferenceInspection/test.py b/python/testData/inspections/PyNonAsciiCharReferenceInspection/test.py new file mode 100644 index 000000000000..49ae2b62b538 --- /dev/null +++ b/python/testData/inspections/PyNonAsciiCharReferenceInspection/test.py @@ -0,0 +1,4 @@ +g = 2 +i = 2 +ɡ = 1 +a = g + i diff --git a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java index ded3e11d5ac7..aeb4cfdccf84 100644 --- a/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java +++ b/python/testSrc/com/jetbrains/python/PythonInspectionsTest.java @@ -300,6 +300,10 @@ public class PythonInspectionsTest extends PyTestCase { doHighlightingTest(PyNonAsciiCharInspection.class); } + public void testPyNonAsciiCharReferenceInspection() { + doHighlightingTest(PyNonAsciiCharInspection.class); + } + public void testPySetFunctionToLiteralInspection() { //PY-3120 setLanguageLevel(LanguageLevel.PYTHON27); doHighlightingTest(PySetFunctionToLiteralInspection.class); From 1c34eb0a0a71b91d0cc2439a302bb0e4df0ac68f Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 15 Sep 2014 17:04:58 +0400 Subject: [PATCH 02/36] fixed PY-13889 Project Interperter: Throwable at com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel$2.run --- .../jetbrains/python/configuration/PyActiveSdkConfigurable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java index 38195d1380b9..282699eccc44 100644 --- a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java +++ b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java @@ -286,7 +286,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { PySdkService.getInstance().solidifySdk(item); } else { - final Sdk sdk = myProjectSdksModel.findSdk(item); + final Sdk sdk = myProjectSdksModel.getProjectSdks().get(item); if (item != null && sdk == null) { myProjectSdksModel.addSdk(item); myProjectSdksModel.apply(null, true); From c091cfdf37e466808f5d64b0975778bc7fb84976 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 15 Sep 2014 17:12:29 +0400 Subject: [PATCH 03/36] fixed PY-13884 "Override Methods" loses @staticmethod decorator from parent --- .../codeInsight/override/PyOverrideImplementUtil.java | 7 +++++-- python/testData/override/staticMethod.py | 7 +++++++ python/testData/override/staticMethod_after.py | 9 +++++++++ python/testSrc/com/jetbrains/python/PyOverrideTest.java | 4 ++++ 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 python/testData/override/staticMethod.py create mode 100644 python/testData/override/staticMethod_after.py diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java index e11f3e01e916..5a6caf0a8941 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java @@ -183,8 +183,11 @@ public class PyOverrideImplementUtil { private static PyFunctionBuilder buildOverriddenFunction(PyClass pyClass, PyFunction baseFunction, boolean implement) { PyFunctionBuilder pyFunctionBuilder = new PyFunctionBuilder(baseFunction.getName()); final PyDecoratorList decorators = baseFunction.getDecoratorList(); - if (decorators != null && decorators.findDecorator(PyNames.CLASSMETHOD) != null) { - pyFunctionBuilder.decorate(PyNames.CLASSMETHOD); + if (decorators != null) { + if (decorators.findDecorator(PyNames.CLASSMETHOD) != null) + pyFunctionBuilder.decorate(PyNames.CLASSMETHOD); + else if (decorators.findDecorator(PyNames.STATICMETHOD) != null) + pyFunctionBuilder.decorate(PyNames.STATICMETHOD); } PyAnnotation anno = baseFunction.getAnnotation(); if (anno != null) { diff --git a/python/testData/override/staticMethod.py b/python/testData/override/staticMethod.py new file mode 100644 index 000000000000..818c544a9ca6 --- /dev/null +++ b/python/testData/override/staticMethod.py @@ -0,0 +1,7 @@ +class A: + @staticmethod + def foo(cls): + cls.k = 3 + +class B(A): + pass diff --git a/python/testData/override/staticMethod_after.py b/python/testData/override/staticMethod_after.py new file mode 100644 index 000000000000..000c0ca534cf --- /dev/null +++ b/python/testData/override/staticMethod_after.py @@ -0,0 +1,9 @@ +class A: + @staticmethod + def foo(cls): + cls.k = 3 + +class B(A): + @staticmethod + def foo(cls): + A.foo(cls) diff --git a/python/testSrc/com/jetbrains/python/PyOverrideTest.java b/python/testSrc/com/jetbrains/python/PyOverrideTest.java index d378f253f628..d80dc06182e7 100644 --- a/python/testSrc/com/jetbrains/python/PyOverrideTest.java +++ b/python/testSrc/com/jetbrains/python/PyOverrideTest.java @@ -64,6 +64,10 @@ public class PyOverrideTest extends PyTestCase { doTest(); } + public void testStaticMethod() { + doTest(); + } + public void testNewStyle() { doTest(); } From f7137da458b96b97a42df60d6c1a0e32ca857147 Mon Sep 17 00:00:00 2001 From: "Svetlana.Zemlyanskay" Date: Mon, 15 Sep 2014 17:41:11 +0400 Subject: [PATCH 04/36] IDEA-129802 Rearranger UI: fix toolbar icons --- .../action/AddArrangementRuleAction.java | 9 ++----- .../AddArrangementSectionRuleAction.java | 2 +- .../action/EditArrangementRuleAction.java | 2 ++ ...MoveArrangementGroupingRuleDownAction.java | 2 ++ .../MoveArrangementGroupingRuleUpAction.java | 2 ++ ...MoveArrangementMatchingRuleDownAction.java | 2 ++ .../MoveArrangementMatchingRuleUpAction.java | 2 ++ .../action/RemoveArrangementRuleAction.java | 5 ++-- .../src/idea/LangActions.xml | 24 +++++++++---------- 9 files changed, 26 insertions(+), 24 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/AddArrangementRuleAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/AddArrangementRuleAction.java index fdde6eab9cbc..4eb993aaa29a 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/AddArrangementRuleAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/AddArrangementRuleAction.java @@ -18,11 +18,10 @@ package com.intellij.application.options.codeStyle.arrangement.action; import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl; import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesModel; import com.intellij.application.options.codeStyle.arrangement.match.EmptyArrangementRuleComponent; -import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.util.SystemInfoRt; +import com.intellij.util.IconUtil; import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NotNull; @@ -35,11 +34,7 @@ public class AddArrangementRuleAction extends AbstractArrangementRuleAction impl public AddArrangementRuleAction() { getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.rule.add.text")); getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.rule.add.description")); - } - - @Override - public void update(AnActionEvent e) { - e.getPresentation().setIcon(SystemInfoRt.isMac ? AllIcons.ToolbarDecorator.Mac.Add : AllIcons.ToolbarDecorator.Add); + getTemplatePresentation().setIcon(IconUtil.getAddIcon()); } @Override diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/AddArrangementSectionRuleAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/AddArrangementSectionRuleAction.java index db0b66fb5167..3ea3b0dd4121 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/AddArrangementSectionRuleAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/AddArrangementSectionRuleAction.java @@ -31,11 +31,11 @@ public class AddArrangementSectionRuleAction extends AddArrangementRuleAction { public AddArrangementSectionRuleAction() { getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.section.rule.add.text")); getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.section.rule.add.description")); + getTemplatePresentation().setIcon(SystemInfoRt.isMac ? AllIcons.CodeStyle.Mac.AddNewSectionRule : AllIcons.CodeStyle.AddNewSectionRule); } @Override public void update(AnActionEvent e) { - e.getPresentation().setIcon(SystemInfoRt.isMac ? AllIcons.CodeStyle.Mac.AddNewSectionRule : AllIcons.CodeStyle.AddNewSectionRule); final ArrangementMatchingRulesControl control = ArrangementMatchingRulesControl.KEY.getData(e.getDataContext()); if (control == null) { return; diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/EditArrangementRuleAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/EditArrangementRuleAction.java index 14beaa21a1d9..c6e9b3cbba36 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/EditArrangementRuleAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/EditArrangementRuleAction.java @@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Toggleable; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.project.DumbAware; +import com.intellij.util.IconUtil; import gnu.trove.TIntArrayList; /** @@ -31,6 +32,7 @@ public class EditArrangementRuleAction extends AbstractArrangementRuleAction imp public EditArrangementRuleAction() { getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.rule.edit.text")); getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.rule.edit.description")); + getTemplatePresentation().setIcon(IconUtil.getEditIcon()); } @Override diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementGroupingRuleDownAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementGroupingRuleDownAction.java index 32ad1bf846b7..b124c7420419 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementGroupingRuleDownAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementGroupingRuleDownAction.java @@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.project.DumbAware; +import com.intellij.util.IconUtil; import javax.swing.table.DefaultTableModel; @@ -32,6 +33,7 @@ public class MoveArrangementGroupingRuleDownAction extends AnAction implements D public MoveArrangementGroupingRuleDownAction() { getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.rule.move.down.text")); getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.rule.move.down.description")); + getTemplatePresentation().setIcon(IconUtil.getMoveDownIcon()); } @Override diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementGroupingRuleUpAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementGroupingRuleUpAction.java index a010f63cbd74..0c3b1e8e3b12 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementGroupingRuleUpAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementGroupingRuleUpAction.java @@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.project.DumbAware; +import com.intellij.util.IconUtil; import javax.swing.table.DefaultTableModel; @@ -32,6 +33,7 @@ public class MoveArrangementGroupingRuleUpAction extends AnAction implements Dum public MoveArrangementGroupingRuleUpAction() { getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.rule.move.up.text")); getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.rule.move.up.description")); + getTemplatePresentation().setIcon(IconUtil.getMoveUpIcon()); } @Override diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementMatchingRuleDownAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementMatchingRuleDownAction.java index 37efc9d0dc51..2596ce9f89ef 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementMatchingRuleDownAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementMatchingRuleDownAction.java @@ -17,6 +17,7 @@ package com.intellij.application.options.codeStyle.arrangement.action; import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl; import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.util.IconUtil; import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NotNull; @@ -31,6 +32,7 @@ public class MoveArrangementMatchingRuleDownAction extends AbstractMoveArrangeme public MoveArrangementMatchingRuleDownAction() { getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.rule.move.down.text")); getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.rule.move.down.description")); + getTemplatePresentation().setIcon(IconUtil.getMoveDownIcon()); } @Override diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementMatchingRuleUpAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementMatchingRuleUpAction.java index 3e2b917c6f98..037aec13efba 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementMatchingRuleUpAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/MoveArrangementMatchingRuleUpAction.java @@ -17,6 +17,7 @@ package com.intellij.application.options.codeStyle.arrangement.action; import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl; import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.util.IconUtil; import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NotNull; @@ -31,6 +32,7 @@ public class MoveArrangementMatchingRuleUpAction extends AbstractMoveArrangement public MoveArrangementMatchingRuleUpAction() { getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.rule.move.up.text")); getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.rule.move.up.description")); + getTemplatePresentation().setIcon(IconUtil.getMoveUpIcon()); } @Override diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/RemoveArrangementRuleAction.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/RemoveArrangementRuleAction.java index 5fbcdccd38e9..677de3c53a3e 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/RemoveArrangementRuleAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/action/RemoveArrangementRuleAction.java @@ -17,12 +17,11 @@ package com.intellij.application.options.codeStyle.arrangement.action; import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl; import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesModel; -import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.util.SystemInfoRt; +import com.intellij.util.IconUtil; import gnu.trove.TIntArrayList; /** @@ -34,13 +33,13 @@ public class RemoveArrangementRuleAction extends AnAction implements DumbAware { public RemoveArrangementRuleAction() { getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.rule.remove.text")); getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.rule.remove.description")); + getTemplatePresentation().setIcon(IconUtil.getRemoveIcon()); } @Override public void update(AnActionEvent e) { ArrangementMatchingRulesControl control = ArrangementMatchingRulesControl.KEY.getData(e.getDataContext()); e.getPresentation().setEnabled(control != null && !control.getSelectedModelRows().isEmpty() && control.getEditingRow() == -1); - e.getPresentation().setIcon(SystemInfoRt.isMac ? AllIcons.ToolbarDecorator.Mac.Remove : AllIcons.ToolbarDecorator.Remove); } @Override diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 55e3d8967742..fe3855c35475 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -844,24 +844,22 @@ - - - + + + + class="com.intellij.application.options.codeStyle.arrangement.action.EditArrangementRuleAction"/> + class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementMatchingRuleUpAction"/> + class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementMatchingRuleDownAction"/> + class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementGroupingRuleUpAction"/> + class="com.intellij.application.options.codeStyle.arrangement.action.MoveArrangementGroupingRuleDownAction"/> From 8af33ddb9c58327323643abb1fd0589a979e5f74 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Mon, 15 Sep 2014 18:23:15 +0400 Subject: [PATCH 05/36] [AutoDetectIndent] Detect tab usage if number of lines with tabs more than lines with space indents. Detect indent size only if number of lines with spaces is greater than min lines threshold. --- .../codeStyle/autodetect/IndentOptionsDetectorImpl.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetectorImpl.java b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetectorImpl.java index 38e818808349..f4972cda633c 100644 --- a/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetectorImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/codeStyle/autodetect/IndentOptionsDetectorImpl.java @@ -31,7 +31,7 @@ public class IndentOptionsDetectorImpl implements IndentOptionsDetector { private static Logger LOG = Logger.getInstance("#com.intellij.psi.codeStyle.CommonCodeStyleSettings.IndentOptionsDetector"); private static final double RATE_THRESHOLD = 0.8; - private static final int MIN_LINES_THRESHOLD = 50; + private static final int MIN_LINES_THRESHOLD = 20; private static final int MAX_INDENT_TO_DETECT = 8; private final PsiFile myFile; @@ -62,16 +62,13 @@ public class IndentOptionsDetectorImpl implements IndentOptionsDetector { int linesWithTabs = stats.getTotalLinesWithLeadingTabs(); int linesWithWhiteSpaceIndent = stats.getTotalLinesWithLeadingSpaces(); - int totalLines = linesWithTabs + linesWithWhiteSpaceIndent; - double lineWithTabsRate = (double)linesWithTabs / totalLines; - - if (linesWithTabs > MIN_LINES_THRESHOLD && lineWithTabsRate > RATE_THRESHOLD) { + if (linesWithTabs > linesWithWhiteSpaceIndent) { if (!indentOptions.USE_TAB_CHARACTER) { indentOptions.USE_TAB_CHARACTER = true; LOG.info("Detected tab usage in" + myFile); } } - else if (linesWithWhiteSpaceIndent > MIN_LINES_THRESHOLD && (1 - lineWithTabsRate) > RATE_THRESHOLD) { + else if (linesWithWhiteSpaceIndent > MIN_LINES_THRESHOLD) { int newIndentSize = getPositiveIndentSize(stats); if (newIndentSize > 0) { indentOptions.USE_TAB_CHARACTER = false; From 991aa19c6941914e3938ada0821eb7b5321ae7b1 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 15 Sep 2014 16:18:17 +0200 Subject: [PATCH 06/36] notnull --- xml/impl/src/org/jetbrains/builtInWebServer/NetService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/impl/src/org/jetbrains/builtInWebServer/NetService.java b/xml/impl/src/org/jetbrains/builtInWebServer/NetService.java index ed2648021029..5c108012cb4c 100644 --- a/xml/impl/src/org/jetbrains/builtInWebServer/NetService.java +++ b/xml/impl/src/org/jetbrains/builtInWebServer/NetService.java @@ -119,7 +119,7 @@ public abstract class NetService implements Disposable { } @Nullable - protected abstract OSProcessHandler createProcessHandler(Project project, int port) throws ExecutionException; + protected abstract OSProcessHandler createProcessHandler(@NotNull Project project, int port) throws ExecutionException; protected void connectToProcess(@NotNull AsyncResult asyncResult, int port, @NotNull OSProcessHandler processHandler, @NotNull Consumer errorOutputConsumer) { asyncResult.setDone(processHandler); From 3da8aa3834c2fc932bd644dbe98690dda8144404 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Mon, 15 Sep 2014 19:07:52 +0400 Subject: [PATCH 07/36] IDEA-129637 mercurial updates to wrong revision if there tag and branch with the same name --- .../src/org/zmlx/hg4idea/action/HgMerge.java | 3 ++- .../zmlx/hg4idea/action/HgUpdateToAction.java | 3 ++- .../hg4idea/ui/HgCommonDialogWithChoices.java | 20 +++++++++++++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java index 45ff24e382ce..d19be540fbca 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java @@ -18,6 +18,7 @@ package org.zmlx.hg4idea.action; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.VcsNotifier; import com.intellij.openapi.vcs.update.UpdatedFiles; @@ -42,7 +43,7 @@ public class HgMerge extends HgAbstractGlobalSingleRepoAction { final HgMergeDialog mergeDialog = new HgMergeDialog(project, repos, selectedRepo); mergeDialog.show(); if (mergeDialog.isOK()) { - final String targetValue = mergeDialog.getTargetValue(); + final String targetValue = StringUtil.escapeBackSlashes(mergeDialog.getTargetValue()); final VirtualFile repoRoot = mergeDialog.getRepository().getRoot(); new Task.Backgroundable(project, "Merging changes...") { @Override diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java index 415cd223bd1f..96178a5679b5 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java @@ -16,6 +16,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,7 +38,7 @@ public class HgUpdateToAction extends HgAbstractGlobalSingleRepoAction { dialog.show(); if (dialog.isOK()) { FileDocumentManager.getInstance().saveAllDocuments(); - final String updateToValue = dialog.getTargetValue(); + final String updateToValue = StringUtil.escapeBackSlashes(dialog.getTargetValue()); boolean clean = dialog.isRemoveLocalChanges(); String title = HgVcsMessages.message("hg4idea.progress.updatingTo", updateToValue); runUpdateToInBackground(project, title, dialog.getRepository().getRoot(), updateToValue, clean); diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.java index 2c28d4c500ed..10c15522f78f 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgCommonDialogWithChoices.java @@ -82,7 +82,7 @@ public class HgCommonDialogWithChoices extends DialogWrapper { return hgRepositorySelectorComponent.getRepository(); } - public String getTag() { + private String getTag() { return (String)tagSelector.getSelectedItem(); } @@ -90,7 +90,7 @@ public class HgCommonDialogWithChoices extends DialogWrapper { return tagOption.isSelected(); } - public String getBranch() { + private String getBranch() { return (String)branchSelector.getSelectedItem(); } @@ -98,7 +98,11 @@ public class HgCommonDialogWithChoices extends DialogWrapper { return branchOption.isSelected(); } - public String getBookmark() { + private boolean isRevisionSelected() { + return revisionOption.isSelected(); + } + + private String getBookmark() { return (String)bookmarkSelector.getSelectedItem(); } @@ -106,7 +110,7 @@ public class HgCommonDialogWithChoices extends DialogWrapper { return bookmarkOption.isSelected(); } - public String getRevision() { + private String getRevision() { return revisionTxt.getText(); } @@ -141,11 +145,15 @@ public class HgCommonDialogWithChoices extends DialogWrapper { } public String getTargetValue() { - return isBranchSelected() ? getBranch() : isBookmarkSelected() ? getBookmark() : isTagSelected() ? getTag() : getRevision(); + return isBranchSelected() + ? "branch(\"" + getBranch() + "\")" + : isBookmarkSelected() + ? "bookmark(\"" + getBookmark() + "\")" + : isTagSelected() ? "tag(\"" + getTag() + "\")" : "\"" + getRevision() + "\""; } protected ValidationInfo doValidate() { String message = "You have to specify appropriate name or revision."; - return StringUtil.isEmptyOrSpaces(getTargetValue()) ? new ValidationInfo(message, myBranchesBorderPanel) : null; + return isRevisionSelected() && StringUtil.isEmptyOrSpaces(getRevision()) ? new ValidationInfo(message, myBranchesBorderPanel) : null; } } From 262d68aeda8697590fa0abe4ee110d1c49db07d0 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 15 Sep 2014 19:08:42 +0400 Subject: [PATCH 08/36] diff: cleanup --- .../vcs/ex/LineStatusTrackerDrawing.java | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java index 2230f9c4ff59..f2e629ef3161 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java @@ -139,37 +139,20 @@ public class LineStatusTrackerDrawing { } public static void showActiveHint(final Range range, final Editor editor, final Point point, final LineStatusTracker tracker) { - final DefaultActionGroup group = new DefaultActionGroup(); - final AnAction globalShowNextAction = ActionManager.getInstance().getAction("VcsShowNextChangeMarker"); - final AnAction globalShowPrevAction = ActionManager.getInstance().getAction("VcsShowPrevChangeMarker"); - final ShowPrevChangeMarkerAction localShowPrevAction = new ShowPrevChangeMarkerAction(tracker.getPrevRange(range), tracker, editor); final ShowNextChangeMarkerAction localShowNextAction = new ShowNextChangeMarkerAction(tracker.getNextRange(range), tracker, editor); - - final JComponent editorComponent = editor.getComponent(); - - localShowNextAction.registerCustomShortcutSet(localShowNextAction.getShortcutSet(), editorComponent); - localShowPrevAction.registerCustomShortcutSet(localShowPrevAction.getShortcutSet(), editorComponent); - - group.add(localShowPrevAction); - group.add(localShowNextAction); - - localShowNextAction.copyFrom(globalShowNextAction); - localShowPrevAction.copyFrom(globalShowPrevAction); - final RollbackLineStatusRangeAction rollback = new RollbackLineStatusRangeAction(tracker, range, editor); final ShowLineStatusRangeDiffAction showDiff = new ShowLineStatusRangeDiffAction(tracker, range, editor); final CopyLineStatusRangeAction copyRange = new CopyLineStatusRangeAction(tracker, range); + group.add(localShowPrevAction); + group.add(localShowNextAction); group.add(rollback); group.add(showDiff); group.add(copyRange); - EmptyAction.setupAction(rollback, IdeActions.SELECTED_CHANGES_ROLLBACK, editorComponent); - EmptyAction.setupAction(showDiff, "ChangesView.Diff", editorComponent); - EmptyAction.setupAction(copyRange, IdeActions.ACTION_COPY, editorComponent); final JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR, group, true).getComponent(); @@ -207,6 +190,7 @@ public class LineStatusTrackerDrawing { component.add(toolbarPanel, BorderLayout.NORTH); + if (range.getType() != Range.INSERTED) { final DocumentEx doc = (DocumentEx) tracker.getVcsDocument(); final EditorEx uEditor = (EditorEx)EditorFactory.getInstance().createViewer(doc, tracker.getProject()); @@ -221,6 +205,15 @@ public class LineStatusTrackerDrawing { EditorFactory.getInstance().releaseEditor(uEditor); } + + final JComponent editorComponent = editor.getComponent(); + EmptyAction.setupAction(localShowPrevAction, "VcsShowPrevChangeMarker", editorComponent); + EmptyAction.setupAction(localShowNextAction, "VcsShowNextChangeMarker", editorComponent); + EmptyAction.setupAction(rollback, IdeActions.SELECTED_CHANGES_ROLLBACK, editorComponent); + EmptyAction.setupAction(showDiff, "ChangesView.Diff", editorComponent); + EmptyAction.setupAction(copyRange, IdeActions.ACTION_COPY, editorComponent); + + final List actionList = ActionUtil.getActions(editorComponent); final LightweightHint lightweightHint = new LightweightHint(component); HintListener closeListener = new HintListener() { @@ -234,9 +227,10 @@ public class LineStatusTrackerDrawing { }; lightweightHint.addHintListener(closeListener); - HintManagerImpl.getInstanceImpl().showEditorHint(lightweightHint, editor, point, HintManagerImpl.HIDE_BY_ANY_KEY | HintManagerImpl.HIDE_BY_TEXT_CHANGE | - HintManagerImpl.HIDE_BY_SCROLLING, - -1, false, new HintHint(editor, point)); + HintManagerImpl.getInstanceImpl() + .showEditorHint(lightweightHint, editor, point, + HintManagerImpl.HIDE_BY_ANY_KEY | HintManagerImpl.HIDE_BY_TEXT_CHANGE | HintManagerImpl.HIDE_BY_SCROLLING, + -1, false, new HintHint(editor, point)); if (!lightweightHint.isVisible()) { closeListener.hintHidden(null); From 0dafbe683ec8af37e740ff7e55c2c79f9619688a Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Mon, 15 Sep 2014 16:08:24 +0400 Subject: [PATCH 09/36] parse entities within comments properly #WEB-13290 fixed --- .../src/com/intellij/lang/html/HtmlParsing.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java b/xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java index 55ab6d28fdd8..82c1dff7aabb 100644 --- a/xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java +++ b/xml/xml-psi-impl/src/com/intellij/lang/html/HtmlParsing.java @@ -449,12 +449,16 @@ public class HtmlParsing { advance(); while (true) { final IElementType tt = token(); - if (tt == XmlTokenType.XML_COMMENT_CHARACTERS || tt == XmlTokenType.XML_CHAR_ENTITY_REF || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_START + if (tt == XmlTokenType.XML_COMMENT_CHARACTERS || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_START || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_START_END || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_END_START || tt == XmlTokenType.XML_CONDITIONAL_COMMENT_END) { advance(); continue; } + if (tt == XmlTokenType.XML_ENTITY_REF_TOKEN || tt == XmlTokenType.XML_CHAR_ENTITY_REF) { + parseReference(); + continue; + } if (tt == XmlTokenType.XML_BAD_CHARACTER) { final PsiBuilder.Marker error = mark(); advance(); From 27112c5fe823129be5f77ec9e58deed18558f7bc Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 15 Sep 2014 20:17:32 +0400 Subject: [PATCH 10/36] Promote the Plugins settings to the root --- platform/platform-resources/src/META-INF/PlatformExtensions.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 29dcf0645cef..2c1c7236c912 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -221,7 +221,7 @@ - From 75392e8b1c57878a8202e39aa5657a86aa4d642f Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 15 Sep 2014 20:25:34 +0400 Subject: [PATCH 11/36] Settings move: ScopeChooser to Appearance, PathVariables to Build. --- .../platform-resources/src/META-INF/PlatformLangPlugin.xml | 2 +- resources/src/idea/RichPlatformPlugin.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml index b675e6491e09..b366a6be4a56 100644 --- a/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml +++ b/platform/platform-resources/src/META-INF/PlatformLangPlugin.xml @@ -82,7 +82,7 @@ - + diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml index 509d22de08cf..3f2971e21570 100644 --- a/resources/src/idea/RichPlatformPlugin.xml +++ b/resources/src/idea/RichPlatformPlugin.xml @@ -252,14 +252,14 @@ - + - Date: Mon, 15 Sep 2014 20:17:35 +0400 Subject: [PATCH 12/36] diff: copy lines with trailing \n --- .../com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java index a9f761a2b5e0..eb008f12aedf 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/CopyLineStatusRangeAction.java @@ -35,7 +35,7 @@ public class CopyLineStatusRangeAction extends BaseLineStatusRangeAction { } public void actionPerformed(final AnActionEvent e) { - final String content = myLineStatusTracker.getVcsContent(myRange).toString(); + final String content = myLineStatusTracker.getVcsContent(myRange) + "\n"; CopyPasteManager.getInstance().setContents(new StringSelection(content)); } } From bca1e3c0f2254e0d48ca65d43fe25d53a8cb6c28 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 15 Sep 2014 20:32:08 +0400 Subject: [PATCH 13/36] diff: fix action initialisation order Action icons should present at the moment of action toolbar initialisation --- .../openapi/vcs/ex/LineStatusTrackerDrawing.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java index f2e629ef3161..e1db617baa62 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java @@ -154,6 +154,14 @@ public class LineStatusTrackerDrawing { group.add(copyRange); + final JComponent editorComponent = editor.getComponent(); + EmptyAction.setupAction(localShowPrevAction, "VcsShowPrevChangeMarker", editorComponent); + EmptyAction.setupAction(localShowNextAction, "VcsShowNextChangeMarker", editorComponent); + EmptyAction.setupAction(rollback, IdeActions.SELECTED_CHANGES_ROLLBACK, editorComponent); + EmptyAction.setupAction(showDiff, "ChangesView.Diff", editorComponent); + EmptyAction.setupAction(copyRange, IdeActions.ACTION_COPY, editorComponent); + + final JComponent toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR, group, true).getComponent(); final Color background = ((EditorEx)editor).getBackgroundColor(); @@ -206,14 +214,6 @@ public class LineStatusTrackerDrawing { } - final JComponent editorComponent = editor.getComponent(); - EmptyAction.setupAction(localShowPrevAction, "VcsShowPrevChangeMarker", editorComponent); - EmptyAction.setupAction(localShowNextAction, "VcsShowNextChangeMarker", editorComponent); - EmptyAction.setupAction(rollback, IdeActions.SELECTED_CHANGES_ROLLBACK, editorComponent); - EmptyAction.setupAction(showDiff, "ChangesView.Diff", editorComponent); - EmptyAction.setupAction(copyRange, IdeActions.ACTION_COPY, editorComponent); - - final List actionList = ActionUtil.getActions(editorComponent); final LightweightHint lightweightHint = new LightweightHint(component); HintListener closeListener = new HintListener() { From f076849c9284d9a7b326c2ba9609021160c8cf7b Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 15 Sep 2014 20:41:27 +0400 Subject: [PATCH 14/36] return file if element is null --- .../com/intellij/ide/actions/GotoRelatedSymbolAction.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java index 229531b3ef53..4a6deff68d9e 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedSymbolAction.java @@ -36,13 +36,13 @@ import java.util.List; public class GotoRelatedSymbolAction extends AnAction { @Override - public void update(AnActionEvent e) { + public void update(@NotNull AnActionEvent e) { PsiElement element = getContextElement(e.getDataContext()); e.getPresentation().setEnabled(element != null); } @Override - public void actionPerformed(AnActionEvent e) { + public void actionPerformed(@NotNull AnActionEvent e) { PsiElement element = getContextElement(e.getDataContext()); if (element == null) return; @@ -70,7 +70,7 @@ public class GotoRelatedSymbolAction extends AnAction { if (file != null && editor != null) { return getContextElement(file, editor); } - return element; + return element == null ? file : element; } @NotNull From 124c18e03eee714d4a0cce133724458e8b74a41f Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 15 Sep 2014 19:47:19 +0400 Subject: [PATCH 15/36] compiling evaluator - correct defineClass invocation --- .../com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java index 467cf985f04c..c306160936b2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java @@ -148,7 +148,7 @@ public class CompilingEvaluator implements ExpressionEvaluator { args.add(mirrorOf(bytes, context, process)); args.add(proxy.mirrorOf(0)); args.add(proxy.mirrorOf(bytes.length)); - classLoader.invokeMethod(threadReference, defineMethod, args, ClassType.INVOKE_SINGLE_THREADED); + process.invokeMethod(context, classLoader, defineMethod, args); } } return (ClassType)process.findClass(context, getGenClassFullName(), classLoader); From 7733bb0918b63399307c5ed7dd224f7f9e316505 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 15 Sep 2014 21:03:26 +0400 Subject: [PATCH 16/36] compiling evaluator - use classpath from the file's module --- .../ui/impl/watch/CompilingEvaluator.java | 78 ++++++++++++++----- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java index c306160936b2..94e97a52ba8b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java @@ -19,19 +19,24 @@ import com.intellij.debugger.DebuggerInvocationUtil; import com.intellij.debugger.EvaluatingComputable; import com.intellij.debugger.engine.ContextUtil; import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.SuspendContextImpl; import com.intellij.debugger.engine.evaluation.*; import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; import com.intellij.debugger.engine.evaluation.expression.Modifier; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiCodeFragment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiJavaFile; import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler; +import com.intellij.util.PathsList; import com.sun.jdi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.org.objectweb.asm.ClassReader; @@ -84,19 +89,27 @@ public class CompilingEvaluator implements ExpressionEvaluator { @Override public Value evaluate(final EvaluationContext evaluationContext) throws EvaluateException { + DebugProcess process = evaluationContext.getDebugProcess(); + ThreadReference threadReference = evaluationContext.getSuspendContext().getThread().getThreadReference(); + + ClassLoaderReference classLoader; try { - DebugProcess process = evaluationContext.getDebugProcess(); - ThreadReference threadReference = evaluationContext.getSuspendContext().getThread().getThreadReference(); + classLoader = getClassLoader(evaluationContext); + } + catch (Exception e) { + throw new EvaluateException("Error creating evaluation class loader: " + e, e); + } - ClassLoaderReference classLoader = getClassLoader(evaluationContext); + Collection classes = compile(); - Collection classes = compile(); - - ClassType mainClass = defineClasses(classes, evaluationContext, process, threadReference, classLoader); - - //Method foo = mainClass.methodsByName(GEN_METHOD_NAME).get(0); - //return mainClass.invokeMethod(threadReference, foo, Collections.emptyList() ,ClassType.INVOKE_SINGLE_THREADED); + try { + defineClasses(classes, evaluationContext, process, threadReference, classLoader); + } + catch (Exception e) { + throw new EvaluateException("Error during classes definition " + e, e); + } + try { // invoke base evaluator on call code final Project project = myPsiContext.getProject(); ExpressionEvaluator evaluator = @@ -115,7 +128,7 @@ public class CompilingEvaluator implements ExpressionEvaluator { return evaluator.evaluate(evaluationContext); } catch (Exception e) { - throw new EvaluateException(e.getMessage()); + throw new EvaluateException("Error during generated code invocation " + e, e); } } @@ -126,8 +139,16 @@ public class CompilingEvaluator implements ExpressionEvaluator { ClassType loaderClass = (ClassType)process.findClass(context, "java.net.URLClassLoader", context.getClassLoader()); Method ctorMethod = loaderClass.concreteMethodByName("", "([Ljava/net/URL;Ljava/lang/ClassLoader;)V"); ThreadReference threadReference = context.getSuspendContext().getThread().getThreadReference(); - return (ClassLoaderReference)loaderClass.newInstance(threadReference, ctorMethod, - Arrays.asList(createURLArray(context), context.getClassLoader()), ClassType.INVOKE_SINGLE_THREADED); + ClassLoaderReference reference = (ClassLoaderReference)loaderClass.newInstance(threadReference, ctorMethod, + Arrays.asList(createURLArray(context), + context.getClassLoader()), + ClassType.INVOKE_SINGLE_THREADED); + keep(reference, context); + return reference; + } + + private static void keep(ObjectReference reference, EvaluationContext context) { + ((SuspendContextImpl)context.getSuspendContext()).keep(reference); } private ClassType defineClasses(Collection classes, @@ -144,7 +165,9 @@ public class CompilingEvaluator implements ExpressionEvaluator { ((ClassType)classLoader.referenceType()).concreteMethodByName("defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;"); byte[] bytes = changeSuperToMagicAccessor(cls.toByteArray()); ArrayList args = new ArrayList(); - args.add(proxy.mirrorOf(cls.myOrigName)); + StringReference name = proxy.mirrorOf(cls.myOrigName); + keep(name, context); + args.add(name); args.add(mirrorOf(bytes, context, process)); args.add(proxy.mirrorOf(0)); args.add(proxy.mirrorOf(bytes.length)); @@ -173,7 +196,7 @@ public class CompilingEvaluator implements ExpressionEvaluator { throws EvaluateException, InvalidTypeException, ClassNotLoadedException { ArrayType arrayClass = (ArrayType)process.findClass(context, "byte[]", context.getClassLoader()); ArrayReference reference = process.newInstance(arrayClass, bytes.length); - reference.disableCollection(); + keep(reference, context); for (int i = 0; i < bytes.length; i++) { reference.setValue(i, ((VirtualMachineProxyImpl)process.getVirtualMachineProxy()).mirrorOf(bytes[i])); } @@ -287,11 +310,15 @@ public class CompilingEvaluator implements ExpressionEvaluator { DebugProcess process = context.getDebugProcess(); ArrayType arrayType = (ArrayType)process.findClass(context, "java.net.URL[]", context.getClassLoader()); ArrayReference arrayRef = arrayType.newInstance(1); + keep(arrayRef, context); ClassType classType = (ClassType)process.findClass(context, "java.net.URL", context.getClassLoader()); VirtualMachineProxyImpl proxy = (VirtualMachineProxyImpl)process.getVirtualMachineProxy(); ThreadReference threadReference = context.getSuspendContext().getThread().getThreadReference(); + StringReference url = proxy.mirrorOf("file:a"); + keep(url, context); ObjectReference reference = classType.newInstance(threadReference, classType.concreteMethodByName("", "(Ljava/lang/String;)V"), - Arrays.asList(proxy.mirrorOf("file:a")), ClassType.INVOKE_SINGLE_THREADED); + Arrays.asList(url), ClassType.INVOKE_SINGLE_THREADED); + keep(reference, context); arrayRef.setValues(Arrays.asList(reference)); return arrayRef; } @@ -302,10 +329,23 @@ public class CompilingEvaluator implements ExpressionEvaluator { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); MemoryFileManager manager = new MemoryFileManager(compiler); DiagnosticCollector diagnostic = new DiagnosticCollector(); - if (!compiler.getTask(null, manager, diagnostic, null, null, Arrays - .asList(new SourceFileObject(getMainClassName(), JavaFileObject.Kind.SOURCE, getClassCode()))).call()) { - // TODO: show only errors - throw new EvaluateException(diagnostic.getDiagnostics().get(0).toString()); + Module module = ModuleUtilCore.findModuleForPsiElement(myPsiContext); + PathsList cp = null; + if (module != null) { + cp = ModuleRootManager.getInstance(module).orderEntries().compileOnly().recursively().exportedOnly().withoutSdk().getPathsList(); + } + if (!compiler.getTask(null, + manager, + diagnostic, + cp != null ? Arrays.asList("-cp", cp.getPathsString()) : null, + null, + Arrays.asList(new SourceFileObject(getMainClassName(), JavaFileObject.Kind.SOURCE, getClassCode())) + ).call()) { + StringBuilder res = new StringBuilder("Compilation failed:\n"); + for (Diagnostic d : diagnostic.getDiagnostics()) { + res.append(d); + } + throw new EvaluateException(res.toString()); } return manager.classes; } From 7ac690fdbe48a9dbd99d5896887a89415bffc5d9 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 15 Sep 2014 21:11:53 +0400 Subject: [PATCH 17/36] compiling evaluator - enable by default --- platform/util/resources/misc/registry.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 42f1e8473467..02fbfb37d3a1 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -169,7 +169,7 @@ debugger.breakpoint.message.full.trace=false debugger.breakpoint.message.full.trace.description='Log message to console' breakpoint action will out full stacktrace\ for the thread that hit the breakpoint. debugger.batch.evaluation=false -debugger.compiling.evaluator=false +debugger.compiling.evaluator=true debugger.watches.in.variables=false analyze.exceptions.on.the.fly=false From 8eada1dbaa32e2314ff48b8d7c5964a0986f3df4 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 15 Sep 2014 21:33:07 +0400 Subject: [PATCH 18/36] Don't use deprecated method. --- .../testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java b/python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java index 7de13d1ebed6..78111bb9fa7c 100644 --- a/python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java +++ b/python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java @@ -115,7 +115,7 @@ public class PyDebuggerTask extends PyBaseDebuggerTask { pyState.execute(executor, PyDebugRunner.createCommandLinePatchers(myFixture.getProject(), pyState, profile, serverLocalPort)); mySession = XDebuggerManager.getInstance(getProject()). - startSession(runner, env, env.getContentToReuse(), new XDebugProcessStarter() { + startSession(env, new XDebugProcessStarter() { @NotNull public XDebugProcess start(@NotNull final XDebugSession session) { myDebugProcess = From 0ab3144ef99ee59040d9f0b2fc50342317f9d2a9 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 15 Sep 2014 21:59:56 +0400 Subject: [PATCH 19/36] Use project-dependent name for the Current Project group --- .../ide/actions/ShowSettingsUtilImpl.java | 2 +- .../options/ex/SortedConfigurableGroup.java | 63 ++++--------------- .../src/messages/OptionsBundle.properties | 10 +-- 3 files changed, 19 insertions(+), 56 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java index 8d6f806802c2..04ad0fd1c97d 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java @@ -75,7 +75,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { new IdeConfigurablesGroup()}; return Registry.is("ide.new.settings.dialog") - ? new ConfigurableGroup[]{new SortedConfigurableGroup(getConfigurables(groups, true))} + ? new ConfigurableGroup[]{new SortedConfigurableGroup(project, getConfigurables(groups, true))} : groups; } diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/SortedConfigurableGroup.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/SortedConfigurableGroup.java index 3d87b7679359..5037d7f43b9a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/SortedConfigurableGroup.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/SortedConfigurableGroup.java @@ -19,6 +19,7 @@ import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; import com.intellij.openapi.options.OptionsBundle; import com.intellij.openapi.options.SearchableConfigurable; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -35,52 +36,6 @@ public final class SortedConfigurableGroup extends SearchableConfigurable.Parent.Abstract implements SearchableConfigurable, ConfigurableGroup, Configurable.NoScroll { - public static ConfigurableGroup getGroup(Configurable... configurables) { - SortedConfigurableGroup root = new SortedConfigurableGroup("root"); - HashMap map = new HashMap(); - map.put("root", root); - for (Configurable configurable : configurables) { - int weight = 0; - String groupId = null; - if (configurable instanceof ConfigurableWrapper) { - ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable; - weight = wrapper.getExtensionPoint().groupWeight; - groupId = wrapper.getExtensionPoint().groupId; - } - SortedConfigurableGroup composite = map.get(groupId); - if (composite == null) { - composite = new SortedConfigurableGroup(groupId); - map.put(groupId, composite); - } - composite.add(weight, configurable); - } - // process supported groups - root.add(60, map.remove("appearance")); - root.add(50, map.remove("editor")); - root.add(40, map.remove("project")); - SortedConfigurableGroup build = map.remove("build"); - if (build == null) { - build = map.remove("build.tools"); - } - else { - build.add(1000, map.remove("build.tools")); - } - root.add(30, build); - root.add(20, map.remove("language")); - root.add(10, map.remove("tools")); - root.add(-10, map.remove(null)); - // process unsupported groups - if (1 < map.size()) { - for (SortedConfigurableGroup group : map.values()) { - if (root != group) { - group.myDisplayName = "Category: " + group.myGroupId; - root.add(0, group); - } - } - } - return root; - } - private final ArrayList myList = new ArrayList(); private final String myGroupId; private String myDisplayName; @@ -89,7 +44,7 @@ public final class SortedConfigurableGroup myGroupId = groupId; } - public SortedConfigurableGroup(Configurable... configurables) { + public SortedConfigurableGroup(Project project, Configurable... configurables) { myGroupId = "root"; // create groups from configurations HashMap map = new HashMap(); @@ -110,9 +65,15 @@ public final class SortedConfigurableGroup composite.add(weight, configurable); } // process supported groups - add(60, map.remove("appearance")); - add(50, map.remove("editor")); - add(40, map.remove("project")); + add(70, map.remove("appearance")); + add(60, map.remove("editor")); + SortedConfigurableGroup projectGroup = map.remove("project"); + if (projectGroup != null && project != null && !project.isDefault()) { + projectGroup.myDisplayName = StringUtil.first( + OptionsBundle.message("configurable.group.project.named.settings.display.name", project.getName()), + 30, true); + } + add(40, projectGroup); SortedConfigurableGroup build = map.remove("build"); if (build == null) { build = map.remove("build.tools"); @@ -128,7 +89,7 @@ public final class SortedConfigurableGroup if (1 < map.size()) { for (SortedConfigurableGroup group : map.values()) { if (this != group) { - group.myDisplayName = "Category: " + group.myGroupId; + group.myDisplayName = OptionsBundle.message("configurable.group.category.named.settings.display.name", group.myGroupId); add(0, group); } } diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties index 537dec1d8f92..029a8fc0bc21 100644 --- a/platform/platform-resources-en/src/messages/OptionsBundle.properties +++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties @@ -198,7 +198,7 @@ options.xml.display.name=XML settings.panel.title=Settings -configurable.group.appearance.settings.display.name=Appearance and Behavior +configurable.group.appearance.settings.display.name=Appearance \\& Behavior configurable.group.appearance.settings.description=\ Personalize IntelliJ appearance and behavior: change themes and font size, tune the keymap,\ configure plugins and system settings, such as password policies, HTTP proxy, updates and more. @@ -207,9 +207,11 @@ configurable.group.editor.settings.description=\ Personalize source code appearance by changing fonts, highlighting styles, indents, etc.\ Customize the Editor from line numbers, caret placement and tabs to source code inspections,\ setting up templates and file encodings. -configurable.group.project.settings.display.name=Current Project +configurable.group.category.named.settings.display.name=Category: {0} +configurable.group.project.named.settings.display.name=Project: {0} +configurable.group.project.settings.display.name=Default Project configurable.group.project.settings.description=\ - Default view for Current Project + Project Settings configurable.group.build.settings.display.name=Build, Execution, Deployment configurable.group.build.settings.description=\ Configure you project integration with different build tools (Maven, Gradle or Gant),\ @@ -217,7 +219,7 @@ configurable.group.build.settings.description=\ configurable.group.build.tools.settings.display.name=Build Tools configurable.group.build.tools.settings.description=\ Configure your project integration with different build tools: Maven, Gradle or Gant. -configurable.group.language.settings.display.name=Languages and Frameworks +configurable.group.language.settings.display.name=Languages \\& Frameworks configurable.group.language.settings.description=\ Configure the settings related to specific frameworks and technologies used in your project. configurable.group.tools.settings.display.name=Tools From d4e1530492e6aec5d60c9c5190c0f4ae45da034e Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Mon, 15 Sep 2014 22:13:05 +0400 Subject: [PATCH 20/36] made tearDown safe (possible fix for sometimes failing BookmarkManagerTest.testBookmarkManagerDoesNotHardReferenceDocuments) --- .../actions/ReformatFilesWithFiltersTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java index dbc05f849a49..799e924c587d 100644 --- a/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java +++ b/platform/platform-tests/testSrc/com/intellij/codeInsight/actions/ReformatFilesWithFiltersTest.java @@ -47,10 +47,11 @@ public class ReformatFilesWithFiltersTest extends LightPlatformTestCase { @Override public void tearDown() throws Exception { - registerCodeStyleManager(myRealCodeStyleManger); - LanguageFormatting.INSTANCE.removeExplicitExtension(PlainTextLanguage.INSTANCE, myMockPlainTextFormattingModelBuilder); - - TestFileStructure.delete(myWorkingDirectory.getVirtualFile()); + if (myRealCodeStyleManger != null) registerCodeStyleManager(myRealCodeStyleManger); + if (myMockPlainTextFormattingModelBuilder != null) { + LanguageFormatting.INSTANCE.removeExplicitExtension(PlainTextLanguage.INSTANCE, myMockPlainTextFormattingModelBuilder); + } + if (myWorkingDirectory != null) TestFileStructure.delete(myWorkingDirectory.getVirtualFile()); super.tearDown(); } From 9f9b41d33dd4657e02176650a5abc40f228b9820 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 15 Sep 2014 21:16:53 +0200 Subject: [PATCH 21/36] use # to handle settings --- .../ide/ui/EditorOptionsTopHitProvider.java | 52 ++++++++++++++++ .../ide/ui/OptionsTopHitProvider.java | 60 +++++++++++++++++++ .../src/META-INF/PlatformExtensions.xml | 1 + 3 files changed, 113 insertions(+) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/OptionsTopHitProvider.java diff --git a/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java b/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java new file mode 100644 index 000000000000..fe88790a689b --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.ui; + +import com.intellij.ide.ui.search.BooleanOptionDescription; +import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public class EditorOptionsTopHitProvider extends OptionsTopHitProvider { + public EditorOptionsTopHitProvider() { + super("editor", createOptions()); + } + + private static Collection createOptions() { + final List options = new ArrayList(); + options.add(editor("IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS", "Mouse", "checkbox.honor.camelhumps.words.settings.on.double.click", + "Editor.Behavior")); + options.add(editor("IS_WHEEL_FONTCHANGE_ENABLED", "Mouse", SystemInfo.isMac ? "checkbox.enable.ctrl.mousewheel.changes.font.size.macos" : "checkbox.enable.ctrl.mousewheel.changes.font.size", "Editor.Behavior")); + options.add(editor("IS_DND_ENABLED", "Mouse", "checkbox.enable.drag.n.drop.functionality.in.editor", "Editor.Behavior")); + return options; + } + + static EditorOptionDescription editor(String fieldName, String group, String property, String configurableId) { + String name = ""; + if (!StringUtil.isEmpty(group)) { + name += group + ": "; + } + name += StringUtil.stripHtml(ApplicationBundle.message(property), false); + return new EditorOptionDescription(fieldName, name, configurableId); + } +} diff --git a/platform/platform-impl/src/com/intellij/ide/ui/OptionsTopHitProvider.java b/platform/platform-impl/src/com/intellij/ide/ui/OptionsTopHitProvider.java new file mode 100644 index 000000000000..633375e73ad3 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/OptionsTopHitProvider.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.ui; + +import com.intellij.ide.SearchTopHitProvider; +import com.intellij.ide.ui.search.BooleanOptionDescription; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.codeStyle.MinusculeMatcher; +import com.intellij.psi.codeStyle.NameUtil; +import com.intellij.util.Consumer; +import org.jetbrains.annotations.NonNls; + +import java.util.Collection; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public abstract class OptionsTopHitProvider implements SearchTopHitProvider { + @NonNls private final String myId; + private final Collection myOptions; + + public OptionsTopHitProvider(String optionId, Collection options) { + myId = optionId.toLowerCase(); + myOptions = options; + } + + @Override + public final void consumeTopHits(@NonNls String pattern, Consumer collector) { + if (!pattern.startsWith("#")) return; + pattern = pattern.substring(1); + final List parts = StringUtil.split(pattern, " "); + + if (parts.size() == 0) return; + + String id = parts.get(0); + if (myId.startsWith(id)) { + pattern = pattern.substring(id.length()).trim().toLowerCase(); + final MinusculeMatcher matcher = NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE); + for (BooleanOptionDescription option : myOptions) { + if (matcher.matches(option.getOption())) { + collector.consume(option); + } + } + } + } +} diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 2c1c7236c912..1930527f521a 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -329,6 +329,7 @@ implementationClass="com.intellij.codeStyle.InconsistentLineSeparatorsInspection"/> + From 19b68b3cdc58a9f419ab08aedcce2a2183149c67 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 15 Sep 2014 21:37:36 +0200 Subject: [PATCH 22/36] + virtual space --- .../ide/ui/EditorOptionsTopHitProvider.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java b/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java index fe88790a689b..b8ce4c8758a0 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java @@ -34,10 +34,17 @@ public class EditorOptionsTopHitProvider extends OptionsTopHitProvider { private static Collection createOptions() { final List options = new ArrayList(); - options.add(editor("IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS", "Mouse", "checkbox.honor.camelhumps.words.settings.on.double.click", - "Editor.Behavior")); - options.add(editor("IS_WHEEL_FONTCHANGE_ENABLED", "Mouse", SystemInfo.isMac ? "checkbox.enable.ctrl.mousewheel.changes.font.size.macos" : "checkbox.enable.ctrl.mousewheel.changes.font.size", "Editor.Behavior")); - options.add(editor("IS_DND_ENABLED", "Mouse", "checkbox.enable.drag.n.drop.functionality.in.editor", "Editor.Behavior")); + options.add(editorMouse("IS_MOUSE_CLICK_SELECTION_HONORS_CAMEL_WORDS", "checkbox.honor.camelhumps.words.settings.on.double.click")); + options.add(editorMouse("IS_WHEEL_FONTCHANGE_ENABLED", SystemInfo.isMac + ? "checkbox.enable.ctrl.mousewheel.changes.font.size.macos" + : "checkbox.enable.ctrl.mousewheel.changes.font.size")); + options.add(editorMouse("IS_DND_ENABLED", "checkbox.enable.drag.n.drop.functionality.in.editor")); + + options.add(editorVirtualSpace("IS_ALL_SOFTWRAPS_SHOWN", "checkbox.show.all.softwraps")); + options.add(editorVirtualSpace("IS_VIRTUAL_SPACE", "checkbox.allow.placement.of.caret.after.end.of.line")); + options.add(editorVirtualSpace("IS_CARET_INSIDE_TABS", "checkbox.allow.placement.of.caret.inside.tabs")); + options.add(editorVirtualSpace("ADDITIONAL_PAGE_AT_BOTTOM", "checkbox.show.virtual.space.at.file.bottom")); + return options; } @@ -49,4 +56,16 @@ public class EditorOptionsTopHitProvider extends OptionsTopHitProvider { name += StringUtil.stripHtml(ApplicationBundle.message(property), false); return new EditorOptionDescription(fieldName, name, configurableId); } + + static EditorOptionDescription editorMouse(String fieldName, String property) { + return editorBehavior(fieldName, "Mouse", property); + } + + static EditorOptionDescription editorVirtualSpace(String fieldName, String property) { + return editorBehavior(fieldName, "Virtual Space", property); + } + + static EditorOptionDescription editorBehavior(String fieldName, String group, String property) { + return editor(fieldName, group, property, "Editor.Behavior"); + } } From df12f7194b0ce8cbf2febc69e16653cbb0a2fbb8 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Mon, 15 Sep 2014 23:41:53 +0400 Subject: [PATCH 23/36] Python console file shouldn't be treated as physical. --- .../com/jetbrains/python/psi/impl/PyFileImpl.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java index 02b790622fe7..8bc55da9235b 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java @@ -24,6 +24,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.NonPhysicalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -729,7 +730,8 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression { public String extractDeprecationMessage() { if (canHaveDeprecationMessage(getText())) { return PyFunctionImpl.extractDeprecationMessage(getStatements()); - } else { + } + else { return null; } } @@ -894,4 +896,13 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression { } }; } + + @Override + public boolean isPhysical() { + VirtualFile virtualFile = getVirtualFile(); + if (virtualFile != null && virtualFile.getFileSystem() instanceof NonPhysicalFileSystem) { + return false; + } + return super.isPhysical(); + } } From 115f4c84d92535a4232e4e50cb4d386731678853 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 15 Sep 2014 22:15:41 +0200 Subject: [PATCH 24/36] avoid blinking in Search Everywhere --- .../ide/actions/SearchEverywhereAction.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index b00717330244..d8b424de8b7e 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -265,6 +265,20 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA final Dimension size = super.getPreferredSize(); return new Dimension(Math.min(size.width - 2, POPUP_MAX_WIDTH), size.height); } + + @Override + public void clearSelection() { + //avoid blinking + } + + @Override + public Object getSelectedValue() { + try { + return super.getSelectedValue(); + } catch (Exception e) { + return null; + } + } }; myList.setCellRenderer(myRenderer); myList.addMouseListener(new MouseAdapter() { @@ -1195,8 +1209,20 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA // this line must be called on EDT to avoid context switch at clear().append("text") Don't touch. Ask [kb] myList.getEmptyText().setText("Searching..."); - //noinspection unchecked - myList.setModel(myListModel); + myAlarm.cancelAllRequests(); + if (myList.getModel() instanceof SearchListModel) { + //noinspection unchecked + myAlarm.addRequest(new Runnable() { + @Override + public void run() { + if (!myDone.isRejected()) { + myList.setModel(myListModel); + } + } + }, 100); + } else { + myList.setModel(myListModel); + } } }); From d77471180b8e95633dd08e24aed13fc36050431e Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 16 Sep 2014 01:02:58 +0400 Subject: [PATCH 25/36] Better disposal in tests. --- .../env/python/debug/PyBaseDebuggerTask.java | 20 ++++++++++++++++--- .../env/python/debug/PyDebuggerTask.java | 7 ++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/python/testSrc/com/jetbrains/env/python/debug/PyBaseDebuggerTask.java b/python/testSrc/com/jetbrains/env/python/debug/PyBaseDebuggerTask.java index 38eed736c7ef..496204c1a42b 100644 --- a/python/testSrc/com/jetbrains/env/python/debug/PyBaseDebuggerTask.java +++ b/python/testSrc/com/jetbrains/env/python/debug/PyBaseDebuggerTask.java @@ -1,9 +1,11 @@ package com.jetbrains.env.python.debug; import com.google.common.collect.Sets; +import com.intellij.execution.ExecutionResult; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.JarFileSystem; @@ -37,6 +39,7 @@ public abstract class PyBaseDebuggerTask extends PyExecutionFixtureTestTask { protected Semaphore myTerminateSemaphore; protected boolean shouldPrintOutput = false; protected boolean myProcessCanTerminate; + protected ExecutionResult myExecutionResult; protected void waitForPause() throws InterruptedException, InvocationTargetException { Assert.assertTrue("Debugger didn't stopped within timeout\nOutput:" + output(), waitFor(myPausedSemaphore)); @@ -246,9 +249,8 @@ public abstract class PyBaseDebuggerTask extends PyExecutionFixtureTestTask { UIUtil.invokeAndWaitIfNeeded(new Runnable() { public void run() { try { - if (mySession != null) { - finishSession(); - } + finishSession(); + PyBaseDebuggerTask.super.tearDown(); } catch (Exception e) { @@ -271,10 +273,22 @@ public abstract class PyBaseDebuggerTask extends PyExecutionFixtureTestTask { waitFor(mySession.getDebugProcess().getProcessHandler()); //wait for process termination after session.stop() which is async XDebuggerTestUtil.disposeDebugSession(mySession); + mySession = null; myDebugProcess = null; myPausedSemaphore = null; } + + + if (myExecutionResult != null) { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + Disposer.dispose(myExecutionResult.getExecutionConsole()); + } + }); + myExecutionResult = null; + } } protected abstract void disposeDebugProcess() throws InterruptedException; diff --git a/python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java b/python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java index 78111bb9fa7c..f9da004ad3af 100644 --- a/python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java +++ b/python/testSrc/com/jetbrains/env/python/debug/PyDebuggerTask.java @@ -12,6 +12,7 @@ import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.xdebugger.*; import com.jetbrains.python.debugger.PyDebugProcess; @@ -111,7 +112,7 @@ public class PyDebuggerTask extends PyBaseDebuggerTask { new WriteAction() { @Override protected void run(@NotNull Result result) throws Throwable { - final ExecutionResult res = + myExecutionResult = pyState.execute(executor, PyDebugRunner.createCommandLinePatchers(myFixture.getProject(), pyState, profile, serverLocalPort)); mySession = XDebuggerManager.getInstance(getProject()). @@ -119,7 +120,7 @@ public class PyDebuggerTask extends PyBaseDebuggerTask { @NotNull public XDebugProcess start(@NotNull final XDebugSession session) { myDebugProcess = - new PyDebugProcess(session, serverSocket, res.getExecutionConsole(), res.getProcessHandler(), isMultiprocessDebug()); + new PyDebugProcess(session, serverSocket, myExecutionResult.getExecutionConsole(), myExecutionResult.getProcessHandler(), isMultiprocessDebug()); myDebugProcess.getProcessHandler().addProcessListener(new ProcessAdapter() { @@ -142,7 +143,7 @@ public class PyDebuggerTask extends PyBaseDebuggerTask { return myDebugProcess; } }); - result.setResult(res); + result.setResult(myExecutionResult); } }.execute().getResultObject(); From 079583f3f09f9512bf72a2f59f135bc9a73ba0bd Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 16 Sep 2014 01:03:42 +0400 Subject: [PATCH 26/36] Fix template exception breakpoints default. --- .../jetbrains/python/debugger/ExceptionBreakpointProperties.java | 1 + 1 file changed, 1 insertion(+) diff --git a/python/src/com/jetbrains/python/debugger/ExceptionBreakpointProperties.java b/python/src/com/jetbrains/python/debugger/ExceptionBreakpointProperties.java index 897b92c645b8..2c7c1db1644d 100644 --- a/python/src/com/jetbrains/python/debugger/ExceptionBreakpointProperties.java +++ b/python/src/com/jetbrains/python/debugger/ExceptionBreakpointProperties.java @@ -18,6 +18,7 @@ package com.jetbrains.python.debugger; import com.intellij.util.xmlb.annotations.Attribute; import com.intellij.xdebugger.breakpoints.XBreakpointProperties; import com.jetbrains.python.debugger.pydev.ExceptionBreakpointCommandFactory; +import com.sun.istack.internal.NotNull; /** * @author traff From 43517feaf95d22d3dab0f3ef775b8e563836154a Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Tue, 16 Sep 2014 02:30:01 +0400 Subject: [PATCH 27/36] +recurse --- spellchecker/src/com/intellij/spellchecker/english.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/spellchecker/src/com/intellij/spellchecker/english.dic b/spellchecker/src/com/intellij/spellchecker/english.dic index 0047044678a5..156c8e951221 100644 --- a/spellchecker/src/com/intellij/spellchecker/english.dic +++ b/spellchecker/src/com/intellij/spellchecker/english.dic @@ -106048,6 +106048,7 @@ recurrent recurrently recurring recurs +recurse recursion recursion's recursions From b963480d0526c128d721eb453d371697ce1c7d57 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 16 Sep 2014 01:38:19 +0200 Subject: [PATCH 28/36] change API to pass project --- .../src/com/intellij/ide/SearchTopHitProvider.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/SearchTopHitProvider.java b/platform/platform-api/src/com/intellij/ide/SearchTopHitProvider.java index 0015f224ab7e..81a00741cae9 100644 --- a/platform/platform-api/src/com/intellij/ide/SearchTopHitProvider.java +++ b/platform/platform-api/src/com/intellij/ide/SearchTopHitProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.ide; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; import com.intellij.util.Consumer; /** @@ -24,5 +25,5 @@ import com.intellij.util.Consumer; public interface SearchTopHitProvider { ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.search.topHitProvider"); - void consumeTopHits(String pattern, Consumer collector); + void consumeTopHits(String pattern, Consumer collector, Project project); } From b19edf03a50949beab388eed1a9492a681142bab Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 16 Sep 2014 01:39:23 +0200 Subject: [PATCH 29/36] API change --- .../src/com/intellij/ide/ActionsTopHitProvider.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/ActionsTopHitProvider.java b/platform/platform-api/src/com/intellij/ide/ActionsTopHitProvider.java index 1d1799129652..3b7e87a381cc 100644 --- a/platform/platform-api/src/com/intellij/ide/ActionsTopHitProvider.java +++ b/platform/platform-api/src/com/intellij/ide/ActionsTopHitProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package com.intellij.ide; import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Consumer; @@ -24,7 +25,7 @@ import com.intellij.util.Consumer; */ public abstract class ActionsTopHitProvider implements SearchTopHitProvider { @Override - public void consumeTopHits(String pattern, Consumer collector) { + public void consumeTopHits(String pattern, Consumer collector, Project project) { final ActionManager actionManager = ActionManager.getInstance(); for (String[] strings : getActionsMatrix()) { if (StringUtil.isBetween(pattern, strings[0], strings[1])) { From 9733598b05250d4a3cd4dc9bb02d35e52b57c9c2 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 16 Sep 2014 01:40:09 +0200 Subject: [PATCH 30/36] max 15 top hits --- .../com/intellij/ide/actions/SearchEverywhereAction.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index d8b424de8b7e..b32a9c9a69c1 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -97,6 +97,7 @@ import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.popup.AbstractPopup; import com.intellij.ui.popup.PopupPositionManager; import com.intellij.util.*; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.Matcher; import com.intellij.util.ui.EmptyIcon; import com.intellij.util.ui.StatusText; @@ -131,6 +132,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA private static final int MAX_RECENT_FILES = 10; private static final int DEFAULT_MORE_STEP_COUNT = 15; public static final int MAX_SEARCH_EVERYWHERE_HISTORY = 50; + public static final int MAX_TOP_HIT = 15; private static final int POPUP_MAX_WIDTH = 600; private static final Logger LOG = Logger.getInstance("#" + SearchEverywhereAction.class.getName()); @@ -1718,7 +1720,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA for (SearchTopHitProvider provider : SearchTopHitProvider.EP_NAME.getExtensions()) { check(); - provider.consumeTopHits(pattern, consumer); + provider.consumeTopHits(pattern, consumer, project); } if (elements.size() > 0) { SwingUtilities.invokeLater(new Runnable() { @@ -1727,7 +1729,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA if (isCanceled()) return; - for (Object element : elements.toArray()) { + for (Object element : new ArrayList(elements)) { if (element instanceof AnAction) { final AnAction action = (AnAction)element; final AnActionEvent e = new AnActionEvent(myActionEvent.getInputEvent(), @@ -1746,7 +1748,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } if (isCanceled() || elements.isEmpty()) return; myListModel.titleIndex.topHit = myListModel.size(); - for (Object element : elements) { + for (Object element : ContainerUtil.getFirstItems(elements, MAX_TOP_HIT)) { myListModel.addElement(element); } } From 2ade886ad93e98327a36ed718ab744adb66d125f Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 16 Sep 2014 01:42:27 +0200 Subject: [PATCH 31/36] a wrapper for inspection tool state in search everywhere --- .../ide/ui/ToolOptionDescription.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/ToolOptionDescription.java diff --git a/platform/platform-impl/src/com/intellij/ide/ui/ToolOptionDescription.java b/platform/platform-impl/src/com/intellij/ide/ui/ToolOptionDescription.java new file mode 100644 index 000000000000..211ab62b7101 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/ToolOptionDescription.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.ui; + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInspection.ex.Tools; +import com.intellij.ide.ui.search.BooleanOptionDescription; +import com.intellij.openapi.project.Project; + +/** + * @author Konstantin Bulenkov + */ +public class ToolOptionDescription extends BooleanOptionDescription { + private final Tools myTool; + private final Project myProject; + + public ToolOptionDescription(Tools tool, Project project) { + super(tool.getTool().getGroupDisplayName() + ": " + tool.getTool().getDisplayName() , "Errors"); + + myTool = tool; + myProject = project; + } + + @Override + public boolean isOptionEnabled() { + return myTool.getDefaultState().isEnabled(); + } + + @Override + public void setOptionState(boolean enabled) { + myTool.getDefaultState().setEnabled(enabled); + DaemonCodeAnalyzer.getInstance(myProject).restart(); + } +} From e4364b6e3e0954c169380eee2a629de66b9f68bb Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 16 Sep 2014 01:43:05 +0200 Subject: [PATCH 32/36] API change --- .../ide/ui/EditorOptionsTopHitProvider.java | 12 +++++++++++- .../com/intellij/ide/ui/OptionsTopHitProvider.java | 13 ++++++++----- .../intellij/ide/ui/UISimpleSettingsProvider.java | 5 +++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java b/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java index b8ce4c8758a0..4571b1c87a48 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/EditorOptionsTopHitProvider.java @@ -17,8 +17,10 @@ package com.intellij.ide.ui; import com.intellij.ide.ui.search.BooleanOptionDescription; import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Collection; @@ -28,8 +30,16 @@ import java.util.List; * @author Konstantin Bulenkov */ public class EditorOptionsTopHitProvider extends OptionsTopHitProvider { + private static final Collection ourOptions = createOptions(); + public EditorOptionsTopHitProvider() { - super("editor", createOptions()); + super("editor"); + } + + @NotNull + @Override + public Collection getOptions(Project project) { + return ourOptions; } private static Collection createOptions() { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/OptionsTopHitProvider.java b/platform/platform-impl/src/com/intellij/ide/ui/OptionsTopHitProvider.java index 633375e73ad3..e472efa7fa7c 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/OptionsTopHitProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/OptionsTopHitProvider.java @@ -17,11 +17,13 @@ package com.intellij.ide.ui; import com.intellij.ide.SearchTopHitProvider; import com.intellij.ide.ui.search.BooleanOptionDescription; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.util.Consumer; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.List; @@ -31,15 +33,16 @@ import java.util.List; */ public abstract class OptionsTopHitProvider implements SearchTopHitProvider { @NonNls private final String myId; - private final Collection myOptions; - public OptionsTopHitProvider(String optionId, Collection options) { + public OptionsTopHitProvider(String optionId) { myId = optionId.toLowerCase(); - myOptions = options; } + @NotNull + public abstract Collection getOptions(Project project); + @Override - public final void consumeTopHits(@NonNls String pattern, Consumer collector) { + public final void consumeTopHits(@NonNls String pattern, Consumer collector, Project project) { if (!pattern.startsWith("#")) return; pattern = pattern.substring(1); final List parts = StringUtil.split(pattern, " "); @@ -50,7 +53,7 @@ public abstract class OptionsTopHitProvider implements SearchTopHitProvider { if (myId.startsWith(id)) { pattern = pattern.substring(id.length()).trim().toLowerCase(); final MinusculeMatcher matcher = NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE); - for (BooleanOptionDescription option : myOptions) { + for (BooleanOptionDescription option : getOptions(project)) { if (matcher.matches(option.getOption())) { collector.consume(option); } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/UISimpleSettingsProvider.java b/platform/platform-impl/src/com/intellij/ide/ui/UISimpleSettingsProvider.java index d02916fd0215..6543d6f573a5 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/UISimpleSettingsProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/UISimpleSettingsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.intellij.ide.ui; import com.intellij.ide.SearchTopHitProvider; import com.intellij.ide.ui.search.OptionDescription; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Consumer; @@ -37,7 +38,7 @@ public class UISimpleSettingsProvider implements SearchTopHitProvider { @Override - public void consumeTopHits(String pattern, Consumer collector) { + public void consumeTopHits(String pattern, Consumer collector, Project project) { pattern = pattern.trim().toLowerCase(); if (StringUtil.isBetween(pattern, "cyc", "cyclic ") || StringUtil.isBetween(pattern, "scr", "scroll ")) { collector.consume(CYCLING_SCROLLING); From 0d2b7789c7ec0975f2cc11b6a46a5e1151a70c42 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 16 Sep 2014 01:43:28 +0200 Subject: [PATCH 33/36] inspection searcher for SE --- .../ide/ui/InspectionsTopHitProvider.java | 47 +++++++++++++++++++ .../src/META-INF/PlatformExtensions.xml | 1 + 2 files changed, 48 insertions(+) create mode 100644 platform/platform-impl/src/com/intellij/ide/ui/InspectionsTopHitProvider.java diff --git a/platform/platform-impl/src/com/intellij/ide/ui/InspectionsTopHitProvider.java b/platform/platform-impl/src/com/intellij/ide/ui/InspectionsTopHitProvider.java new file mode 100644 index 000000000000..165323e9349b --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/InspectionsTopHitProvider.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.ui; + +import com.intellij.codeInspection.ex.Tools; +import com.intellij.ide.ui.search.BooleanOptionDescription; +import com.intellij.openapi.project.Project; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author Konstantin Bulenkov + */ +public class InspectionsTopHitProvider extends OptionsTopHitProvider { + + public InspectionsTopHitProvider() { + super("inspections"); + } + + @NotNull + @Override + public Collection getOptions(Project project) { + ArrayList result = new ArrayList(); + List tools = InspectionProjectProfileManager.getInstance(project).getInspectionProfile().getAllEnabledInspectionTools(project); + for (Tools tool : tools) { + result.add(new ToolOptionDescription(tool, project)); + } + return result; + } +} diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 1930527f521a..f8c10406b0d7 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -330,6 +330,7 @@ + From c5d44ea9c2eab2d9ae6080454ab1789b4656dff3 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 15 Sep 2014 16:22:30 +0400 Subject: [PATCH 34/36] optimization: do not start inference to check caught thrown types if there is no thrown list at all (also helps to avoid calculations inside checked expression constraint during java 8 inference) --- .../intellij/codeInsight/ExceptionUtil.java | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index bb4e322a2eec..001016c8924a 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -412,42 +412,44 @@ public class ExceptionUtil { return Collections.emptyList(); } + final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes(); + if (thrownExceptions.length == 0) { + return Collections.emptyList(); + } + final PsiSubstitutor substitutor = result.getSubstitutor(); if (!isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) { - final PsiClassType[] thrownExceptions = method.getThrowsList().getReferencedTypes(); - if (thrownExceptions.length > 0) { - final PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile(); - final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall, containingFile); - try { - PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); - final List> candidates = ContainerUtil.mapNotNull( - processor.getResults(), new Function>() { - @Override - public Pair fun(CandidateInfo info) { - PsiElement element = info.getElement(); - if (element instanceof PsiMethod && - MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod)element) && - !MethodSignatureUtil.isSuperMethod((PsiMethod)element, method)) { - return Pair.create((PsiMethod)element, info.getSubstitutor()); - } - return null; + final PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile(); + final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall, containingFile); + try { + PsiScopesUtil.setupAndRunProcessor(processor, methodCall, false); + final List> candidates = ContainerUtil.mapNotNull( + processor.getResults(), new Function>() { + @Override + public Pair fun(CandidateInfo info) { + PsiElement element = info.getElement(); + if (element instanceof PsiMethod && + MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod)element) && + !MethodSignatureUtil.isSuperMethod((PsiMethod)element, method)) { + return Pair.create((PsiMethod)element, info.getSubstitutor()); } - }); - if (candidates.size() > 1) { - final List ex = collectSubstituted(substitutor, thrownExceptions); - for (Pair pair : candidates) { - final PsiClassType[] exceptions = pair.first.getThrowsList().getReferencedTypes(); - if (exceptions.length == 0) { - return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, PsiClassType.EMPTY_ARRAY); - } - retainExceptions(ex, collectSubstituted(pair.second, exceptions)); - } - return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()])); + return null; } + }); + if (candidates.size() > 1) { + final List ex = collectSubstituted(substitutor, thrownExceptions); + for (Pair pair : candidates) { + final PsiClassType[] exceptions = pair.first.getThrowsList().getReferencedTypes(); + if (exceptions.length == 0) { + return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, PsiClassType.EMPTY_ARRAY); + } + retainExceptions(ex, collectSubstituted(pair.second, exceptions)); + } + return getUnhandledExceptions(methodCall, topElement, PsiSubstitutor.EMPTY, ex.toArray(new PsiClassType[ex.size()])); } - catch (MethodProcessorSetupFailedException ignore) { - return Collections.emptyList(); - } + } + catch (MethodProcessorSetupFailedException ignore) { + return Collections.emptyList(); } } From dc988e848d87c0957810efc337f390d8d680656d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 15 Sep 2014 16:25:12 +0400 Subject: [PATCH 35/36] new inference: do not resolve method calls in lambda return expressions to check isPolyExpression when arguments do not contain potential constrains --- .../graphInference/InferenceSession.java | 28 +++++++++-- .../InferenceFromNestedIn2LambdasCall.java | 24 ++++++++++ .../GraphInferenceHighlightingTest.java | 5 -- .../daemon/lambda/InferredTypeTest.java | 39 +++++++++++++-- ...ceCollectingAdditionalConstraintsTest.java | 47 +++++++++++++++++++ .../lambda/NewLambdaHighlightingTest.java | 7 +-- 6 files changed, 131 insertions(+), 19 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/additionalConstraints/InferenceFromNestedIn2LambdasCall.java create mode 100644 java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewInferenceCollectingAdditionalConstraintsTest.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index a1b4570e5361..4c42a19d3ced 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -278,7 +278,7 @@ public class InferenceSession { //If the expression is a poly class instance creation expression (15.9) or a poly method invocation expression (15.12), //the set contains all constraint formulas that would appear in the set C when determining the poly expression's invocation type. final PsiMethod calledMethod = getCalledMethod((PsiCallExpression)arg); - if (PsiPolyExpressionUtil.isMethodCallPolyExpression(arg, calledMethod)) { + if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(arg, calledMethod)) { collectAdditionalConstraints(additionalConstraints, (PsiCallExpression)arg); } } else if (arg instanceof PsiLambdaExpression) { @@ -294,12 +294,32 @@ public class InferenceSession { return null; } + boolean found = false; + for (PsiExpression expression : argumentList.getExpressions()) { + expression = PsiUtil.skipParenthesizedExprDown(expression); + if (expression instanceof PsiConditionalExpression || + expression instanceof PsiCallExpression || + expression instanceof PsiLambdaExpression || + expression instanceof PsiMethodReferenceExpression) { + found = true; + break; + } + } + if (!found) { + return null; + } + MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList); if (properties != null) { return properties.getMethod(); } final JavaResolveResult resolveResult = getMethodResult(arg); - return resolveResult instanceof MethodCandidateInfo ? (PsiMethod)resolveResult.getElement() : null; + if (resolveResult instanceof MethodCandidateInfo) { + return (PsiMethod)resolveResult.getElement(); + } + else { + return null; + } } private void collectLambdaReturnExpression(Set additionalConstraints, @@ -319,7 +339,7 @@ public class InferenceSession { PsiType functionalType) { if (returnExpression instanceof PsiCallExpression) { final PsiMethod calledMethod = getCalledMethod((PsiCallExpression)returnExpression); - if (PsiPolyExpressionUtil.isMethodCallPolyExpression(returnExpression, calledMethod)) { + if (calledMethod != null && PsiPolyExpressionUtil.isMethodCallPolyExpression(returnExpression, calledMethod)) { collectAdditionalConstraints(additionalConstraints, (PsiCallExpression)returnExpression); } } @@ -365,7 +385,7 @@ public class InferenceSession { }; MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList); return properties != null ? null : - expression == null + expression == null || !PsiResolveHelper.ourGraphGuard.currentStack().contains(expression) ? computableResolve.compute() : PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, false, computableResolve); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/additionalConstraints/InferenceFromNestedIn2LambdasCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/additionalConstraints/InferenceFromNestedIn2LambdasCall.java new file mode 100644 index 000000000000..e6efba1ee65f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/additionalConstraints/InferenceFromNestedIn2LambdasCall.java @@ -0,0 +1,24 @@ +import java.util.List; + +class Test { + + interface A { + T m(T t); + } + + interface B { + List l(K k); + } + + F foo(A a) {return null;} + Bar bar(B b) { return null;} + + { + Integer i = foo(a -> bar(b -> asList(1, b))); + Integer i1 = foo(a -> bar(b -> asList(1, 1))); + } + + List asList(L l, L l1) { + return null; + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java index 69afb0db23bb..21b54f133b70 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java @@ -16,14 +16,11 @@ package com.intellij.codeInsight.daemon.lambda; import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; -import com.intellij.idea.Bombed; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; -import java.util.Calendar; - public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase { @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/graphInference"; @@ -47,12 +44,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) public void testInferenceFromSiblings() throws Exception { doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) public void testChainedInferenceTypeParamsOrderIndependent() throws Exception { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferredTypeTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferredTypeTest.java index 541a519b8099..c116a058493f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferredTypeTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferredTypeTest.java @@ -15,10 +15,8 @@ */ package com.intellij.codeInsight.daemon.lambda; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiIdentifier; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; @@ -44,6 +42,39 @@ public class InferredTypeTest extends LightCodeInsightFixtureTestCase { Assert.assertTrue(type.getCanonicalText(), type.equalsToText("java.util.List")); } + public void testCashedTypes() throws Exception { + myFixture.configureByText("a.java", "import java.util.*;\n" + + "abstract class Main {\n" + + " void test(List li) {\n" + + " foo(li, s -> s.substr(0), Collections.emptyList());\n" + + " }\n" + + " abstract Collection foo(Collection coll, Fun, U> f, List it);" + + " interface Stream {\n" + + " T substr(long startingOffset);\n" + + " }\n" + + " interface Fun {\n" + + " R _(T t);\n" + + " }\n" + + "}\n"); + final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); + Assert.assertTrue(elementAtCaret instanceof PsiIdentifier); + + final PsiElement refExpr = elementAtCaret.getParent(); + Assert.assertTrue(refExpr.toString(), refExpr instanceof PsiExpression); + final PsiType type = ((PsiExpression)refExpr).getType(); + Assert.assertNotNull(refExpr.toString(), type); + Assert.assertTrue(type.getCanonicalText(), type.equalsToText("Stream")); + + final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(refExpr, PsiExpressionList.class); + assertNotNull(expressionList); + final PsiExpression[] expressions = expressionList.getExpressions(); + assertEquals(3, expressions.length); + + final PsiType ensureNotCached = expressions[2].getType(); + assertNotNull(ensureNotCached); + assertTrue(ensureNotCached.getCanonicalText(), ensureNotCached.equalsToText("java.util.List")); + } + @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewInferenceCollectingAdditionalConstraintsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewInferenceCollectingAdditionalConstraintsTest.java new file mode 100644 index 000000000000..960185e4b637 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewInferenceCollectingAdditionalConstraintsTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.daemon.lambda; + +import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.testFramework.IdeaTestUtil; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class NewInferenceCollectingAdditionalConstraintsTest extends LightDaemonAnalyzerTestCase { + @NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/additionalConstraints"; + + public void testInferenceFromNestedIn2LambdasCall() throws Exception { + doTest(); + } + + private void doTest() { + doTest(true); + } + + private void doTest(boolean warnings) { + IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable()); + doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, false); + } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk18(); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index ac2ba93420d3..8acafbc3dbbc 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -73,23 +73,20 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA121315() { doTest(); } public void testIDEA118965comment() { doTest(); } public void testIDEA122074() { doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) public void testIDEA122084() { doTest(); } public void testAdditionalConstraintDependsOnNonMentionedVars() { doTest(); } public void testIDEA122616() { doTest(); } public void testIDEA122700() { doTest(); } public void testIDEA122406() { doTest(); } public void testNestedCallsInsideLambdaReturnExpression() { doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) public void testIDEA123731() { doTest(); } public void testIDEA123869() { doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) public void testIDEA123848() { doTest(); } public void testOnlyLambdaAtTypeParameterPlace() { doTest(); } public void testLiftedIntersectionType() { doTest(); } public void testInferenceFromReturnStatements() { doTest(); } public void testDownUpThroughLambdaReturnStatements() { doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) + @Bombed(day = 30, month = Calendar.OCTOBER) public void testIDEA124547() { doTest(); } public void testIDEA118362() { doTest(); } public void testIDEA126056() { doTest(); } @@ -100,7 +97,6 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA124424() { doTest(); } public void testNestedLambdaExpressions1() { doTest(); } public void testNestedLambdaExpressionsNoFormalParams() { doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) public void testNestedLambdaExpressionsNoFormalParams1() { doTest(); } public void testDeepNestedLambdaExpressionsNoFormalParams() { doTest(); } public void testNestedLambdaExpressionsNoFormalParamsStopAtStandalone() { doTest(); } @@ -128,7 +124,6 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } - @Bombed(day = 30, month = Calendar.SEPTEMBER) public void testIDEA126778() throws Exception { doTest(); } From 800f508c44948619d59bc3adcc7c08ed7278c25d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 15 Sep 2014 17:43:22 +0400 Subject: [PATCH 36/36] new inference: prohibit substitution during checked exception constraint processing --- .../intellij/codeInsight/ExceptionUtil.java | 25 ++++++++++++++-- ...eckedExceptionCompatibilityConstraint.java | 13 +++++++-- ...tedLambdaCheckedExceptionsConstraints.java | 29 +++++++++++++++++++ .../lambda/NewLambdaHighlightingTest.java | 4 +++ 4 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/NestedLambdaCheckedExceptionsConstraints.java diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java index 001016c8924a..abb7d3fc5038 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java @@ -16,11 +16,15 @@ package com.intellij.codeInsight; import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.RecursionGuard; +import com.intellij.openapi.util.RecursionManager; import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.infos.CandidateInfo; +import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.scope.MethodProcessorSetupFailedException; import com.intellij.psi.scope.processor.MethodResolverProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; @@ -41,6 +45,7 @@ import java.util.*; */ public class ExceptionUtil { @NonNls private static final String CLONE_METHOD_NAME = "clone"; + public static final RecursionGuard ourThrowsGuard = RecursionManager.createGuard("checkedExceptionsGuard"); private ExceptionUtil() {} @@ -417,7 +422,7 @@ public class ExceptionUtil { return Collections.emptyList(); } - final PsiSubstitutor substitutor = result.getSubstitutor(); + final PsiSubstitutor substitutor = getSubstitutor(result, methodCall); if (!isArrayClone(method, methodCall) && methodCall instanceof PsiMethodCallExpression) { final PsiFile containingFile = (containingMethod == null ? methodCall : containingMethod).getContainingFile(); final MethodResolverProcessor processor = new MethodResolverProcessor((PsiMethodCallExpression)methodCall, containingFile); @@ -431,7 +436,7 @@ public class ExceptionUtil { if (element instanceof PsiMethod && MethodSignatureUtil.areSignaturesEqual(method, (PsiMethod)element) && !MethodSignatureUtil.isSuperMethod((PsiMethod)element, method)) { - return Pair.create((PsiMethod)element, info.getSubstitutor()); + return Pair.create((PsiMethod)element, getSubstitutor(info, methodCall)); } return null; } @@ -456,6 +461,22 @@ public class ExceptionUtil { return getUnhandledExceptions(method, methodCall, topElement, substitutor); } + private static PsiSubstitutor getSubstitutor(final JavaResolveResult result, PsiCallExpression methodCall) { + final PsiLambdaExpression expression = PsiTreeUtil.getParentOfType(methodCall, PsiLambdaExpression.class); + final PsiSubstitutor substitutor; + if (expression != null) { + substitutor = ourThrowsGuard.doPreventingRecursion(expression, false, new Computable() { + @Override + public PsiSubstitutor compute() { + return result.getSubstitutor(); + } + }); + } else { + substitutor = result.getSubstitutor(); + } + return substitutor == null ? ((MethodCandidateInfo)result).getSiteSubstitutor() : substitutor; + } + public static void retainExceptions(List ex, List thrownEx) { final List replacement = new ArrayList(); for (Iterator iterator = ex.iterator(); iterator.hasNext(); ) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java index a629175b9d48..f731b25c861b 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/CheckedExceptionCompatibilityConstraint.java @@ -17,6 +17,7 @@ package com.intellij.psi.impl.source.resolve.graphInference.constraints; import com.intellij.codeInsight.ExceptionUtil; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Computable; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession; import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable; @@ -101,9 +102,17 @@ public class CheckedExceptionCompatibilityConstraint extends InputOutputConstrai final List thrownTypes = new ArrayList(); if (myExpression instanceof PsiLambdaExpression) { - PsiElement body = ((PsiLambdaExpression)myExpression).getBody(); + final PsiElement body = ((PsiLambdaExpression)myExpression).getBody(); if (body != null) { - thrownTypes.addAll(ExceptionUtil.getUnhandledExceptions(body)); + final List exceptions = ExceptionUtil.ourThrowsGuard.doPreventingRecursion(myExpression, false, new Computable>() { + @Override + public List compute() { + return ExceptionUtil.getUnhandledExceptions(body); + } + }); + if (exceptions != null) { + thrownTypes.addAll(exceptions); + } } } else { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/NestedLambdaCheckedExceptionsConstraints.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/NestedLambdaCheckedExceptionsConstraints.java new file mode 100644 index 000000000000..5f28e5663f78 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/NestedLambdaCheckedExceptionsConstraints.java @@ -0,0 +1,29 @@ +import java.io.IOException; +import java.util.List; + +class Test { + + interface A { + T m(T t); + } + + interface B { + List l(K k) throws IOException; + } + + F foo(A a) { + return null; + } + + R bar(B b) { + return null; + } + + List baz(Z l) throws IOException{ + return null; + } + + { + Integer i = foo(a -> bar(b -> baz(b))); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 8acafbc3dbbc..59450964394a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -101,6 +101,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { public void testDeepNestedLambdaExpressionsNoFormalParams() { doTest(); } public void testNestedLambdaExpressionsNoFormalParamsStopAtStandalone() { doTest(); } + public void testNestedLambdaCheckedExceptionsConstraints() throws Exception { + doTest(); + } + public void testIDEA127596() throws Exception { doTest(); }