From c81fcb5004ea02bbab484482ce4ad2b855f8ed97 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Thu, 17 Mar 2016 15:36:51 +0300 Subject: [PATCH 01/35] PY-18739 Union types are generated in PEP 484 compatible format --- python/pydevSrc/com/jetbrains/python/debugger/PySignature.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java b/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java index 9d13e6421554..521e6d17f155 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java @@ -120,7 +120,7 @@ public class PySignature { return myTypes.get(0); } else { - return StringUtil.join(myTypes, " or "); + return "Union[" + StringUtil.join(myTypes, ", ") + "]"; } } From 243c730c82e3c374ae940e0a2ca0fd1de0f38b1f Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Thu, 17 Mar 2016 16:06:42 +0300 Subject: [PATCH 02/35] PY-18788 Don't generate type annotations for "self" parameters --- .../python/codeInsight/intentions/PyAnnotateTypesIntention.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyAnnotateTypesIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyAnnotateTypesIntention.java index 3f91a6a692aa..0d0605d527cd 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyAnnotateTypesIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyAnnotateTypesIntention.java @@ -203,7 +203,7 @@ public class PyAnnotateTypesIntention implements IntentionAction { PyParameter[] params = function.getParameterList().getParameters(); for (int i = params.length - 1; i >= 0; i--) { - if (params[i] instanceof PyNamedParameter) { + if (params[i] instanceof PyNamedParameter && !params[i].isSelf()) { params[i] = annotateParameter(project, editor, (PyNamedParameter)params[i], false); } } From acbf0524e5f369dcaf53124ccbb19fc43c6b0fec Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Thu, 17 Mar 2016 17:43:52 +0300 Subject: [PATCH 03/35] PY-18803 Annotate Types inserts return type annotation over the old one, not after --- .../SpecifyTypeInPy3AnnotationsIntention.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInPy3AnnotationsIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInPy3AnnotationsIntention.java index f9b41ab1c7b7..a2b2735c5aa1 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInPy3AnnotationsIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/SpecifyTypeInPy3AnnotationsIntention.java @@ -137,8 +137,7 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention { static String returnType(@NotNull PyFunction function) { String returnType = PyNames.OBJECT; - final PySignature signature = PySignatureCacheManager.getInstance(function.getProject()).findSignature( - function); + final PySignature signature = PySignatureCacheManager.getInstance(function.getProject()).findSignature(function); if (signature != null) { returnType = ObjectUtils.chooseNotNull(signature.getReturnTypeQualifiedName(), returnType); } @@ -148,22 +147,28 @@ public class SpecifyTypeInPy3AnnotationsIntention extends TypeIntention { public static PyExpression annotateReturnType(Project project, PyFunction function, boolean createTemplate) { String returnType = returnType(function); - final String annotationText = " -> " + returnType; - - final PsiElement prevElem = PyPsiUtils.getPrevNonCommentSibling(function.getStatementList(), true); - assert prevElem != null; + final String annotationText = "-> " + returnType; final PsiDocumentManager manager = PsiDocumentManager.getInstance(project); Document documentWithCallable = manager.getDocument(function.getContainingFile()); if (documentWithCallable != null) { try { - final TextRange range = prevElem.getTextRange(); manager.doPostponedOperationsAndUnblockDocument(documentWithCallable); - if (prevElem.getNode().getElementType() == PyTokenTypes.COLON) { - documentWithCallable.insertString(range.getStartOffset(), annotationText); + final PyAnnotation oldAnnotation = function.getAnnotation(); + if (oldAnnotation != null) { + final TextRange oldRange = oldAnnotation.getTextRange(); + documentWithCallable.replaceString(oldRange.getStartOffset(), oldRange.getEndOffset(), annotationText); } else { - documentWithCallable.insertString(range.getEndOffset(), annotationText + ":"); + final PsiElement prevElem = PyPsiUtils.getPrevNonCommentSibling(function.getStatementList(), true); + assert prevElem != null; + final TextRange range = prevElem.getTextRange(); + if (prevElem.getNode().getElementType() == PyTokenTypes.COLON) { + documentWithCallable.insertString(range.getStartOffset(), " " + annotationText); + } + else { + documentWithCallable.insertString(range.getEndOffset(), " " + annotationText + ":"); + } } } finally { From f94a753e21492d3c6c329316fc76e424824914f5 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Thu, 17 Mar 2016 18:45:31 +0300 Subject: [PATCH 04/35] PY-18820 Use None instead of NoneType in generated annotations to conform to PEP 484 Probably it should be fixed on debugger side later, though. --- .../com/jetbrains/python/debugger/PySignature.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java b/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java index 521e6d17f155..03192a47eb97 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PySignature.java @@ -117,13 +117,18 @@ public class PySignature { public String getTypeQualifiedName() { if (myTypes.size() == 1) { - return myTypes.get(0); + return noneTypeToNone(myTypes.get(0)); } else { - return "Union[" + StringUtil.join(myTypes, ", ") + "]"; + return "Union[" + StringUtil.join(myTypes, NamedParameter::noneTypeToNone, ", ") + "]"; } } + @Nullable + private static String noneTypeToNone(@Nullable String type) { + return "NoneType".equals(type) ? "None" : type; + } + public void addType(String type) { if (!myTypes.contains(type)) { myTypes.add(type); From 0234922fd0c0531f37625e3ec39e409d1cffe2df Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 17 Mar 2016 19:08:10 +0300 Subject: [PATCH 05/35] EA-80750 - assert: AnAction.setShortcutSet before this fix, it worked only for the first search field in IDE, because after the first time the shortcut is no longer empty (we registered it), and action was not registered on component any more. --- .../platform-api/src/com/intellij/ui/SearchTextField.java | 5 +---- platform/platform-resources/src/idea/Keymap_Default.xml | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/SearchTextField.java b/platform/platform-api/src/com/intellij/ui/SearchTextField.java index 58fbfd79909f..f79d7528e371 100644 --- a/platform/platform-api/src/com/intellij/ui/SearchTextField.java +++ b/platform/platform-api/src/com/intellij/ui/SearchTextField.java @@ -18,7 +18,6 @@ package com.intellij.ui; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.CommonShortcuts; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.JBMenuItem; @@ -204,9 +203,7 @@ public class SearchTextField extends JPanel { final ActionManager actionManager = ActionManager.getInstance(); if (actionManager != null) { final AnAction clearTextAction = actionManager.getAction(IdeActions.ACTION_CLEAR_TEXT); - if (clearTextAction.getShortcutSet().getShortcuts().length == 0) { - clearTextAction.registerCustomShortcutSet(CommonShortcuts.ESCAPE, this); - } + clearTextAction.registerCustomShortcutSet(clearTextAction.getShortcutSet(), this); } } } diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml index d55e485180aa..83773d111b93 100644 --- a/platform/platform-resources/src/idea/Keymap_Default.xml +++ b/platform/platform-resources/src/idea/Keymap_Default.xml @@ -15,9 +15,9 @@ - + From 4b90c97d62b28c2ddf0d8fce6052da9fc3457c15 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Thu, 17 Mar 2016 19:00:20 +0300 Subject: [PATCH 06/35] ToolbarDecor: multi-selection movements --- .../intellij/ui/TableToolbarDecorator.java | 63 +++++++++---------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/TableToolbarDecorator.java b/platform/platform-api/src/com/intellij/ui/TableToolbarDecorator.java index af62010bc1c0..2f6155cf2b8e 100644 --- a/platform/platform-api/src/com/intellij/ui/TableToolbarDecorator.java +++ b/platform/platform-api/src/com/intellij/ui/TableToolbarDecorator.java @@ -15,6 +15,7 @@ */ package com.intellij.ui; +import com.intellij.util.ArrayUtil; import com.intellij.util.ui.EditableModel; import com.intellij.util.ui.ElementProducer; import com.intellij.util.ui.ListTableModel; @@ -27,6 +28,7 @@ import javax.swing.event.ListSelectionListener; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import java.util.Arrays; /** * @author Konstantin Bulenkov @@ -149,46 +151,41 @@ class TableToolbarDecorator extends ToolbarDecorator { } }; - myUpAction = new AnActionButtonRunnable() { + class MoveRunnable implements AnActionButtonRunnable { + final int delta; + + MoveRunnable(int delta) { + this.delta = delta; + } + @Override - public void run(AnActionButton button) { - final int row = table.getEditingRow(); - final int col = table.getEditingColumn(); + public void run(AnActionButton button) { + int row = table.getEditingRow(); + int col = table.getEditingColumn(); TableUtil.stopEditing(table); - final int[] indexes = table.getSelectedRows(); - for (int index : indexes) { - if (0 < index && index < table.getModel().getRowCount()) { - tableModel.exchangeRows(index, index - 1); - table.setRowSelectionInterval(index - 1, index - 1); - } - } + int[] idx = table.getSelectedRows(); + Arrays.sort(idx); + if (delta > 0) { + idx = ArrayUtil.reverseArray(idx); + } + + if (idx.length == 0) return; + if (idx[0] + delta < 0) return; + if (idx[idx.length - 1] + delta > table.getModel().getRowCount()) return; + + for (int i = 0; i < idx.length; i++) { + tableModel.exchangeRows(idx[i], idx[i] + delta); + idx[i] += delta; + } + TableUtil.selectRows(table, idx); table.requestFocus(); if (row > 0 && col != -1) { table.editCellAt(row - 1, col); } } - }; - - myDownAction = new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - final int row = table.getEditingRow(); - final int col = table.getEditingColumn(); - - TableUtil.stopEditing(table); - final int[] indexes = table.getSelectedRows(); - for (int index : indexes) { - if (0 <= index && index < table.getModel().getRowCount() - 1) { - tableModel.exchangeRows(index, index + 1); - table.setRowSelectionInterval(index + 1, index + 1); - } - } - table.requestFocus(); - if (row < table.getRowCount() - 1 && col != -1) { - table.editCellAt(row + 1, col); - } - } - }; + } + myUpAction = new MoveRunnable(-1); + myDownAction = new MoveRunnable(1); } @Override From 4480577c81957b9cb055f6e7221f766c5494951b Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Thu, 17 Mar 2016 18:47:04 +0300 Subject: [PATCH 07/35] Use saved modules for gevent (PY-14992) --- python/helpers/pydev/_pydev_bundle/pydev_monkey.py | 10 ++++------ python/helpers/pydev/_pydevd_bundle/pydevd_comm.py | 1 + 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/python/helpers/pydev/_pydev_bundle/pydev_monkey.py b/python/helpers/pydev/_pydev_bundle/pydev_monkey.py index f692ece44586..a2f951996273 100644 --- a/python/helpers/pydev/_pydev_bundle/pydev_monkey.py +++ b/python/helpers/pydev/_pydev_bundle/pydev_monkey.py @@ -566,12 +566,10 @@ _UseNewThreadStartup = _NewThreadStartupWithTrace def _get_threading_modules_to_patch(): threading_modules_to_patch = [] - try: - import thread as _thread - threading_modules_to_patch.append(_thread) - except: - import _thread # @UnresolvedImport @Reimport - threading_modules_to_patch.append(_thread) + + from _pydev_imps._pydev_saved_modules import thread as _thread + threading_modules_to_patch.append(_thread) + return threading_modules_to_patch threading_modules_to_patch = _get_threading_modules_to_patch() diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py b/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py index 14fb74d11792..d3c12f164dbb 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py @@ -61,6 +61,7 @@ each command has a format: from _pydev_bundle.pydev_imports import _queue from _pydev_imps._pydev_saved_modules import time from _pydev_imps._pydev_saved_modules import thread +from _pydev_imps._pydev_saved_modules import threading from _pydev_imps._pydev_saved_modules import socket from socket import socket, AF_INET, SOCK_STREAM, SHUT_RD, SHUT_WR from _pydevd_bundle.pydevd_constants import * #@UnusedWildImport From b87a11401ca4201b966b8f1802bc1813b97cf920 Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Thu, 17 Mar 2016 19:27:08 +0300 Subject: [PATCH 08/35] Minors after review again (PY-14992) --- .../pydev/_pydev_imps/_pydev_saved_modules.py | 26 +++++-------------- .../pydev/_pydevd_bundle/pydevd_constants.py | 5 ++++ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/python/helpers/pydev/_pydev_imps/_pydev_saved_modules.py b/python/helpers/pydev/_pydev_imps/_pydev_saved_modules.py index 16fe21bd25db..6ff3939d7b39 100644 --- a/python/helpers/pydev/_pydev_imps/_pydev_saved_modules.py +++ b/python/helpers/pydev/_pydev_imps/_pydev_saved_modules.py @@ -1,15 +1,8 @@ import sys -IS_PY2 = True -if sys.version_info[0] >= 3: - IS_PY2 = False +IS_PY2 = sys.version_info < (3,) import threading -if IS_PY2: - import thread -else: - import _thread as thread - import time import socket @@ -17,21 +10,14 @@ import socket import select if IS_PY2: + import thread import Queue as _queue -else: - import queue as _queue - -if IS_PY2: import xmlrpclib -else: - import xmlrpc.client as xmlrpclib - -if IS_PY2: import SimpleXMLRPCServer as _pydev_SimpleXMLRPCServer -else: - import xmlrpc.server as _pydev_SimpleXMLRPCServer - -if IS_PY2: import BaseHTTPServer else: + import _thread as thread + import queue as _queue + import xmlrpc.client as xmlrpclib + import xmlrpc.server as _pydev_SimpleXMLRPCServer import http.server as BaseHTTPServer \ No newline at end of file diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py b/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py index 50d1b971a469..9516c1455f9b 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py @@ -102,6 +102,11 @@ USE_LIB_COPY = SUPPORT_GEVENT and \ def protect_libraries_from_patching(): + """ + In this function we delete some modules from `sys.modules` dictionary and import them again inside + `_pydev_saved_modules` in order to save their original copies there. After that we can use these + saved modules within the debugger to protect them from patching by external libraries (e.g. gevent). + """ patched = ['threading', 'thread', '_thread', 'time', 'socket', 'Queue', 'queue', 'select', 'xmlrpclib', 'SimpleXMLRPCServer', 'BaseHTTPServer', 'SocketServer', 'xmlrpc.client', 'xmlrpc.server', 'http.server', 'socketserver'] From 365ae7a6c2c3eb529a070caa5405b025e380204e Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 17 Mar 2016 19:42:04 +0300 Subject: [PATCH 09/35] editor: do not erase text on escape fixup for 0234922 --- .../platform-api/src/com/intellij/ui/SearchTextField.java | 6 +++--- platform/platform-resources/src/idea/Keymap_Default.xml | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/SearchTextField.java b/platform/platform-api/src/com/intellij/ui/SearchTextField.java index f79d7528e371..4540d2ee1fbb 100644 --- a/platform/platform-api/src/com/intellij/ui/SearchTextField.java +++ b/platform/platform-api/src/com/intellij/ui/SearchTextField.java @@ -17,7 +17,8 @@ package com.intellij.ui; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.CommonShortcuts; +import com.intellij.openapi.actionSystem.EmptyAction; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.ui.JBMenuItem; @@ -202,8 +203,7 @@ public class SearchTextField extends JPanel { if (ApplicationManager.getApplication() != null) { //tests final ActionManager actionManager = ActionManager.getInstance(); if (actionManager != null) { - final AnAction clearTextAction = actionManager.getAction(IdeActions.ACTION_CLEAR_TEXT); - clearTextAction.registerCustomShortcutSet(clearTextAction.getShortcutSet(), this); + EmptyAction.registerWithShortcutSet(IdeActions.ACTION_CLEAR_TEXT, CommonShortcuts.ESCAPE, this); } } } diff --git a/platform/platform-resources/src/idea/Keymap_Default.xml b/platform/platform-resources/src/idea/Keymap_Default.xml index 83773d111b93..a843d5c6cf53 100644 --- a/platform/platform-resources/src/idea/Keymap_Default.xml +++ b/platform/platform-resources/src/idea/Keymap_Default.xml @@ -15,9 +15,6 @@ - - - From daa9f7901f920e590bc654b475063015ae579709 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 11:17:16 +0100 Subject: [PATCH 10/35] EA-80288 (IOE: PsiElementFactoryImpl.createKeyword) --- .../siyeh/ig/classlayout/UtilityClassCanBeEnumInspection.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/UtilityClassCanBeEnumInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/UtilityClassCanBeEnumInspection.java index 7b5416fa6975..cfe033dd2498 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/UtilityClassCanBeEnumInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/UtilityClassCanBeEnumInspection.java @@ -72,6 +72,9 @@ public class UtilityClassCanBeEnumInspection extends BaseInspection { @Override protected void doFix(Project project, ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); + if (!PsiUtil.isLanguageLevel5OrHigher(element)) { + return; + } final PsiElement parent = element.getParent(); if (!(parent instanceof PsiClass)) { return; From e12a62a318bd1640b4f57711c14d2319a76342b0 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 11:48:21 +0100 Subject: [PATCH 11/35] EA-54946 (IOE: PsiJavaParserFacadeImpl.createExpressionFromText) --- .../ImplicitNumericConversionInspection.java | 36 ++++++++++++------- .../HexadecimalLiteral.after.java | 6 ++++ .../HexadecimalLiteral.java | 6 ++++ .../ImplicitNumericConversionFixTest.java | 7 ++-- 4 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/numeric/implicit_numeric_conversion/HexadecimalLiteral.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/numeric/implicit_numeric_conversion/HexadecimalLiteral.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ImplicitNumericConversionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ImplicitNumericConversionInspection.java index 18e650160ade..92f21d4d0ce9 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ImplicitNumericConversionInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/ImplicitNumericConversionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2016 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -156,27 +156,35 @@ public class ImplicitNumericConversionInspection extends BaseInspection { if (expressionType == null) { return null; } + final String text = expression.getText(); if (expressionType.equals(PsiType.INT) && expectedType.equals(PsiType.LONG)) { - return expression.getText() + 'L'; + return text + 'L'; } if (expressionType.equals(PsiType.INT) && expectedType.equals(PsiType.FLOAT)) { - return expression.getText() + ".0F"; + if (!isDecimalLiteral(text)) { + return null; + } + return text + ".0F"; } if (expressionType.equals(PsiType.INT) && expectedType.equals(PsiType.DOUBLE)) { - return expression.getText() + ".0"; + if (!isDecimalLiteral(text)) { + return null; + } + return text + ".0"; } if (expressionType.equals(PsiType.LONG) && expectedType.equals(PsiType.FLOAT)) { - final String text = expression.getText(); - final int length = text.length(); - return text.substring(0, length - 1) + ".0F"; + if (!isDecimalLiteral(text)) { + return null; + } + return text.substring(0, text.length() - 1) + ".0F"; } if (expressionType.equals(PsiType.LONG) && expectedType.equals(PsiType.DOUBLE)) { - final String text = expression.getText(); - final int length = text.length(); - return text.substring(0, length - 1) + ".0"; + if (!isDecimalLiteral(text)) { + return null; + } + return text.substring(0, text.length() - 1) + ".0"; } if (expressionType.equals(PsiType.DOUBLE) && expectedType.equals(PsiType.FLOAT)) { - final String text = expression.getText(); final int length = text.length(); if (text.charAt(length - 1) == 'd' || text.charAt(length - 1) == 'D') { return text.substring(0, length - 1) + 'F'; @@ -186,13 +194,17 @@ public class ImplicitNumericConversionInspection extends BaseInspection { } } if (expressionType.equals(PsiType.FLOAT) && expectedType.equals(PsiType.DOUBLE)) { - final String text = expression.getText(); final int length = text.length(); return text.substring(0, length - 1); } return null; } + private static boolean isDecimalLiteral(String text) { + // should not be binary, octal or hexadecimal: 0b101, 077, 0xFF + return text.length() > 0 && text.charAt(0) != '0'; + } + private static boolean isNegatedLiteral(PsiExpression expression) { if (!(expression instanceof PsiPrefixExpression)) { return false; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/numeric/implicit_numeric_conversion/HexadecimalLiteral.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/numeric/implicit_numeric_conversion/HexadecimalLiteral.after.java new file mode 100644 index 000000000000..53d289fafc20 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/numeric/implicit_numeric_conversion/HexadecimalLiteral.after.java @@ -0,0 +1,6 @@ +class HexadecimalLiteral { + + void a() { + double value = (double) 0xFF; + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/numeric/implicit_numeric_conversion/HexadecimalLiteral.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/numeric/implicit_numeric_conversion/HexadecimalLiteral.java new file mode 100644 index 000000000000..f31ee9dbec5e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/numeric/implicit_numeric_conversion/HexadecimalLiteral.java @@ -0,0 +1,6 @@ +class HexadecimalLiteral { + + void a() { + double value = 0xFF; + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/numeric/ImplicitNumericConversionFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/numeric/ImplicitNumericConversionFixTest.java index f5487306fd74..b0cdec66a489 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/numeric/ImplicitNumericConversionFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/numeric/ImplicitNumericConversionFixTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -24,9 +24,8 @@ import com.siyeh.ig.numeric.ImplicitNumericConversionInspection; */ public class ImplicitNumericConversionFixTest extends IGQuickFixesTestCase { - public void testOperatorAssignment() { - doTest(); - } + public void testOperatorAssignment() { doTest(); } + public void testHexadecimalLiteral() { doTest(); } @Override protected void setUp() throws Exception { From 37958d1d926c1d6a28391f6643946e6a16a9f8bf Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 12:42:50 +0100 Subject: [PATCH 12/35] make IG test light --- .../UnqualifiedMethodAccess.java | 2 +- .../unqualified_method_access/expected.xml | 9 ------ ...UnqualifiedMethodAccessInspectionTest.java | 32 ++++++++++++++++--- 3 files changed, 28 insertions(+), 15 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/expected.xml diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/UnqualifiedMethodAccess.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/UnqualifiedMethodAccess.java index 0e626f3fe31d..4d7b2baf00bc 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/UnqualifiedMethodAccess.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/UnqualifiedMethodAccess.java @@ -9,7 +9,7 @@ public class UnqualifiedMethodAccess extends JPanel { void foo() {} void bar() { - foo(); + foo(); } void foo(String s) { diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/expected.xml deleted file mode 100644 index a2183473e31a..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/expected.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - UnqualifiedMethodAccess.java - 12 - Instance method call not qualified with 'this' - Instance method call <code>foo</code> is not qualified with 'this' #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedMethodAccessInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedMethodAccessInspectionTest.java index 57128c4e694d..dc7db8157758 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedMethodAccessInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedMethodAccessInspectionTest.java @@ -1,11 +1,33 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.siyeh.ig.style; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class UnqualifiedMethodAccessInspectionTest - extends IGInspectionTestCase { +public class UnqualifiedMethodAccessInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - doTest("com/siyeh/igtest/style/unqualified_method_access", new UnqualifiedMethodAccessInspection()); + public void testUnqualifiedMethodAccess() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new UnqualifiedMethodAccessInspection(); } } \ No newline at end of file From 27e6a8821b47176e56d1bb75766c42ff414f8480 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 13:35:38 +0100 Subject: [PATCH 13/35] make IG test light --- .../UnqualifiedFieldAccess.java | 6 ++-- .../unqualified_field_access/expected.xml | 23 -------------- .../UnqualifiedFieldAccessInspectionTest.java | 31 ++++++++++++++++--- 3 files changed, 30 insertions(+), 30 deletions(-) delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java index ac24026a8ae9..737d11b15f18 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java @@ -5,8 +5,8 @@ public class UnqualifiedFieldAccess { private String field; public void x () { - field = "foofoo"; - final String s = String.valueOf(field.hashCode()); + field = "foofoo"; + final String s = String.valueOf(field.hashCode()); System.out.println(s); } @@ -28,7 +28,7 @@ public class UnqualifiedFieldAccess { String s; void foo() { - System.out.println(s); + System.out.println(s); } }; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml deleted file mode 100644 index aa352acb6311..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/expected.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - UnqualifiedFieldAccess.java - 8 - Instance field access not qualified with 'this' - Instance field access <code>field</code> is not qualified with 'this' #loc - - - - UnqualifiedFieldAccess.java - 9 - Instance field access not qualified with 'this' - Instance field access <code>field</code> is not qualified with 'this' #loc - - - - UnqualifiedFieldAccess.java - 31 - Instance field access not qualified with 'this' - Instance field access <code>s</code> is not qualified with 'this' #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedFieldAccessInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedFieldAccessInspectionTest.java index 07d99ddb4de4..45a14d03333b 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedFieldAccessInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/UnqualifiedFieldAccessInspectionTest.java @@ -1,10 +1,33 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.siyeh.ig.style; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class UnqualifiedFieldAccessInspectionTest extends IGInspectionTestCase { +public class UnqualifiedFieldAccessInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - doTest("com/siyeh/igtest/style/unqualified_field_access", new UnqualifiedFieldAccessInspection()); + public void testUnqualifiedFieldAccess() throws Exception { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new UnqualifiedFieldAccessInspection(); } } \ No newline at end of file From 36cccb5ced5ae0cff54c397052eb16a7cecae948 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 14:08:51 +0100 Subject: [PATCH 14/35] IG: do not suggest qualified this expression on method of local class --- .../ig/style/UnqualifiedMethodAccessInspection.java | 13 +++++++++++-- .../UnqualifiedMethodAccess.java | 11 +++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedMethodAccessInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedMethodAccessInspection.java index 85aa3ee7c603..f7086af1cd76 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedMethodAccessInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedMethodAccessInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2012 Bas Leijdekkers + * Copyright 2006-2016 Bas Leijdekkers * * 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,8 @@ package com.siyeh.ig.style; import com.intellij.codeInspection.CleanupLocalInspectionTool; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -70,9 +72,16 @@ public class UnqualifiedMethodAccessInspection extends BaseInspection implements return; } final PsiClass containingClass = method.getContainingClass(); - if (containingClass instanceof PsiAnonymousClass) { + if (containingClass == null) { return; } + if (PsiUtil.isLocalOrAnonymousClass(containingClass)) { + final PsiClass expressionClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); + if (expressionClass == null || !expressionClass.equals(containingClass)) { + // qualified this expression not possible for anonymous or local class + return; + } + } registerError(expression); } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/UnqualifiedMethodAccess.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/UnqualifiedMethodAccess.java index 4d7b2baf00bc..c4e1087bb011 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/UnqualifiedMethodAccess.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_method_access/UnqualifiedMethodAccess.java @@ -14,6 +14,16 @@ public class UnqualifiedMethodAccess extends JPanel { void foo(String s) { this.foo(); + class A { + void a() { + a(); + new Object() { + void b() { + a(); + } + }; + } + } } void anonymous() { @@ -22,6 +32,7 @@ public class UnqualifiedMethodAccess extends JPanel { new Object() { void foo() { bar(); + foo(); } }; } From 09ccbc85cd58fd60427d2849ff2d5024acc8aa3f Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 14:14:15 +0100 Subject: [PATCH 15/35] IG: do not suggest qualified this expression on field of local class --- .../ig/style/UnqualifiedFieldAccessInspection.java | 10 +++++++--- .../UnqualifiedFieldAccess.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java index 57fe539de724..4746a0aa1448 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/UnqualifiedFieldAccessInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2013 Bas Leijdekkers + * Copyright 2006-2016 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package com.siyeh.ig.style; import com.intellij.codeInspection.CleanupLocalInspectionTool; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -71,10 +72,13 @@ public class UnqualifiedFieldAccessInspection extends BaseInspection implements return; } final PsiClass fieldClass = field.getContainingClass(); - if (fieldClass instanceof PsiAnonymousClass) { + if (fieldClass == null) { + return; + } + if (PsiUtil.isLocalOrAnonymousClass(fieldClass)) { final PsiClass expressionClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); if (expressionClass != null && !expressionClass.equals(fieldClass)) { - // qualified this expression not possible for anonymous class + // qualified this expression not possible for anonymous or local class return; } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java index 737d11b15f18..27ba03166372 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/unqualified_field_access/UnqualifiedFieldAccess.java @@ -21,6 +21,16 @@ public class UnqualifiedFieldAccess { }; } }; + class A { + int i; + void a() { + new Object() { + void b() { + System.out.println(i); + } + }; + } + } } void simpleAnonymous() { From e2918b0e099c932d043bfa116c21fd79cdd10903 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 14:26:00 +0100 Subject: [PATCH 16/35] EA-67016 (IOE: PsiJavaParserFacadeImpl.createExpressionFromText) --- .../src/com/siyeh/ig/fixes/AddThisQualifierFix.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddThisQualifierFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddThisQualifierFix.java index a1f95383b762..3e83acf92c1b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddThisQualifierFix.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/fixes/AddThisQualifierFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 Bas Leijdekkers + * Copyright 2011-2016 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,7 +74,11 @@ public class AddThisQualifierFix extends InspectionGadgetsFix { return; } } - newExpression = containingClass.getQualifiedName() + ".this." + expression.getText(); + final String qualifiedName = containingClass.getQualifiedName(); + if (qualifiedName == null) { + return; + } + newExpression = qualifiedName + ".this." + expression.getText(); } PsiReplacementUtil.replaceExpressionAndShorten(expression, newExpression); } From d96a153680827794db87ccb58c5c191bcb9b1bb5 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 17:24:40 +0100 Subject: [PATCH 17/35] make IG test light --- .../StringConcatenationInFormatCall.java | 11 +++++++ .../StringContenationInFormatCall.java | 11 ------- .../expected.xml | 16 ---------- ...ncatenationInFormatCallInspectionTest.java | 31 ++++++++++++++++--- 4 files changed, 38 insertions(+), 31 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/StringConcatenationInFormatCall.java delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/StringContenationInFormatCall.java delete mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/expected.xml diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/StringConcatenationInFormatCall.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/StringConcatenationInFormatCall.java new file mode 100644 index 000000000000..8171071df705 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/StringConcatenationInFormatCall.java @@ -0,0 +1,11 @@ +package com.siyeh.igtest.bugs.string_concatenation_in_format_call; + + + +public class StringConcatenationInFormatCall { + + void foo(int i) { + String.format("a" + "b" + i); + String.format("c: " + i); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/StringContenationInFormatCall.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/StringContenationInFormatCall.java deleted file mode 100644 index f192146ff6ff..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/StringContenationInFormatCall.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.siyeh.igtest.bugs.string_concatenation_in_format_call; - - - -public class StringContenationInFormatCall { - - void foo(int i) { - String.format("a" + "b" + i); - String.format("c: " + i); - } -} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/expected.xml deleted file mode 100644 index a41bfb82f655..000000000000 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/string_concatenation_in_format_call/expected.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - StringContenationInFormatCall.java - 8 - String concatenation as argument to 'format()' call - <code>format()</code> call has a String concatenation argument #loc - - - - StringContenationInFormatCall.java - 9 - String concatenation as argument to 'format()' call - <code>format()</code> call has a String concatenation argument #loc - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspectionTest.java index 46c74708bec9..b3a979122a17 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspectionTest.java @@ -1,10 +1,33 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.siyeh.ig.bugs; -import com.siyeh.ig.IGInspectionTestCase; +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.Nullable; -public class StringConcatenationInFormatCallInspectionTest extends IGInspectionTestCase { +public class StringConcatenationInFormatCallInspectionTest extends LightInspectionTestCase { - public void test() throws Exception { - doTest("com/siyeh/igtest/bugs/string_concatenation_in_format_call", new StringConcatenationInFormatCallInspection()); + public void testStringConcatenationInFormatCall() { + doTest(); + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new StringConcatenationInFormatCallInspection(); } } \ No newline at end of file From 654df4a206289f6c7df2b71de43c4ae2c3ef6e29 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 17 Mar 2016 17:29:25 +0100 Subject: [PATCH 18/35] IG: remove quick fix (IDEA-153124) --- .../siyeh/InspectionGadgetsBundle.properties | 1 - ...ngConcatenationInFormatCallInspection.java | 70 +------------------ 2 files changed, 2 insertions(+), 69 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index c432dd0f0876..779ba44914f1 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1835,7 +1835,6 @@ overloaded.methods.with.same.number.parameters.option=Ignore overloaded me string.concatenation.in.format.call.display.name=String concatenation as argument to 'format()' call string.concatenation.in.format.call.problem.descriptor=#ref() call has a String concatenation argument #loc string.concatenation.in.format.call.quickfix=Replace concatenation with separate argument -string.concatenation.in.format.call.plural.quickfix=Replace concatenation with separate arguments string.concatenation.in.message.format.call.display.name=String concatenation as argument to 'MessageFormat.format()' call string.concatenation.in.message.format.call.problem.descriptor=String concatenation as argument to 'MessageFormat.format()' call #loc shift.out.of.range.quickfix=Replace ''{0}'' with ''{1}'' diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspection.java index d228809e03b6..20213454d4dc 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/StringConcatenationInFormatCallInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2012 Bas Leijdekkers + * Copyright 2010-2016 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,10 @@ */ package com.siyeh.ig.bugs; -import com.intellij.codeInspection.ProblemDescriptor; -import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.PsiReplacementUtil; import com.siyeh.ig.psiutils.ExpressionUtils; import com.siyeh.ig.psiutils.FormatUtils; import org.jetbrains.annotations.Nls; @@ -44,67 +39,6 @@ public class StringConcatenationInFormatCallInspection extends BaseInspection { return InspectionGadgetsBundle.message("string.concatenation.in.format.call.problem.descriptor"); } - @Override - protected InspectionGadgetsFix buildFix(Object... infos) { - return new StringConcatenationInFormatCallFix(((Boolean)infos[0]).booleanValue()); - } - - private static class StringConcatenationInFormatCallFix extends InspectionGadgetsFix { - - - private final boolean myPlural; - - public StringConcatenationInFormatCallFix(boolean plural) { - myPlural = plural; - } - - @Override - @NotNull - public String getName() { - if (myPlural) { - return InspectionGadgetsBundle.message("string.concatenation.in.format.call.plural.quickfix"); - } - else { - return InspectionGadgetsBundle.message("string.concatenation.in.format.call.quickfix"); - } - } - - @NotNull - @Override - public String getFamilyName() { - return InspectionGadgetsBundle.message("string.concatenation.in.format.call.plural.quickfix"); - } - - @Override - protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { - final PsiElement element = descriptor.getPsiElement().getParent().getParent(); - if (!(element instanceof PsiMethodCallExpression)) { - return; - } - final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element; - final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); - final PsiExpression formatArgument = FormatUtils.getFormatArgument(argumentList); - if (!(formatArgument instanceof PsiPolyadicExpression)) { - return; - } - final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)formatArgument; - final StringBuilder newExpression = new StringBuilder(); - final PsiExpression[] operands = polyadicExpression.getOperands(); - for (PsiExpression operand : operands) { - if (operand instanceof PsiReferenceExpression) { - argumentList.add(operand); - continue; - } - final PsiJavaToken token = polyadicExpression.getTokenBeforeOperand(operand); - if (token != null) { - newExpression.append(token.getText()); - } - newExpression.append(operand.getText()); - } - PsiReplacementUtil.replaceExpression(polyadicExpression, newExpression.toString()); - } - } - @Override public BaseInspectionVisitor buildVisitor() { return new StringConcatenationInFormatCallVisitor(); @@ -141,7 +75,7 @@ public class StringConcatenationInFormatCallInspection extends BaseInspection { if (count == 0) { return; } - registerMethodCallError(expression, Boolean.valueOf(count > 1)); + registerMethodCallError(expression); } } } From 6158cdad029def7b59daa092988cee8286fafba3 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Thu, 17 Mar 2016 19:52:40 +0300 Subject: [PATCH 19/35] JSON Schema: move to Schemas & DTDs --- platform/platform-resources/src/META-INF/JsonPlugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources/src/META-INF/JsonPlugin.xml b/platform/platform-resources/src/META-INF/JsonPlugin.xml index cf8cffb68459..c553ac02ae7b 100644 --- a/platform/platform-resources/src/META-INF/JsonPlugin.xml +++ b/platform/platform-resources/src/META-INF/JsonPlugin.xml @@ -62,7 +62,7 @@ - From 72fbe54d5a0fcb2a3da0dc0d111d827d9a217be2 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 17 Mar 2016 19:36:52 +0300 Subject: [PATCH 20/35] IDEA-153112 vcs: register shortcuts in "Show Diff For Selection" dialog --- .../openapi/vcs/history/impl/VcsSelectionHistoryDialog.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsSelectionHistoryDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsSelectionHistoryDialog.java index ea47c68786dd..fb723833deeb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsSelectionHistoryDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsSelectionHistoryDialog.java @@ -216,6 +216,10 @@ public class VcsSelectionHistoryDialog extends FrameWrapper implements DataProvi popupActions.add(ActionManager.getInstance().getAction(VcsActions.ACTION_COPY_REVISION_NUMBER)); PopupHandler.installPopupHandler(myList, popupActions, ActionPlaces.UPDATE_POPUP, ActionManager.getInstance()); + for (AnAction action : popupActions.getChildren(null)) { + action.registerCustomShortcutSet(action.getShortcutSet(), mySplitter); + } + setTitle(title); setComponent(mySplitter); setPreferredFocusedComponent(myList); @@ -460,6 +464,7 @@ public class VcsSelectionHistoryDialog extends FrameWrapper implements DataProvi private class MyDiffAction extends DumbAwareAction { public MyDiffAction() { super(VcsBundle.message("action.name.compare"), VcsBundle.message("action.description.compare"), AllIcons.Actions.Diff); + setShortcutSet(CommonShortcuts.getDiff()); } public void update(final AnActionEvent e) { @@ -489,6 +494,7 @@ public class VcsSelectionHistoryDialog extends FrameWrapper implements DataProvi super(VcsBundle.message("show.diff.with.local.action.text"), VcsBundle.message("show.diff.with.local.action.description"), AllIcons.Actions.DiffWithCurrent); + setShortcutSet(ActionManager.getInstance().getAction("Vcs.ShowDiffWithLocal").getShortcutSet()); } public void update(final AnActionEvent e) { From f967d9f0d0bc37a4948ff35ed6fbd230841685dd Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 17 Mar 2016 12:41:20 +0100 Subject: [PATCH 21/35] introduce parameter object: extract change signature part to start under the same progress --- .../IntroduceParameterObjectProcessor.java | 58 +++++++-- .../{usageInfo => }/MergeMethodArguments.java | 111 +++++++----------- .../ChangeSignatureProcessorBase.java | 97 ++++++++------- 3 files changed, 142 insertions(+), 124 deletions(-) rename java/java-impl/src/com/intellij/refactoring/introduceparameterobject/{usageInfo => }/MergeMethodArguments.java (63%) diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java index 21bad491f704..39c943eb3020 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java @@ -38,6 +38,8 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.MoveDestination; import com.intellij.refactoring.RefactorJBundle; +import com.intellij.refactoring.changeSignature.ChangeInfo; +import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase; import com.intellij.refactoring.introduceparameterobject.usageInfo.*; import com.intellij.refactoring.util.FixableUsageInfo; import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor; @@ -77,6 +79,7 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP private final Set paramsNeedingGetters = new HashSet(); private final PsiClass existingClass; private PsiMethod myExistingClassCompatibleConstructor; + private ChangeInfo myChangeInfo; public IntroduceParameterObjectProcessor(String className, String packageName, @@ -179,7 +182,24 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP if (myUseExistingClass && existingClass != null) { myExistingClassCompatibleConstructor = existingClassIsCompatible(existingClass, parameters); } - findUsagesForMethod(method, usages, true); + + final PsiCodeBlock body = method.getBody(); + final String baseParameterName = StringUtil.decapitalize(className); + + final String fixedParamName = + body != null + ? JavaCodeStyleManager.getInstance(myProject).suggestUniqueVariableName(baseParameterName, body.getLBrace(), true) + : JavaCodeStyleManager.getInstance(myProject).propertyNameToVariableName(baseParameterName, VariableKind.PARAMETER); + + myChangeInfo = + new MergeMethodArguments(method, className, packageName, fixedParamName, paramsToMerge, typeParams, keepMethodAsDelegate, + myCreateInnerClass ? method.getContainingClass() : null).createChangeInfo(); + + for (UsageInfo info : ChangeSignatureProcessorBase.findUsages(myChangeInfo)) { + usages.add(new ChangeSignatureUsageWrapper(info)); + } + + findUsagesForMethod(method, usages, fixedParamName); if (myUseExistingClass && existingClass != null && !(paramsNeedingGetters.isEmpty() && paramsNeedingSetters.isEmpty())) { usages.add(new AppendAccessorsUsageInfo(existingClass, myGenerateAccessors, paramsNeedingGetters, paramsNeedingSetters, parameters)); @@ -187,7 +207,7 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP final PsiMethod[] overridingMethods = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); for (PsiMethod siblingMethod : overridingMethods) { - findUsagesForMethod(siblingMethod, usages, false); + findUsagesForMethod(siblingMethod, usages, fixedParamName); } if (myNewVisibility != null) { @@ -195,16 +215,7 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP } } - private void findUsagesForMethod(PsiMethod overridingMethod, List usages, boolean changeSignature) { - final PsiCodeBlock body = overridingMethod.getBody(); - final String baseParameterName = StringUtil.decapitalize(className); - final String fixedParamName = - body != null - ? JavaCodeStyleManager.getInstance(myProject).suggestUniqueVariableName(baseParameterName, body.getLBrace(), true) - : JavaCodeStyleManager.getInstance(myProject).propertyNameToVariableName(baseParameterName, VariableKind.PARAMETER); - - usages.add(new MergeMethodArguments(overridingMethod, className, packageName, fixedParamName, paramsToMerge, typeParams, keepMethodAsDelegate, myCreateInnerClass ? method.getContainingClass() : null, changeSignature)); - + private void findUsagesForMethod(PsiMethod overridingMethod, List usages, String fixedParamName) { final ParamUsageVisitor visitor = new ParamUsageVisitor(overridingMethod, paramsToMerge); overridingMethod.accept(visitor); final Set values = visitor.getParameterUsages(); @@ -261,6 +272,13 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP } } } + List changeSignatureUsages = new ArrayList<>(); + for (UsageInfo info : usageInfos) { + if (info instanceof ChangeSignatureUsageWrapper) { + changeSignatureUsages.add(((ChangeSignatureUsageWrapper)info).getInfo()); + } + } + ChangeSignatureProcessorBase.doChangeSignature(myChangeInfo, changeSignatureUsages.toArray(new UsageInfo[changeSignatureUsages.size()])); } } @@ -537,4 +555,20 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP } } + + private static class ChangeSignatureUsageWrapper extends FixableUsageInfo { + private final UsageInfo myInfo; + + public ChangeSignatureUsageWrapper(UsageInfo info) { + super(info.getElement()); + myInfo = info; + } + + public UsageInfo getInfo() { + return myInfo; + } + + @Override + public void fixUsage() throws IncorrectOperationException {} + } } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/MergeMethodArguments.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/MergeMethodArguments.java similarity index 63% rename from java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/MergeMethodArguments.java rename to java/java-impl/src/com/intellij/refactoring/introduceparameterobject/MergeMethodArguments.java index 0aecd58be007..33da7f6253c9 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/MergeMethodArguments.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/MergeMethodArguments.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -13,32 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.refactoring.introduceparameterobject.usageInfo; +package com.intellij.refactoring.introduceparameterobject; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.impl.source.PsiImmediateClassType; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.TypeConversionUtil; -import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; +import com.intellij.refactoring.changeSignature.ChangeInfo; +import com.intellij.refactoring.changeSignature.JavaChangeInfoImpl; import com.intellij.refactoring.changeSignature.ParameterInfoImpl; -import com.intellij.refactoring.util.FixableUsageInfo; +import com.intellij.refactoring.util.CanonicalTypes; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.VisibilityUtil; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; -@SuppressWarnings({"MethodWithTooManyParameters"}) -public class MergeMethodArguments extends FixableUsageInfo { +public class MergeMethodArguments { private final PsiMethod method; private final PsiClass myContainingClass; - private final boolean myChangeSignature; private final boolean myKeepMethodAsDelegate; private final List typeParams; private final String className; @@ -53,50 +50,45 @@ public class MergeMethodArguments extends FixableUsageInfo { String parameterName, int[] paramsToMerge, List typeParams, - final boolean keepMethodAsDelegate, final PsiClass containingClass, boolean changeSignature) { - super(method); + final boolean keepMethodAsDelegate, + final PsiClass containingClass) { this.paramsToMerge = paramsToMerge; this.packageName = packageName; this.className = className; this.parameterName = parameterName; this.method = method; myContainingClass = containingClass; - myChangeSignature = changeSignature; lastParamIsVararg = method.isVarArgs() && isParameterToMerge(method.getParameterList().getParametersCount() - 1); myKeepMethodAsDelegate = keepMethodAsDelegate; this.typeParams = new ArrayList(typeParams); } - public void fixUsage() throws IncorrectOperationException { + public ChangeInfo createChangeInfo() { final Project project = method.getProject(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); - final PsiMethod deepestSuperMethod = method.findDeepestSuperMethod(); - final PsiClass psiClass; + PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + String packageName; if (myContainingClass != null) { - psiClass = myContainingClass.findInnerClassByName(className, false); - } - else { - psiClass = psiFacade.findClass(StringUtil.getQualifiedName(packageName, className), GlobalSearchScope.allScope(project)); - } - assert psiClass != null; - PsiSubstitutor subst = PsiSubstitutor.EMPTY; - if (deepestSuperMethod != null) { - final PsiClass parentClass = deepestSuperMethod.getContainingClass(); - final PsiSubstitutor parentSubstitutor = - TypeConversionUtil.getSuperClassSubstitutor(parentClass, method.getContainingClass(), PsiSubstitutor.EMPTY); - for (int i1 = 0; i1 < psiClass.getTypeParameters().length; i1++) { - final PsiTypeParameter typeParameter = psiClass.getTypeParameters()[i1]; - for (PsiTypeParameter parameter : parentClass.getTypeParameters()) { - if (Comparing.strEqual(typeParameter.getName(), parameter.getName())) { - subst = subst.put(typeParameter, parentSubstitutor.substitute( - new PsiImmediateClassType(parameter, PsiSubstitutor.EMPTY))); - break; - } - } + packageName = myContainingClass.getQualifiedName(); + if (packageName == null) { + packageName = myContainingClass.getName(); } } + else { + packageName = this.packageName; + } + + String text = StringUtil.getQualifiedName(packageName, className); + if (!typeParams.isEmpty()) { + text += "<" + StringUtil.join(typeParams, new Function() { + @Override + public String fun(PsiTypeParameter parameter) { + return parameter.getName(); + } + }, ", ") + ">"; + } + final PsiType classType = factory.createTypeFromText(text, method); final List parametersInfo = new ArrayList(); - final PsiClassType classType = JavaPsiFacade.getElementFactory(project).createType(psiClass, subst); final ParameterInfoImpl mergedParamInfo = new ParameterInfoImpl(-1, parameterName, classType, null) { @Override @@ -117,33 +109,16 @@ public class MergeMethodArguments extends FixableUsageInfo { } parametersInfo.add(firstIncludedIdx == -1 ? 0 : firstIncludedIdx, mergedParamInfo); - final SmartPsiElementPointer meth = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(method); - - final Runnable performChangeSignatureRunnable = new Runnable() { - @Override - public void run() { - final PsiMethod psiMethod = meth.getElement(); - if (psiMethod == null) return; - if (myChangeSignature) { - final ChangeSignatureProcessor changeSignatureProcessor = - new ChangeSignatureProcessor(psiMethod.getProject(), psiMethod, - myKeepMethodAsDelegate, null, psiMethod.getName(), - psiMethod.getReturnType(), - parametersInfo.toArray(new ParameterInfoImpl[parametersInfo.size()])); - changeSignatureProcessor.run(); - } - } - }; - if (ApplicationManager.getApplication().isUnitTestMode()) { - performChangeSignatureRunnable.run(); - } else { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - CommandProcessor.getInstance().runUndoTransparentAction(performChangeSignatureRunnable); - } - }); - } + PsiType returnType = method.getReturnType(); + return new JavaChangeInfoImpl(VisibilityUtil.getVisibilityModifier(method.getModifierList()), + method, + method.getName(), + returnType != null ? CanonicalTypes.createTypeWrapper(returnType) : null, + parametersInfo.toArray(new ParameterInfoImpl[parametersInfo.size()]), + null, + myKeepMethodAsDelegate, + Collections.emptySet(), + Collections.emptySet()); } private boolean isParameterToMerge(int index) { diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java index 4bf5cd412a3c..867e566d5cc6 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java @@ -71,23 +71,27 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces @Override @NotNull protected UsageInfo[] findUsages() { - List infos = new ArrayList(); + return findUsages(myChangeInfo); + } + @NotNull + public static UsageInfo[] findUsages(ChangeInfo changeInfo) { + List infos = new ArrayList(); final ChangeSignatureUsageProcessor[] processors = ChangeSignatureUsageProcessor.EP_NAME.getExtensions(); for (ChangeSignatureUsageProcessor processor : processors) { - ContainerUtil.addAll(infos, processor.findUsages(myChangeInfo)); + ContainerUtil.addAll(infos, processor.findUsages(changeInfo)); } infos = filterUsages(infos); return infos.toArray(new UsageInfo[infos.size()]); } - protected List filterUsages(List infos) { + protected static List filterUsages(List infos) { Map moveRenameInfos = new HashMap(); Set usedElements = new HashSet(); List result = new ArrayList(infos.size() / 2); for (UsageInfo info : infos) { - LOG.assertTrue(info != null, getClass()); + LOG.assertTrue(info != null); PsiElement element = info.getElement(); if (info instanceof MoveRenameUsageInfo) { if (usedElements.contains(element)) continue; @@ -139,14 +143,15 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces @Override protected void performRefactoring(@NotNull UsageInfo[] usages) { RefactoringTransaction transaction = getTransaction(); - final RefactoringElementListener elementListener = transaction == null ? null : transaction.getElementListener(myChangeInfo.getMethod()); - final String fqn = CopyReferenceAction.elementToFqn(myChangeInfo.getMethod()); + final ChangeInfo changeInfo = myChangeInfo; + final RefactoringElementListener elementListener = transaction == null ? null : transaction.getElementListener(changeInfo.getMethod()); + final String fqn = CopyReferenceAction.elementToFqn(changeInfo.getMethod()); if (fqn != null) { UndoableAction action = new BasicUndoableAction() { @Override public void undo() { if (elementListener instanceof UndoRefactoringElementListener) { - ((UndoRefactoringElementListener)elementListener).undoElementMovedOrRenamed(myChangeInfo.getMethod(), fqn); + ((UndoRefactoringElementListener)elementListener).undoElementMovedOrRenamed(changeInfo.getMethod(), fqn); } } @@ -157,44 +162,10 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces UndoManager.getInstance(myProject).undoableActionPerformed(action); } try { - final ChangeSignatureUsageProcessor[] processors = ChangeSignatureUsageProcessor.EP_NAME.getExtensions(); - - final ResolveSnapshotProvider resolveSnapshotProvider = myChangeInfo.isParameterNamesChanged() ? - VariableInplaceRenamer.INSTANCE.forLanguage(myChangeInfo.getMethod().getLanguage()) : null; - final List snapshots = new ArrayList(); - for (ChangeSignatureUsageProcessor processor : processors) { - if (resolveSnapshotProvider != null) { - processor.registerConflictResolvers(snapshots, resolveSnapshotProvider, usages, myChangeInfo); - } - } - - for (UsageInfo usage : usages) { - for (ChangeSignatureUsageProcessor processor : processors) { - if (processor.processUsage(myChangeInfo, usage, true, usages)) break; - } - } - - LOG.assertTrue(myChangeInfo.getMethod().isValid()); - for (ChangeSignatureUsageProcessor processor : processors) { - if (processor.processPrimaryMethod(myChangeInfo)) break; - } - - for (UsageInfo usage : usages) { - for (ChangeSignatureUsageProcessor processor : processors) { - if (processor.processUsage(myChangeInfo, usage, false, usages)) break; - } - } - - if (!snapshots.isEmpty()) { - for (ParameterInfo parameterInfo : myChangeInfo.getNewParameters()) { - for (ResolveSnapshotProvider.ResolveSnapshot snapshot : snapshots) { - snapshot.apply(parameterInfo.getName()); - } - } - } - final PsiElement method = myChangeInfo.getMethod(); + doChangeSignature(changeInfo, usages); + final PsiElement method = changeInfo.getMethod(); LOG.assertTrue(method.isValid()); - if (elementListener != null && myChangeInfo.isNameChanged()) { + if (elementListener != null && changeInfo.isNameChanged()) { elementListener.elementRenamed(method); } } @@ -203,6 +174,44 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces } } + public static void doChangeSignature(ChangeInfo changeInfo, @NotNull UsageInfo[] usages) { + final ChangeSignatureUsageProcessor[] processors = ChangeSignatureUsageProcessor.EP_NAME.getExtensions(); + + final ResolveSnapshotProvider resolveSnapshotProvider = changeInfo.isParameterNamesChanged() ? + VariableInplaceRenamer.INSTANCE.forLanguage(changeInfo.getMethod().getLanguage()) : null; + final List snapshots = new ArrayList(); + for (ChangeSignatureUsageProcessor processor : processors) { + if (resolveSnapshotProvider != null) { + processor.registerConflictResolvers(snapshots, resolveSnapshotProvider, usages, changeInfo); + } + } + + for (UsageInfo usage : usages) { + for (ChangeSignatureUsageProcessor processor : processors) { + if (processor.processUsage(changeInfo, usage, true, usages)) break; + } + } + + LOG.assertTrue(changeInfo.getMethod().isValid()); + for (ChangeSignatureUsageProcessor processor : processors) { + if (processor.processPrimaryMethod(changeInfo)) break; + } + + for (UsageInfo usage : usages) { + for (ChangeSignatureUsageProcessor processor : processors) { + if (processor.processUsage(changeInfo, usage, false, usages)) break; + } + } + + if (!snapshots.isEmpty()) { + for (ParameterInfo parameterInfo : changeInfo.getNewParameters()) { + for (ResolveSnapshotProvider.ResolveSnapshot snapshot : snapshots) { + snapshot.apply(parameterInfo.getName()); + } + } + } + } + @Override protected String getCommandName() { return RefactoringBundle.message("changing.signature.of.0", DescriptiveNameUtil.getDescriptiveName(myChangeInfo.getMethod())); From ea26329614fb5b6fb5da78e8124f7640b37c2d21 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 17 Mar 2016 12:51:28 +0100 Subject: [PATCH 22/35] change signature: extract common code to search for conflicts; use it in introduce parameter object --- .../ChangeSignatureProcessor.java | 15 +++++-------- .../IntroduceParameterObjectProcessor.java | 7 +++++++ .../ChangeSignatureProcessorBase.java | 21 +++++++++++++++---- .../GrChangeSignatureProcessor.java | 12 +---------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java index efa82dfbc230..77fce0eb1366 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessor.java @@ -37,7 +37,10 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; import static com.intellij.util.ObjectUtils.assertNotNull; @@ -140,15 +143,7 @@ public class ChangeSignatureProcessor extends ChangeSignatureProcessorBase { if (!processor.setupDefaultValues(myChangeInfo, refUsages, myProject)) return false; } MultiMap conflictDescriptions = new MultiMap(); - for (ChangeSignatureUsageProcessor usageProcessor : ChangeSignatureUsageProcessor.EP_NAME.getExtensions()) { - final MultiMap conflicts = usageProcessor.findConflicts(myChangeInfo, refUsages); - for (PsiElement key : conflicts.keySet()) { - Collection collection = conflictDescriptions.get(key); - if (collection.size() == 0) collection = new HashSet(); - collection.addAll(conflicts.get(key)); - conflictDescriptions.put(key, collection); - } - } + collectConflictsFromExtensions(refUsages, conflictDescriptions, myChangeInfo); final UsageInfo[] usagesIn = refUsages.get(); RenameUtil.addConflictDescriptions(usagesIn, conflictDescriptions); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java index 39c943eb3020..2cd79bd89714 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java @@ -167,6 +167,7 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP } } } + List changeSignatureUsages = new ArrayList<>(); for (UsageInfo usageInfo : refUsages.get()) { if (usageInfo instanceof FixableUsageInfo) { final String conflictMessage = ((FixableUsageInfo)usageInfo).getConflictMessage(); @@ -174,7 +175,13 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP conflicts.putValue(usageInfo.getElement(), conflictMessage); } } + else { + changeSignatureUsages.add(usageInfo); + } } + + ChangeSignatureProcessorBase.collectConflictsFromExtensions(new Ref<>(changeSignatureUsages.toArray(new UsageInfo[changeSignatureUsages.size()])), conflicts, myChangeInfo); + return showConflicts(conflicts, refUsages.get()); } diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java index 867e566d5cc6..d3c0f6a202bc 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureProcessorBase.java @@ -22,6 +22,7 @@ import com.intellij.openapi.command.undo.UndoManager; import com.intellij.openapi.command.undo.UndoableAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.refactoring.BaseRefactoringProcessor; @@ -36,15 +37,13 @@ import com.intellij.refactoring.util.MoveRenameUsageInfo; import com.intellij.usageView.UsageInfo; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.hash.HashMap; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * @author Maxim.Medvedev @@ -74,6 +73,20 @@ public abstract class ChangeSignatureProcessorBase extends BaseRefactoringProces return findUsages(myChangeInfo); } + public static void collectConflictsFromExtensions(@NotNull Ref refUsages, + MultiMap conflictDescriptions, + ChangeInfo changeInfo) { + for (ChangeSignatureUsageProcessor usageProcessor : ChangeSignatureUsageProcessor.EP_NAME.getExtensions()) { + final MultiMap conflicts = usageProcessor.findConflicts(changeInfo, refUsages); + for (PsiElement key : conflicts.keySet()) { + Collection collection = conflictDescriptions.get(key); + if (collection.isEmpty()) collection = new com.intellij.util.containers.HashSet(); + collection.addAll(conflicts.get(key)); + conflictDescriptions.put(key, collection); + } + } + } + @NotNull public static UsageInfo[] findUsages(ChangeInfo changeInfo) { List infos = new ArrayList(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureProcessor.java index f6e340cc92da..0cab91db1a1c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureProcessor.java @@ -22,7 +22,6 @@ import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase; -import com.intellij.refactoring.changeSignature.ChangeSignatureUsageProcessor; import com.intellij.refactoring.changeSignature.ChangeSignatureViewDescriptor; import com.intellij.refactoring.rename.RenameUtil; import com.intellij.refactoring.ui.ConflictsDialog; @@ -33,7 +32,6 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import java.util.Arrays; -import java.util.Collection; import java.util.Set; /** @@ -68,15 +66,7 @@ public class GrChangeSignatureProcessor extends ChangeSignatureProcessorBase { @Override protected boolean preprocessUsages(@NotNull Ref refUsages) { MultiMap conflictDescriptions = new MultiMap(); - for (ChangeSignatureUsageProcessor usageProcessor : ChangeSignatureUsageProcessor.EP_NAME.getExtensions()) { - final MultiMap conflicts = usageProcessor.findConflicts(myChangeInfo, refUsages); - for (PsiElement key : conflicts.keySet()) { - Collection collection = conflictDescriptions.get(key); - if (collection.isEmpty()) collection = new HashSet(); - collection.addAll(conflicts.get(key)); - conflictDescriptions.put(key, collection); - } - } + collectConflictsFromExtensions(refUsages, conflictDescriptions, myChangeInfo); final UsageInfo[] usagesIn = refUsages.get(); RenameUtil.addConflictDescriptions(usagesIn, conflictDescriptions); From cdc7349caa7aa72daf54ba34c7c07f7b1ccad06b Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 17 Mar 2016 15:52:25 +0100 Subject: [PATCH 23/35] unchecked warnings: don't warn about generics array creation if arg of array type is found (IDEA-153122) --- .../daemon/impl/analysis/JavaGenericsUtil.java | 14 ++------------ .../UncheckedGenericsArrayCreation.java | 8 ++++++++ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java index 26169b7bc063..e01eb710d73d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java @@ -101,18 +101,8 @@ public class JavaGenericsUtil { final PsiExpression[] args = argumentList.getExpressions(); if (args.length == parametersCount) { final PsiExpression lastArg = args[args.length - 1]; - if (lastArg instanceof PsiReferenceExpression) { - final PsiElement lastArgsResolve = ((PsiReferenceExpression)lastArg).resolve(); - if (lastArgsResolve instanceof PsiParameter) { - if (((PsiParameter)lastArgsResolve).getType() instanceof PsiArrayType) { - return false; - } - } - } - else if (lastArg instanceof PsiMethodCallExpression) { - if (lastArg.getType() instanceof PsiArrayType) { - return false; - } + if (lastArg.getType() instanceof PsiArrayType) { + return false; } } for (int i = parametersCount - 1; i < args.length; i++) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java index ce0660b63538..1a2f4ce9a7b0 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/UncheckedGenericsArrayCreation.java @@ -29,6 +29,14 @@ class Test { public static void main(String[] args) { asList(new ArrayList()); + ArrayList[] arrayOfStrings = null; + asList(arrayOfStrings); + asList((ArrayList[])null); + + //overload should be chosen before target type is known -> inference failure + List[]> arraysList = asList(arrayOfStrings); + System.out.println(arraysList); + asListSuppressed(new ArrayList()); //noinspection unchecked From 9757b6288b717fc273d2b5b6d3bb58433f2e1ea3 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 17 Mar 2016 16:13:52 +0100 Subject: [PATCH 24/35] fix testdata --- .../groovy/intentions/AddConstructorMatchingSuperTest.groovy | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/AddConstructorMatchingSuperTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/AddConstructorMatchingSuperTest.groovy index 7dc8e6ca6e83..9e7ea7a89f99 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/AddConstructorMatchingSuperTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/AddConstructorMatchingSuperTest.groovy @@ -34,6 +34,7 @@ public class AddConstructorMatchingSuperTest extends GrIntentionTestCase { void testGroovyToGroovy() { doTextTest('''\ +@interface Anno {} class Base { Base(int p, @Anno int x) throws Exception {} } @@ -41,6 +42,7 @@ class Base { class Derived extends Base { } ''', '''\ +@interface Anno {} class Base { Base(int p, @Anno int x) throws Exception {} } @@ -55,6 +57,7 @@ class Derived extends Base { void testJavaToGroovy() { myFixture.addClass('''\ +@interface Anno {} class Base { Base(int p, @Anno int x) throws Exception {} } From 1545f58d8d0905b1df86f66bebce5514b1a278e9 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 17 Mar 2016 17:38:17 +0100 Subject: [PATCH 25/35] make type denotable: ensure that array type is not created over wildcard --- java/java-psi-api/src/com/intellij/psi/GenericsUtil.java | 5 ++++- .../introduceVariable/DenotableType3.after.java | 9 +++++++++ .../refactoring/introduceVariable/DenotableType3.java | 7 +++++++ .../com/intellij/refactoring/IntroduceVariableTest.java | 4 ++++ 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/refactoring/introduceVariable/DenotableType3.after.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/DenotableType3.java diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index 314580fc7d80..aaf7141512ab 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -307,7 +307,10 @@ public class GenericsUtil { PsiType componentType = arrayType.getComponentType(); PsiType type = componentType.accept(this); if (type == componentType) return arrayType; - return type.createArrayType(); + if (type instanceof PsiWildcardType) { + type = ((PsiWildcardType)type).getBound(); + } + return type != null ? type.createArrayType() : arrayType; } @Override diff --git a/java/java-tests/testData/refactoring/introduceVariable/DenotableType3.after.java b/java/java-tests/testData/refactoring/introduceVariable/DenotableType3.after.java new file mode 100644 index 000000000000..793e6c8130bc --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/DenotableType3.after.java @@ -0,0 +1,9 @@ +import java.util.function.IntFunction; +import java.util.stream.Stream; + +class MyTest { + private static void getArguments(final Stream> classStream) { + IntFunction[]> m = (value) -> new Class[value]; + final Class[] classes = classStream.toArray(m); + } +} diff --git a/java/java-tests/testData/refactoring/introduceVariable/DenotableType3.java b/java/java-tests/testData/refactoring/introduceVariable/DenotableType3.java new file mode 100644 index 000000000000..fa27ffb44e62 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/DenotableType3.java @@ -0,0 +1,7 @@ +import java.util.stream.Stream; + +class MyTest { + private static void getArguments(final Stream> classStream) { + final Class[] classes = classStream.toArray((value) -> new Class[value]); + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index ae1fb74ff029..24eb5804792b 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -512,6 +512,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("m", false, false, false, "I>")); } + public void testDenotableType3() { + doTest(new MockIntroduceVariableHandler("m", false, false, false, "java.util.function.IntFunction[]>")); + } + public void testReturnNonExportedArray() { doTest(new MockIntroduceVariableHandler("i", false, false, false, "java.io.File[]") { @Override From ec5245ed00f063629fd5ff624a170857aa9a60fe Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Thu, 17 Mar 2016 17:57:08 +0100 Subject: [PATCH 26/35] redundant cast: recapture wildcards for non-physical elements (IDEA-153166) --- .../src/com/intellij/psi/util/PsiUtil.java | 35 +++++++++++++++++++ .../intellij/psi/util/RedundantCastUtil.java | 2 +- .../redundantCast/CapturedWildcardInCast.java | 9 +++++ .../lambda/LambdaRedundantCastTest.java | 4 +++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/redundantCast/CapturedWildcardInCast.java diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java index 98df1492904c..b8b9f39e2f8d 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java @@ -764,6 +764,9 @@ public final class PsiUtil extends PsiUtilCore { return null; } + /** + * Applies capture conversion to the type in context + */ @NotNull public static PsiType captureToplevelWildcards(@NotNull final PsiType type, @NotNull final PsiElement context) { if (type instanceof PsiClassType) { @@ -811,6 +814,38 @@ public final class PsiUtil extends PsiUtilCore { return type; } + /** + * Opens top level captured wildcards and remap them according to the context. + * The only valid purpose: allow to speculate on non-physical expressions about types, e.g. to detect redundant casts with 'wildcards' + */ + public static PsiType recaptureWildcards(PsiType type, PsiElement context) { + if (type instanceof PsiClassType) { + final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics(); + final PsiClass aClass = resolveResult.getElement(); + if (aClass != null) { + final PsiSubstitutor substitutor = resolveResult.getSubstitutor(); + + PsiSubstitutor resultSubstitution = null; + for (PsiTypeParameter parameter : substitutor.getSubstitutionMap().keySet()) { + final PsiType substitute = substitutor.substitute(parameter); + if (substitute instanceof PsiCapturedWildcardType) { + if (resultSubstitution == null) resultSubstitution = substitutor; + resultSubstitution = resultSubstitution.put(parameter, ((PsiCapturedWildcardType)substitute).getWildcard()); + } + } + + if (resultSubstitution != null) { + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(context.getProject()); + return captureToplevelWildcards(factory.createType(aClass, resultSubstitution), context); + } + } + } + else if (type instanceof PsiArrayType) { + return recaptureWildcards(((PsiArrayType)type).getComponentType(), context).createArrayType(); + } + return type; + } + public static boolean isInsideJavadocComment(PsiElement element) { return PsiTreeUtil.getParentOfType(element, PsiDocComment.class, true) != null; } diff --git a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java index d4c9d0960cac..d4829aa8b268 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/RedundantCastUtil.java @@ -385,7 +385,7 @@ public class RedundantCastUtil { if (oldMethod.equals(newResult.getElement()) && (!(newCall instanceof PsiCallExpression) || oldAnonymousClass != null && newAnonymousClass != null && Comparing.equal(oldAnonymousClass.getBaseClassType(), newAnonymousClass.getBaseClassType()) || - Comparing.equal(((PsiCallExpression)newCall).getType(), ((PsiCallExpression)expression).getType())) && + Comparing.equal(PsiUtil.recaptureWildcards(((PsiCallExpression)newCall).getType(), expression), ((PsiCallExpression)expression).getType())) && newResult.isValidResult()) { if (!(newArgs[i] instanceof PsiFunctionalExpression) || castType != null && castType.equals(((PsiFunctionalExpression)newArgs[i]).getFunctionalInterfaceType())) { addToResults(cast); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/redundantCast/CapturedWildcardInCast.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/redundantCast/CapturedWildcardInCast.java new file mode 100644 index 000000000000..85a53bf77ba4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/redundantCast/CapturedWildcardInCast.java @@ -0,0 +1,9 @@ + +import java.util.function.IntFunction; +import java.util.stream.Stream; + +class MyTest { + private static void getArguments(final Stream> classStream) { + final Class[] classes = classStream.toArray(((IntFunction[]>) (value) -> new Class[value]) ); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java index 820925a1bd2e..dbe905446a8d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/LambdaRedundantCastTest.java @@ -61,6 +61,10 @@ public class LambdaRedundantCastTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testCapturedWildcardInCast() throws Exception { + doTest(); + } + private void doTest() { doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false); } From 44aa117051337eda5029f3be9f570ce18c6bde7c Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 17 Mar 2016 20:11:08 +0300 Subject: [PATCH 27/35] ui: AnAction.setShortcutSet check - replace error with warning fix tests until most of the issues are fixed --- .../src/com/intellij/openapi/actionSystem/AnAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java index 5cd2c2148ac6..dad449da8ba8 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java @@ -279,7 +279,7 @@ public abstract class AnAction implements PossiblyDumbAware { protected void setShortcutSet(ShortcutSet shortcutSet) { if (myIsGlobal && myShortcutSet != shortcutSet) { - LOG.error("Shortcuts of global AnActions should not be changed outside of KeymapManager"); + LOG.warn("Shortcuts of global AnActions should not be changed outside of KeymapManager", new Throwable()); } myShortcutSet = shortcutSet; } From ca9fee4f6f2f4e67973b347793e4dcada02a97de Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Thu, 17 Mar 2016 20:23:12 +0300 Subject: [PATCH 28/35] Support gevent if only it is installed on the interpreter (PY-14992) --- python/helpers/pydev/_pydevd_bundle/pydevd_constants.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py b/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py index 9516c1455f9b..6ba6bd0030be 100644 --- a/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py +++ b/python/helpers/pydev/_pydevd_bundle/pydevd_constants.py @@ -91,6 +91,10 @@ except AttributeError: try: SUPPORT_GEVENT = os.getenv('GEVENT_SUPPORT', 'False') == 'True' + try: + import gevent + except: + SUPPORT_GEVENT = False except: # Jython 2.1 doesn't accept that construct SUPPORT_GEVENT = False From 3ca6e33491ba2429f4c956f05b234358d7379d23 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Thu, 17 Mar 2016 20:35:38 +0300 Subject: [PATCH 29/35] IDEA-153115 vcs: load revisions under single progress --- .../openapi/vcs/history/impl/VcsSelectionHistoryDialog.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsSelectionHistoryDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsSelectionHistoryDialog.java index fb723833deeb..661586bc8cd4 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsSelectionHistoryDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/history/impl/VcsSelectionHistoryDialog.java @@ -245,7 +245,7 @@ public class VcsSelectionHistoryDialog extends FrameWrapper implements DataProvi return myCachedContents.getContentOf(revision); } - private void loadContentsFor(final VcsFileRevision[] revisions) throws VcsException { + private void loadContentsFor(final VcsFileRevision... revisions) throws VcsException { myCachedContents.loadContentsFor(revisions); } @@ -430,6 +430,8 @@ public class VcsSelectionHistoryDialog extends FrameWrapper implements DataProvi } private void ensureBlocksCreated(int requiredIndex) throws VcsException { + loadContentsFor(myRevisions.get(requiredIndex)); + for (int i = 0; i <= requiredIndex; i++) { if (myBlocks.get(i) == null) { myBlocks.set(i, createBlock(i)); From 4a6a9a6a5aad763d135331b5a9bab5831b675281 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 17 Mar 2016 13:53:31 +0100 Subject: [PATCH 30/35] cleanup --- .../openapi/wm/impl/welcomeScreen/ChangeProjectIconForm.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/ChangeProjectIconForm.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/ChangeProjectIconForm.java index d5689502d50f..e278af001833 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/ChangeProjectIconForm.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/ChangeProjectIconForm.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -122,7 +122,7 @@ public class ChangeProjectIconForm { pathToIcon = files[0]; } } - catch (Exception e1) { + catch (Exception ignore) { } } } From f3fd599f39cc38659ef19657f6344a38f00a55ef Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 17 Mar 2016 18:49:01 +0100 Subject: [PATCH 31/35] don't call cell edit if selection key is enabled --- .../src/com/intellij/util/ui/table/JBListTable.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/util/ui/table/JBListTable.java b/platform/platform-impl/src/com/intellij/util/ui/table/JBListTable.java index b491438ac5a8..b0a3d46eabc8 100644 --- a/platform/platform-impl/src/com/intellij/util/ui/table/JBListTable.java +++ b/platform/platform-impl/src/com/intellij/util/ui/table/JBListTable.java @@ -43,6 +43,7 @@ import javax.swing.table.TableColumn; import javax.swing.table.TableModel; import java.awt.*; import java.awt.event.*; +import java.util.EventObject; import java.util.List; import static java.awt.event.KeyEvent.*; @@ -142,6 +143,14 @@ public abstract class JBListTable { myEditor = editor; } + @Override + public boolean isCellEditable(EventObject e) { + if (e instanceof MouseEvent && UIUtil.isSelectionButtonDown((MouseEvent)e)) { + return false; + } + return super.isCellEditable(e); + } + @Override public Component getTableCellEditorComponent(final JTable table, Object value, boolean isSelected, final int row, int column) { final JPanel p = new JPanel(new BorderLayout()) { From 6e3902326904d3925f9f0212b004e410ade25fd7 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Mar 2016 19:08:18 +0100 Subject: [PATCH 32/35] add nullity annotations to PomTransaction --- platform/core-api/src/com/intellij/pom/PomTransaction.java | 4 ++++ .../src/com/intellij/pom/impl/PomTransactionBase.java | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/platform/core-api/src/com/intellij/pom/PomTransaction.java b/platform/core-api/src/com/intellij/pom/PomTransaction.java index 679b00a45050..788e6c90603c 100644 --- a/platform/core-api/src/com/intellij/pom/PomTransaction.java +++ b/platform/core-api/src/com/intellij/pom/PomTransaction.java @@ -18,16 +18,20 @@ package com.intellij.pom; import com.intellij.pom.event.PomModelEvent; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; /** * @author ik */ public interface PomTransaction { + @NotNull PomModelEvent getAccumulatedEvent(); void run() throws IncorrectOperationException; + @NotNull PsiElement getChangeScope(); + @NotNull PomModelAspect getTransactionAspect(); } diff --git a/platform/core-api/src/com/intellij/pom/impl/PomTransactionBase.java b/platform/core-api/src/com/intellij/pom/impl/PomTransactionBase.java index 78383f215857..d40a8581c26b 100644 --- a/platform/core-api/src/com/intellij/pom/impl/PomTransactionBase.java +++ b/platform/core-api/src/com/intellij/pom/impl/PomTransactionBase.java @@ -21,18 +21,20 @@ import com.intellij.pom.PomTransaction; import com.intellij.pom.event.PomModelEvent; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public abstract class PomTransactionBase implements PomTransaction{ private final PsiElement myScope; private final PomModelAspect myAspect; private final PomModelEvent myAccumulatedEvent; - public PomTransactionBase(PsiElement scope, final PomModelAspect aspect){ + public PomTransactionBase(@NotNull PsiElement scope, @NotNull final PomModelAspect aspect){ myScope = scope; myAspect = aspect; myAccumulatedEvent = new PomModelEvent(PomManager.getModel(scope.getProject())); } + @NotNull @Override public PomModelEvent getAccumulatedEvent() { return myAccumulatedEvent; @@ -53,11 +55,13 @@ public abstract class PomTransactionBase implements PomTransaction{ @Nullable public abstract PomModelEvent runInner() throws IncorrectOperationException; + @NotNull @Override public PsiElement getChangeScope() { return myScope; } + @NotNull @Override public PomModelAspect getTransactionAspect() { return myAspect; From 51d0a8530671ad7a681bf7e2288dc329bc61c92c Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Mar 2016 19:13:44 +0100 Subject: [PATCH 33/35] allow nested synchronous transactions in the same modality --- .../application/TransactionGuardImpl.java | 30 ++++++++++++++----- .../codeInsight/editorActions/EndHandler.java | 4 +-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java b/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java index 2c40b8549527..2ba93aaca322 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java @@ -36,24 +36,40 @@ public class TransactionGuardImpl extends TransactionGuard { private final Queue myQueue = new LinkedBlockingQueue(); private final Set myMergeableKinds = ContainerUtil.newHashSet(); private String myTransactionStartTrace; + private ModalityState myTransactionModality; @Override @NotNull public AccessToken startSynchronousTransaction(@NotNull TransactionKind kind) throws IllegalStateException { - ApplicationManager.getApplication().assertIsDispatchThread(); - if (myTransactionStartTrace != null) { - if (!myMergeableKinds.contains(kind) && !ApplicationManager.getApplication().isUnitTestMode()) { - // please assign exceptions that occur here to Peter - LOG.error("Nested transactions are not allowed, see FAQ in TransactionGuard class javadoc. Transaction start trace is in attachment. Kind is " + kind, - new Attachment("trace.txt", myTransactionStartTrace)); + ModalityState modality = ModalityState.current(); + if (isInsideTransaction()) { + if (myTransactionModality == modality) { + return AccessToken.EMPTY_ACCESS_TOKEN; } + + if (myMergeableKinds.contains(kind)) { + final ModalityState prev = myTransactionModality; + myTransactionModality = modality; + return new AccessToken() { + @Override + public void finish() { + myTransactionModality = prev; + } + }; + } + + // please assign exceptions that occur here to Peter + LOG.error("Nested transactions are not allowed, see FAQ in TransactionGuard class javadoc. Transaction start trace is in attachment. Kind is " + kind, + new Attachment("trace.txt", myTransactionStartTrace)); return AccessToken.EMPTY_ACCESS_TOKEN; } + myTransactionModality = modality; myTransactionStartTrace = DebugUtil.currentStackTrace(); return new AccessToken() { @Override public void finish() { myTransactionStartTrace = null; + myTransactionModality = null; if (!myQueue.isEmpty()) { pollQueueLater(); } @@ -148,7 +164,7 @@ public class TransactionGuardImpl extends TransactionGuard { public void submitTransactionAndWait(@NotNull TransactionKind kind, @NotNull final Runnable transaction) throws ProcessCanceledException { Application app = ApplicationManager.getApplication(); if (app.isDispatchThread()) { - if (!canRunTransactionNow(kind)) { + if (!canRunTransactionNow(kind) && myTransactionModality != ModalityState.current()) { throw new AssertionError("Cannot run submitTransactionAndWait from another transaction, kind " + kind + " is not allowed"); } runSyncTransaction(kind, transaction); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EndHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EndHandler.java index d43e47dfb3cb..72a64b2b49c4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EndHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/EndHandler.java @@ -94,9 +94,7 @@ public class EndHandler extends EditorActionHandler { // here just as a boolean value holder due to requirement to declare variable used from inner class as final. final AtomicBoolean stopProcessing = new AtomicBoolean(true); - TransactionGuard guard = TransactionGuard.getInstance(); - // sometimes this handler is invoked from other actions, then we're already inside a transaction - try (AccessToken ignore = guard.isInsideTransaction() ? null : guard.startSynchronousTransaction(TransactionKind.TEXT_EDITING)) { + try (AccessToken ignore = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.TEXT_EDITING)) { PsiDocumentManager.getInstance(project).commitAllDocuments(); ApplicationManager.getApplication().runWriteAction(() -> { CodeStyleManager styleManager = CodeStyleManager.getInstance(project); From 1254e38e75f298a438cd88c08adda3b03a104a36 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Mar 2016 19:36:03 +0100 Subject: [PATCH 34/35] remove insecure TransactionGuard#isInsideTransaction --- .../openapi/application/TransactionGuard.java | 12 +++++++----- .../openapi/application/TransactionGuardImpl.java | 10 ++++++++-- .../src/com/intellij/openapi/ui/DialogWrapper.java | 5 ++--- .../openapi/application/impl/ApplicationImpl.java | 6 +++--- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java b/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java index 9134e9c58fbd..6c41ce40deca 100644 --- a/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java +++ b/platform/core-api/src/com/intellij/openapi/application/TransactionGuard.java @@ -161,11 +161,6 @@ public abstract class TransactionGuard { @NotNull public abstract AccessToken startSynchronousTransaction(@NotNull TransactionKind kind); - /** - * @return whether there's a transaction currently running - */ - public abstract boolean isInsideTransaction(); - /** * When on UI thread and there's no other transaction running, executes the given runnable. If there is a transaction running, * but the given {@code kind} is allowed via {@link #acceptNestedTransactions(TransactionKind...)}, merges two transactions @@ -190,4 +185,11 @@ public abstract class TransactionGuard { */ @NotNull public abstract AccessToken acceptNestedTransactions(TransactionKind... kinds); + + /** + * Asserts that a transaction is currently running, or not. Callable only on Swing thread. + * @param transactionRequired whether the assertion should check that the application is inside transaction or not + * @param errorMessage the message that will be logged if current transaction status differs from the expected one + */ + public abstract void assertInsideTransaction(boolean transactionRequired, @NotNull String errorMessage); } diff --git a/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java b/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java index 2ba93aaca322..671f56094a74 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/application/TransactionGuardImpl.java @@ -103,8 +103,7 @@ public class TransactionGuardImpl extends TransactionGuard { } } - @Override - public boolean isInsideTransaction() { + private boolean isInsideTransaction() { ApplicationManager.getApplication().assertIsDispatchThread(); return myTransactionStartTrace != null; } @@ -160,6 +159,13 @@ public class TransactionGuardImpl extends TransactionGuard { }; } + @Override + public void assertInsideTransaction(boolean transactionRequired, @NotNull String errorMessage) { + if (transactionRequired != isInsideTransaction()) { + LOG.error(errorMessage); + } + } + @Override public void submitTransactionAndWait(@NotNull TransactionKind kind, @NotNull final Runnable transaction) throws ProcessCanceledException { Application app = ApplicationManager.getApplication(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java index b39ef3d91bb1..6c5da11ab3b3 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java @@ -1644,9 +1644,8 @@ public abstract class DialogWrapper { if (ApplicationManager.getApplication().isWriteAccessAllowed()) { LOG.error("Project-modal dialogs should not be shown under a write action."); } - if (TransactionGuard.getInstance().isInsideTransaction()) { - LOG.error("Project-modal dialogs should not be shown inside a transaction. See TransactionGuard documentation."); - } + TransactionGuard.getInstance().assertInsideTransaction( + false, "Project-modal dialogs should not be shown inside a transaction. See TransactionGuard documentation."); } final AsyncResult result = new AsyncResult(); diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 0578a0550dc9..beee7d02aef0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -1229,9 +1229,9 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private void startWrite(/*@NotNull*/ Class clazz) { assertIsDispatchThread(getStatus(), "Write access is allowed from event dispatch thread only"); HeavyProcessLatch.INSTANCE.stopThreadPrioritizing(); // let non-cancellable read actions complete faster, if present - if (!TransactionGuard.getInstance().isInsideTransaction() && Registry.is("ide.require.transaction.for.model.changes", false)) { - // please assign exceptions that occur here to Peter - LOG.error("Write access is allowed from model transactions only, see TransactionGuard documentation for details"); + if (Registry.is("ide.require.transaction.for.model.changes", false)) { + TransactionGuard.getInstance().assertInsideTransaction( + true, "Write access is allowed from model transactions only, see TransactionGuard documentation for details"); } boolean writeActionPending = myWriteActionPending; if (gatherWriteActionStatistics && myWriteActionsStack.isEmpty() && !writeActionPending) { From 29aad5b545bf63ab03ca58825124440f48571a57 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 17 Mar 2016 20:23:26 +0100 Subject: [PATCH 35/35] InspectionTreeUpdater: prevent project leaks in tests via pending alarm requests --- .../com/intellij/codeInspection/ui/InspectionTreeUpdater.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeUpdater.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeUpdater.java index 19cb4d24288d..3eaac402798a 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeUpdater.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionTreeUpdater.java @@ -20,8 +20,6 @@ import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeNode; -import javax.swing.tree.TreePath; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -34,7 +32,7 @@ public class InspectionTreeUpdater { public InspectionTreeUpdater(InspectionResultsView view) { myView = view; - myUpdateQueue = new MergingUpdateQueue("InspectionView", 100, true, view); + myUpdateQueue = new MergingUpdateQueue("InspectionView", 100, true, view, view); } public void updateWithPreviewPanel() {