From 30c59473187573eca01c8b260fb743597e07ee1d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 26 Aug 2014 19:22:23 +0400 Subject: [PATCH 01/11] testng: show root node status with respect to already passed tests (IDEA-128289) --- .../execution/testframework/TestTreeView.java | 4 ++++ .../testng/ui/ResultTreeRenderer.java | 14 ++++++++------ .../theoryinpractice/testng/ui/TestNGResults.java | 4 ++++ .../testng/ui/TestNGTestTreeView.java | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java index 2ecb0fca32cd..839568b4c2a9 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/TestTreeView.java @@ -52,6 +52,10 @@ public abstract class TestTreeView extends Tree implements DataProvider, CopyPro public abstract AbstractTestProxy getSelectedTest(@NotNull TreePath selectionPath); + protected TestFrameworkRunningModel getTestFrameworkRunningModel() { + return myModel; + } + @Nullable public AbstractTestProxy getSelectedTest() { TreePath[] paths = getSelectionPaths(); diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java b/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java index ba30f43b66f0..9ea4429447fe 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/ResultTreeRenderer.java @@ -16,6 +16,7 @@ package com.theoryinpractice.testng.ui; import com.intellij.execution.testframework.PoolOfTestIcons; +import com.intellij.execution.testframework.TestFrameworkRunningModel; import com.intellij.icons.AllIcons; import com.intellij.ui.ColoredTreeCellRenderer; import com.intellij.ui.SimpleTextAttributes; @@ -34,10 +35,11 @@ import javax.swing.tree.DefaultMutableTreeNode; */ public class ResultTreeRenderer extends ColoredTreeCellRenderer { - private final TestNGConsoleProperties consoleProperties; - public ResultTreeRenderer(TestNGConsoleProperties consoleProperties) { - this.consoleProperties = consoleProperties; + private TestFrameworkRunningModel model; + + public ResultTreeRenderer(TestFrameworkRunningModel model) { + this.model = model; } @Override @@ -47,7 +49,7 @@ public class ResultTreeRenderer extends ColoredTreeCellRenderer TestProxy proxy = ((TestNodeDescriptor) node.getUserObject()).getElement(); if (node == tree.getModel().getRoot()) { TreeRootNode root = (TreeRootNode) proxy; - if (node.getChildCount() == 0) { + if (node.getChildCount() == 0 && !((TestNGResults)model).hasFinishedTests()) { if ((root.isStarted() && root.isInProgress()) || (root.isInProgress() && !root.isStarted())) { setIcon(PoolOfTestIcons.NOT_RAN); append("Instantiating tests... ", SimpleTextAttributes.REGULAR_ATTRIBUTES); @@ -64,13 +66,13 @@ public class ResultTreeRenderer extends ColoredTreeCellRenderer append(root.isInProgress() ? "Running tests..." : "Test Results", SimpleTextAttributes.REGULAR_ATTRIBUTES); } - if (consoleProperties.isPaused()) { + if (model.getProperties().isPaused()) { setIcon(AllIcons.RunConfigurations.TestPaused); } } else { if (proxy.getResultMessage() != null) { final TestResultMessage result = proxy.getResultMessage(); - final String name = TestProxy.toDisplayText(result, consoleProperties.getProject()); + final String name = TestProxy.toDisplayText(result, model.getProperties().getProject()); append(name, SimpleTextAttributes.REGULAR_ATTRIBUTES); } else { append(proxy.getName(), SimpleTextAttributes.REGULAR_ATTRIBUTES); diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java index 442e03440ac5..35b76d3e8367 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java @@ -466,6 +466,10 @@ public class TestNGResults extends TestResultsPanel implements TestFrameworkRunn this.failedToStart = failedToStart; } + public boolean hasFinishedTests() { + return count > 0; + } + private class OpenSourceSelectionListener implements TreeSelectionListener { public void valueChanged(TreeSelectionEvent e) { diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java index 48f252d828ee..7e5b7995af0c 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/TestNGTestTreeView.java @@ -33,7 +33,7 @@ import javax.swing.tree.TreeSelectionModel; public class TestNGTestTreeView extends TestTreeView { protected TreeCellRenderer getRenderer(final TestConsoleProperties properties) { - return new ResultTreeRenderer((TestNGConsoleProperties)properties); + return new ResultTreeRenderer(getTestFrameworkRunningModel()); } public TestProxy getSelectedTest(@NotNull TreePath treepath) { From 918222b7e9c0c8070981973b3631d1c2e98ae272 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 26 Aug 2014 20:08:15 +0400 Subject: [PATCH 02/11] testng depends on methods check: process masks (IDEA-127238) --- .../inspection/DependsOnMethodInspection.java | 19 +++++++++++++++++-- .../inspection/dependsOn/Dependencies.java | 8 +++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java b/plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java index 0e5054717c22..c7582025ee73 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java +++ b/plugins/testng/src/com/theoryinpractice/testng/inspection/DependsOnMethodInspection.java @@ -18,8 +18,11 @@ package com.theoryinpractice.testng.inspection; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInspection.*; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.ContainerUtil; import com.theoryinpractice.testng.util.TestNGUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,7 +38,7 @@ import java.util.regex.Pattern; public class DependsOnMethodInspection extends BaseJavaLocalInspectionTool { private static final Logger LOGGER = Logger.getInstance("TestNG Runner"); - private static final Pattern PATTERN = Pattern.compile("\"([a-zA-Z1-9_\\(\\)]*)\""); + private static final Pattern PATTERN = Pattern.compile("\"([a-zA-Z1-9_\\(\\)\\*]*)\""); @NotNull @Override @@ -107,7 +110,19 @@ public class DependsOnMethodInspection extends BaseJavaLocalInspectionTool } else { final String configAnnotation = TestNGUtil.getConfigAnnotation(PsiTreeUtil.getParentOfType(value, PsiMethod.class)); - PsiMethod[] foundMethods = psiClass.findMethodsByName(methodName, true); + final PsiMethod[] foundMethods; + if (methodName.endsWith("*")) { + final String methodNameMask = StringUtil.trimEnd(methodName, "*"); + final List methods = ContainerUtil.filter(psiClass.getMethods(), new Condition() { + @Override + public boolean value(PsiMethod method) { + return method.getName().startsWith(methodNameMask); + } + }); + foundMethods = methods.toArray(new PsiMethod[methods.size()]); + } else { + foundMethods = psiClass.findMethodsByName(methodName, true); + } if (foundMethods.length == 0) { LOGGER.debug("dependsOnMethods method doesn't exist:" + methodName); ProblemDescriptor descriptor = manager.createProblemDescriptor(value, diff --git a/plugins/testng/testData/inspection/dependsOn/Dependencies.java b/plugins/testng/testData/inspection/dependsOn/Dependencies.java index 9111c74affd0..fc095a3ecd3d 100644 --- a/plugins/testng/testData/inspection/dependsOn/Dependencies.java +++ b/plugins/testng/testData/inspection/dependsOn/Dependencies.java @@ -14,6 +14,12 @@ import org.testng.annotations.*; @BeforeMethod(dependsOnMethods = "afterSuiteMethod") public final void beforeMethod() throws Throwable { } -} + + @Test(dependsOnMethods = "foo*") + public void testBar2() {} + + @Test(dependsOnMethods = "testBa*") + public void testBar1() {} + } From 9f86257df3e6d84cd7f832eb68b2e0897fa602a9 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 26 Aug 2014 20:47:02 +0400 Subject: [PATCH 03/11] testng: test class has config even if only its superclass has config method (IDEA-107735) --- .../testng/util/TestNGUtil.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java index ff7d0d064c7a..565af249a27f 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java +++ b/plugins/testng/src/com/theoryinpractice/testng/util/TestNGUtil.java @@ -113,25 +113,27 @@ public class TestNGUtil { private static final String SUITE_TAG_NAME = "suite"; public static boolean hasConfig(PsiModifierListOwner element) { - PsiMethod[] methods; if (element instanceof PsiClass) { - methods = ((PsiClass) element).getMethods(); + for (PsiMethod method : ((PsiClass)element).getAllMethods()) { + if (isConfigMethod(method)) return true; + } } else { if (!(element instanceof PsiMethod)) return false; - methods = new PsiMethod[] {(PsiMethod) element}; + return isConfigMethod((PsiMethod)element); + } + return false; + } + + private static boolean isConfigMethod(PsiMethod method) { + for (String fqn : CONFIG_ANNOTATIONS_FQN) { + if (AnnotationUtil.isAnnotated(method, fqn, false)) return true; } - for (PsiMethod method : methods) { - for (String fqn : CONFIG_ANNOTATIONS_FQN) { - if (AnnotationUtil.isAnnotated(method, fqn, false)) return true; - } - - if (hasDocTagsSupport) { - final PsiDocComment comment = method.getDocComment(); - if (comment != null) { - for (String javadocTag : CONFIG_JAVADOC_TAGS) { - if (comment.findTagByName(javadocTag) != null) return true; - } + if (hasDocTagsSupport) { + final PsiDocComment comment = method.getDocComment(); + if (comment != null) { + for (String javadocTag : CONFIG_JAVADOC_TAGS) { + if (comment.findTagByName(javadocTag) != null) return true; } } } From f4a43c87820a87fca8a5accb47059b8b29efd446 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 26 Aug 2014 20:59:22 +0400 Subject: [PATCH 04/11] testng: include all config-only classes in rerun failed (IDEA-124571) --- .../ui/actions/RerunFailedTestsAction.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java b/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java index a3538059b1db..1d263335b90c 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java @@ -8,9 +8,11 @@ import com.intellij.execution.actions.JavaRerunFailedTestsAction; import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.testframework.AbstractTestProxy; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComponentContainer; +import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; @@ -19,14 +21,12 @@ import com.intellij.psi.search.GlobalSearchScope; import com.theoryinpractice.testng.configuration.SearchingForTestsTask; import com.theoryinpractice.testng.configuration.TestNGConfiguration; import com.theoryinpractice.testng.configuration.TestNGRunnableState; +import com.theoryinpractice.testng.util.TestNGUtil; import org.jetbrains.annotations.NotNull; import java.io.File; import java.net.ServerSocket; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; public class RerunFailedTestsAction extends JavaRerunFailedTestsAction { @@ -53,6 +53,19 @@ public class RerunFailedTestsAction extends JavaRerunFailedTestsAction { return new SearchingForTestsTask(serverSocket, config, tempFile, client) { @Override protected void fillTestObjects(final Map> classes) throws CantRunException { + final HashMap> fullClassList = new HashMap<>(); + super.fillTestObjects(fullClassList); + for (final PsiClass aClass : fullClassList.keySet()) { + if (!ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + return TestNGUtil.hasTest(aClass); + } + })) { + classes.put(aClass, fullClassList.get(aClass)); + } + } + final GlobalSearchScope scope = config.getConfigurationModule().getSearchScope(); final Project project = config.getProject(); for (AbstractTestProxy proxy : failedTests) { From e14ae0fe18ca7a8df852667f82d8f9d2ec3f395a Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 26 Aug 2014 20:54:38 +0400 Subject: [PATCH 05/11] when traversing dirty files do not visit roots from other targets of module build chunk --- .../src/org/jetbrains/jps/incremental/FSOperations.java | 2 +- .../src/org/jetbrains/jps/incremental/fs/BuildFSState.java | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java index 63e538022160..d52e1e6a0132 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSOperations.java @@ -151,7 +151,7 @@ public class FSOperations { } } - public static void processFilesToRecompile(CompileContext context, ModuleBuildTarget target, FileProcessor processor) throws IOException { + public static void processFilesToRecompile(CompileContext context, @NotNull ModuleBuildTarget target, FileProcessor processor) throws IOException { context.getProjectDescriptor().fsState.processFilesToRecompile(context, target, processor); } diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java index e92c0d59a3b0..bb28c422044b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java @@ -145,13 +145,17 @@ public class BuildFSState extends FSState { setRoundDelta(CURRENT_ROUND_DELTA_KEY, context, new FilesDelta()); } - public > boolean processFilesToRecompile(CompileContext context, final T target, final FileProcessor processor) throws IOException { + public > boolean processFilesToRecompile(CompileContext context, final @NotNull T target, final FileProcessor processor) throws IOException { final Map> data = getSourcesToRecompile(context, target); final CompileScope scope = context.getScope(); synchronized (data) { for (Map.Entry> entry : data.entrySet()) { //noinspection unchecked R root = (R)entry.getKey(); + if (!target.equals(root.getTarget())) { + // the data can contain roots from other targets (e.g. when compiling module cycles) + continue; + } for (File file : entry.getValue()) { if (!scope.isAffected(target, file)) { continue; From 0b317415e29cedb3349313569d33c774c4fe2176 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 26 Aug 2014 21:00:59 +0400 Subject: [PATCH 06/11] QuickDoc: re-fix IDEA-100941 and simplify component management --- .../documentation/DockablePopupManager.java | 16 +++-- .../documentation/DocumentationManager.java | 69 ++++++++----------- 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java index 4b0c8b660985..e0d17d3c164b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java @@ -23,7 +23,6 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.AsyncResult; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowAnchor; @@ -35,6 +34,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.ui.content.*; +import com.intellij.util.Consumer; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; @@ -193,12 +193,16 @@ public abstract class DockablePopupManager { public void updateComponent() { if (myProject.isDisposed()) return; - AsyncResult asyncResult = DataManager.getInstance().getDataContextFromFocus(); - DataContext dataContext = asyncResult.getResult(); - if (dataContext == null) { - return; - } + DataManager.getInstance().getDataContextFromFocus().doWhenDone(new Consumer() { + @Override + public void consume(@NotNull DataContext dataContext) { + if (!myProject.isOpen()) return; + updateComponentInner(dataContext); + } + }); + } + private void updateComponentInner(@NotNull DataContext dataContext) { if (CommonDataKeys.PROJECT.getData(dataContext) != myProject) { return; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java index 1f8f6aae922f..f1e93cbe4227 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationManager.java @@ -36,6 +36,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.actionSystem.ex.AnActionListener; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -59,7 +60,6 @@ import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.ListScrollingUtil; import com.intellij.ui.content.Content; import com.intellij.ui.popup.AbstractPopup; -import com.intellij.ui.popup.NotLookupOrSearchCondition; import com.intellij.ui.popup.PopupPositionManager; import com.intellij.ui.popup.PopupUpdateProcessor; import com.intellij.util.Alarm; @@ -141,12 +141,7 @@ public class DocumentationManager extends DockablePopupManager() { @Override @@ -455,8 +455,7 @@ public class DocumentationManager extends DockablePopupManager Date: Tue, 26 Aug 2014 16:06:01 +0200 Subject: [PATCH 07/11] Fix "Type may be weakened" inspection for local classes --- .../TypeMayBeWeakenedInspection.java | 58 ++++++++++--------- .../LocalClass.after.java | 11 ++++ .../type_may_be_weakened/LocalClass.java | 11 ++++ .../weaken_type/TypeMayBeWeakened.java | 13 ++++- .../abstraction/TypeMayBeWeakenedFixTest.java | 5 +- 5 files changed, 70 insertions(+), 28 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java index bf23939f2c86..2787f34e4dcf 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java @@ -21,7 +21,6 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.util.Query; import com.siyeh.InspectionGadgetsBundle; @@ -64,9 +63,9 @@ public class TypeMayBeWeakenedInspection extends BaseInspection { @NonNls final StringBuilder builder = new StringBuilder(); final Iterator iterator = weakerClasses.iterator(); if (iterator.hasNext()) { - builder.append('\'').append(iterator.next().getQualifiedName()).append('\''); + builder.append('\'').append(getClassName(iterator.next())).append('\''); while (iterator.hasNext()) { - builder.append(", '").append(iterator.next().getQualifiedName()).append('\''); + builder.append(", '").append(getClassName(iterator.next())).append('\''); } } final Object info = infos[0]; @@ -85,6 +84,14 @@ public class TypeMayBeWeakenedInspection extends BaseInspection { return InspectionGadgetsBundle.message("type.may.be.weakened.problem.descriptor", builder.toString()); } + private static String getClassName(PsiClass aClass) { + final String qualifiedName = aClass.getQualifiedName(); + if (qualifiedName == null) { + return aClass.getName(); + } + return qualifiedName; + } + @Override @Nullable public JComponent createOptionsPanel() { @@ -106,11 +113,11 @@ public class TypeMayBeWeakenedInspection extends BaseInspection { final Iterable weakerClasses = (Iterable)infos[1]; final Collection fixes = new ArrayList(); for (PsiClass weakestClass : weakerClasses) { - final String qualifiedName = weakestClass.getQualifiedName(); - if (qualifiedName == null) { + final String className = getClassName(weakestClass); + if (className == null) { continue; } - fixes.add(new TypeMayBeWeakenedFix(qualifiedName)); + fixes.add(new TypeMayBeWeakenedFix(className)); } return fixes.toArray(new InspectionGadgetsFix[fixes.size()]); } @@ -162,31 +169,30 @@ public class TypeMayBeWeakenedInspection extends BaseInspection { if (!(oldType instanceof PsiClassType)) { return; } - final PsiClassType classType = (PsiClassType)oldType; - final PsiType[] parameterTypes = classType.getParameters(); - final GlobalSearchScope scope = element.getResolveScope(); + final PsiClassType oldClassType = (PsiClassType)oldType; + final PsiType[] parameterTypes = oldClassType.getParameters(); final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); - final PsiClass aClass = facade.findClass(fqClassName, scope); - if (aClass == null) { + final PsiElementFactory factory = facade.getElementFactory(); + final PsiType type = factory.createTypeFromText(fqClassName, element); + if (!(type instanceof PsiClassType)) { return; } - final PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); - final PsiElementFactory factory = facade.getElementFactory(); - final PsiClassType type; - if (typeParameters.length != 0 && typeParameters.length == parameterTypes.length) { - final Map typeParameterMap = new HashMap(); - for (int i = 0; i < typeParameters.length; i++) { - final PsiTypeParameter typeParameter = typeParameters[i]; - final PsiType parameterType = parameterTypes[i]; - typeParameterMap.put(typeParameter, parameterType); + PsiClassType classType = (PsiClassType)type; + final PsiClass aClass = classType.resolve(); + if (aClass != null) { + final PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); + if (typeParameters.length != 0 && typeParameters.length == parameterTypes.length) { + final Map typeParameterMap = new HashMap(); + for (int i = 0; i < typeParameters.length; i++) { + final PsiTypeParameter typeParameter = typeParameters[i]; + final PsiType parameterType = parameterTypes[i]; + typeParameterMap.put(typeParameter, parameterType); + } + final PsiSubstitutor substitutor = factory.createSubstitutor(typeParameterMap); + classType = factory.createType(aClass, substitutor); } - final PsiSubstitutor substitutor = factory.createSubstitutor(typeParameterMap); - type = factory.createType(aClass, substitutor); } - else { - type = factory.createTypeByFQClassName(fqClassName, scope); - } - final PsiJavaCodeReferenceElement referenceElement = factory.createReferenceElementByType(type); + final PsiJavaCodeReferenceElement referenceElement = factory.createReferenceElementByType(classType); final PsiElement replacement = componentReferenceElement.replace(referenceElement); final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project); javaCodeStyleManager.shortenClassReferences(replacement); diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.after.java new file mode 100644 index 000000000000..42653ac7af63 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.after.java @@ -0,0 +1,11 @@ +class LocalClass { + + void foo() { + class A { + void foo() {} + } + class B extends A {} + A bb = new B(); + bb.foo(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.java new file mode 100644 index 000000000000..1c905035b914 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/abstraction/type_may_be_weakened/LocalClass.java @@ -0,0 +1,11 @@ +class LocalClass { + + void foo() { + class A { + void foo() {} + } + class B extends A {} + B bb = new B(); + bb.foo(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java index 370aba53a19c..a134fcd8d9fb 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/weaken_type/TypeMayBeWeakened.java @@ -162,4 +162,15 @@ class Test implements Foo2 { interface Foo { void bar(); } -interface Foo2 extends Foo {} \ No newline at end of file +interface Foo2 extends Foo {} +class Helper { + + void foo() { + class A { + void foo() {} + } + class B extends A {} + B b = new B(); + b.foo(); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java index 58373f3a3955..d4b9ec3039bb 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/abstraction/TypeMayBeWeakenedFixTest.java @@ -12,10 +12,13 @@ public class TypeMayBeWeakenedFixTest extends IGQuickFixesTestCase { @Override public void setUp() throws Exception { super.setUp(); - myFixture.enableInspections(new TypeMayBeWeakenedInspection()); + final TypeMayBeWeakenedInspection inspection = new TypeMayBeWeakenedInspection(); + inspection.onlyWeakentoInterface = false; + myFixture.enableInspections(inspection); myRelativePath = "abstraction/type_may_be_weakened"; } public void testShorten() { doTest(InspectionGadgetsBundle.message("type.may.be.weakened.quickfix", "java.util.Collection")); } + public void testLocalClass() { doTest(InspectionGadgetsBundle.message("type.may.be.weakened.quickfix", "A")); } } From 3d06a72938f1dc93d4ba8b9afb5462c825e4234e Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 26 Aug 2014 19:17:34 +0200 Subject: [PATCH 08/11] Use find settings showResultsInSeparateView in SSR --- .../structuralsearch/plugin/ui/SearchDialog.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java index 22bbc228955b..3f89f11b9e6d 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/ui/SearchDialog.java @@ -91,8 +91,6 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator private boolean useLastConfiguration; - private static boolean ourOpenInNewTab; - @NonNls private FileType ourFtSearchVariant = StructuralSearchUtil.getDefaultFileType(); private static Language ourDialect = null; private static String ourContext = null; @@ -499,7 +497,7 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator final UsageViewContext context = createUsageViewContext(config); final UsageViewPresentation presentation = new UsageViewPresentation(); - presentation.setOpenInNewTab(openInNewTab.isSelected()); + presentation.setOpenInNewTab(FindSettings.getInstance().isShowResultsInSeparateView()); presentation.setScopeText(config.getMatchOptions().getScope().getDisplayName()); context.configure(presentation); @@ -636,7 +634,7 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0)); openInNewTab = new JCheckBox(FindBundle.message("find.open.in.new.tab.checkbox")); - openInNewTab.setSelected(ourOpenInNewTab); + openInNewTab.setSelected(FindSettings.getInstance().isShowResultsInSeparateView()); ToolWindow findWindow = ToolWindowManager.getInstance(searchContext.getProject()).getToolWindow(ToolWindowId.FIND); openInNewTab.setEnabled(findWindow != null && findWindow.isAvailable()); panel.add(openInNewTab, BorderLayout.EAST); @@ -869,8 +867,9 @@ public class SearchDialog extends DialogWrapper implements ConfigurationCreator super.doOKAction(); if (!myRunFindActionOnClose) return; - FindSettings.getInstance().setDefaultScopeName(selectedScope.getDisplayName()); - ourOpenInNewTab = openInNewTab.isSelected(); + final FindSettings findSettings = FindSettings.getInstance(); + findSettings.setDefaultScopeName(selectedScope.getDisplayName()); + findSettings.setShowResultsInSeparateView(openInNewTab.isSelected()); try { if (model.getShadowConfig() != null) { From 2818360b58f1de71ba0d8ddc3dc5dc256790be55 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 26 Aug 2014 19:19:29 +0200 Subject: [PATCH 09/11] fix AIOOBE in "'equals()' called on itself" inspection --- .../src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java index 7d498b7c5609..698ace189a6b 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EqualsWithItselfInspection.java @@ -64,6 +64,9 @@ public class EqualsWithItselfInspection extends BaseInspection { } final PsiExpressionList argumentList = expression.getArgumentList(); final PsiExpression[] arguments = argumentList.getExpressions(); + if (arguments.length != 1) { + return; + } final PsiExpression argument = arguments[0]; if (!EquivalenceChecker.expressionsAreEquivalent(qualifier, argument) || SideEffectChecker.mayHaveSideEffects(qualifier)) { From 22fffefad1880070b8a672b4a3b5bd6829e1302b Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 26 Aug 2014 21:22:24 +0400 Subject: [PATCH 10/11] compilation fix --- .../testng/ui/actions/RerunFailedTestsAction.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java b/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java index 1d263335b90c..597bb5983876 100644 --- a/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java +++ b/plugins/testng/src/com/theoryinpractice/testng/ui/actions/RerunFailedTestsAction.java @@ -18,6 +18,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.containers.ContainerUtil; import com.theoryinpractice.testng.configuration.SearchingForTestsTask; import com.theoryinpractice.testng.configuration.TestNGConfiguration; import com.theoryinpractice.testng.configuration.TestNGRunnableState; @@ -53,7 +54,7 @@ public class RerunFailedTestsAction extends JavaRerunFailedTestsAction { return new SearchingForTestsTask(serverSocket, config, tempFile, client) { @Override protected void fillTestObjects(final Map> classes) throws CantRunException { - final HashMap> fullClassList = new HashMap<>(); + final HashMap> fullClassList = ContainerUtil.newHashMap(); super.fillTestObjects(fullClassList); for (final PsiClass aClass : fullClassList.keySet()) { if (!ApplicationManager.getApplication().runReadAction(new Computable() { From d9f367a3d0a0673aaef13dfc9ce1a0ba1ba6babd Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 26 Aug 2014 21:28:38 +0400 Subject: [PATCH 11/11] cleanup: drop meaningless setRequestFocusCondition() --- .../codeInsight/hint/actions/ShowImplementationsAction.java | 3 --- .../src/com/intellij/internal/ImageDuplicateResultsDialog.java | 2 -- .../src/com/intellij/byteCodeViewer/ShowByteCodeAction.java | 2 -- .../intellij/designer/propertyTable/actions/ShowJavadoc.java | 2 -- 4 files changed, 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java index 4a7abe355380..afd7b230621c 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/actions/ShowImplementationsAction.java @@ -37,7 +37,6 @@ import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; -import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; @@ -48,7 +47,6 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.reference.SoftReference; import com.intellij.ui.popup.AbstractPopup; -import com.intellij.ui.popup.NotLookupOrSearchCondition; import com.intellij.ui.popup.PopupPositionManager; import com.intellij.ui.popup.PopupUpdateProcessor; import com.intellij.usages.UsageView; @@ -274,7 +272,6 @@ public class ShowImplementationsAction extends AnAction implements PopupAction { }; popup = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component.getPreferredFocusableComponent()) - .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE) .setProject(project) .addListener(updateProcessor) .addUserData(updateProcessor) diff --git a/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java b/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java index c7c62288c158..53d4a3edd7ef 100644 --- a/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java +++ b/platform/lang-impl/src/com/intellij/internal/ImageDuplicateResultsDialog.java @@ -39,7 +39,6 @@ import com.intellij.ui.*; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBList; import com.intellij.ui.components.JBScrollPane; -import com.intellij.ui.popup.NotLookupOrSearchCondition; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Function; import com.intellij.util.NotNullFunction; @@ -232,7 +231,6 @@ public class ImageDuplicateResultsDialog extends DialogWrapper { final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(viewComponent, viewComponent.getPreferredFocusableComponent()) - .setRequestFocusCondition(myProject, NotLookupOrSearchCondition.INSTANCE) .setProject(myProject) .setDimensionServiceKey(myProject, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false) .setResizable(true) diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java index 39d01579b342..1a8bfb7a3558 100644 --- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java +++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java @@ -41,7 +41,6 @@ import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.awt.RelativePoint; -import com.intellij.ui.popup.NotLookupOrSearchCondition; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -138,7 +137,6 @@ public class ShowByteCodeAction extends AnAction { }; final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(component, null) - .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE) .setProject(project) .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false) .setResizable(true) diff --git a/plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java b/plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java index 459d18ae2bab..6f42108cab9a 100644 --- a/plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java +++ b/plugins/ui-designer-core/src/com/intellij/designer/propertyTable/actions/ShowJavadoc.java @@ -33,7 +33,6 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.ui.awt.RelativePoint; -import com.intellij.ui.popup.NotLookupOrSearchCondition; import java.awt.*; @@ -101,7 +100,6 @@ public class ShowJavadoc extends AnAction implements IPropertyTableAction { public void run() { JBPopup hint = JBPopupFactory.getInstance().createComponentPopupBuilder(component, component) - .setRequestFocusCondition(project, NotLookupOrSearchCondition.INSTANCE) .setProject(project) .setDimensionServiceKey(project, DocumentationManager.JAVADOC_LOCATION_AND_SIZE, false) .setResizable(true)