From 70d66687e2c4c8936e331875799a4538f8f240ea Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 22 Sep 2015 12:46:02 +0300 Subject: [PATCH 01/18] fixed incorrect evaluate expression for list children --- .../settings/NodeRendererSettings.java | 50 +++++++------------ .../render/CompoundReferenceRenderer.java | 22 +++++++- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java index eaf6c37821b1..996c878f212f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java @@ -34,13 +34,11 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.CommonClassNames; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiElementFactory; -import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiElement; import com.intellij.util.EventDispatcher; import com.intellij.util.IncorrectOperationException; import com.intellij.util.containers.InternalIterator; -import com.sun.jdi.*; +import com.sun.jdi.Value; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -90,11 +88,7 @@ public class NodeRendererSettings implements PersistentStateComponent { new MapEntryLabelRenderer()/*createLabelRenderer(null, "\" \" + getKey() + \" -> \" + getValue()", null)*/, createEnumerationChildrenRenderer(new String[][]{{"key", "getKey()"}, {"value", "getValue()"}}) ), - createCompoundReferenceRenderer( - "List", CommonClassNames.JAVA_UTIL_LIST, - createLabelRenderer(" size = ", "size()", null), - new ListChildrenRenderer() - ), + new ListObjectRenderer(this), createCompoundReferenceRenderer( "Collection", "java.util.Collection", createLabelRenderer(" size = ", "size()", null), @@ -494,33 +488,25 @@ public class NodeRendererSettings implements PersistentStateComponent { } } - private static class ListChildrenRenderer extends ExpressionChildrenRenderer { - private static final ArrayRenderer ourChildrenRenderer = new ArrayRenderer() { - @Override - public PsiExpression getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) { - try { - ArrayElementDescriptorImpl descriptor = (ArrayElementDescriptorImpl)node.getDescriptor(); - PsiElementFactory elementFactory = JavaPsiFacade.getInstance(node.getProject()).getElementFactory(); - return elementFactory.createExpressionFromText("get(" + descriptor.getIndex() + ")", null); - } - catch (IncorrectOperationException e) { - // fallback to original - return super.getChildValueExpression(node, context); - } - } - }; - - public ListChildrenRenderer() { - setChildrenExpression(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "toArray()", "", StdFileTypes.JAVA)); - setChildrenExpandable(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, "!isEmpty()", "", StdFileTypes.JAVA)); + private static class ListObjectRenderer extends CompoundReferenceRenderer { + public ListObjectRenderer(NodeRendererSettings rendererSettings) { + super(rendererSettings, + "List", + createLabelRenderer(" size = ", "size()", null), + createExpressionChildrenRenderer("toArray()", "!isEmpty()")); + setClassName(CommonClassNames.JAVA_UTIL_LIST); } @Override - public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) { - if (getLastChildrenRenderer(builder.getParentDescriptor()) == null) { - setPreferableChildrenRenderer(builder.getParentDescriptor(), ourChildrenRenderer); + public PsiElement getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) throws EvaluateException { + LOG.assertTrue(node.getDescriptor() instanceof ArrayElementDescriptorImpl); + try { + return getChildValueExpression("this.get(" + ((ArrayElementDescriptorImpl)node.getDescriptor()).getIndex() + ")", node, context); + } + catch (IncorrectOperationException e) { + // fallback to original + return super.getChildValueExpression(node, context); } - super.buildChildren(value, builder, evaluationContext); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java index 4cb8a56021f2..76976c36c7d4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java @@ -15,16 +15,24 @@ */ package com.intellij.debugger.ui.tree.render; +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.engine.DebugProcess; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.settings.NodeRendererSettings; +import com.intellij.debugger.ui.tree.DebuggerTreeNode; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; import com.intellij.psi.CommonClassNames; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementFactory; +import com.intellij.psi.search.GlobalSearchScope; import com.sun.jdi.ReferenceType; import com.sun.jdi.Type; import org.jetbrains.annotations.NotNull; public class CompoundReferenceRenderer extends CompoundNodeRenderer{ - private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.CompoundReferenceRenderer"); + protected static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.CompoundReferenceRenderer"); public CompoundReferenceRenderer(final NodeRendererSettings rendererSettings, String name, ValueLabelRenderer labelRenderer, ChildrenRenderer childrenRenderer) { super(rendererSettings, name, labelRenderer, childrenRenderer); @@ -109,4 +117,16 @@ public class CompoundReferenceRenderer extends CompoundNodeRenderer{ public @NotNull String getClassName() { return myProperties.getClassName(); } + + protected final PsiElement getContext(Project project, DebuggerContext context) { + DebugProcess process = context.getDebugProcess(); + GlobalSearchScope scope = process != null ? process.getSearchScope() : GlobalSearchScope.allScope(project); + return DebuggerUtils.findClass(getClassName(), project, scope); + } + + protected final PsiElement getChildValueExpression(String text, DebuggerTreeNode node, DebuggerContext context) { + Project project = node.getProject(); + PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); + return elementFactory.createExpressionFromText(text, getContext(project, context)); + } } From 4035e9c9c3eecf14d79d39f4d20a0be310c07654 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 22 Sep 2015 12:28:30 +0300 Subject: [PATCH 02/18] javadoc --- .../com/intellij/psi/codeStyle/CodeStyleSettings.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java index fc093b7e5e5d..a0766b7e70ba 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettings.java @@ -605,6 +605,17 @@ public class CodeStyleSettings extends CommonCodeStyleSettings implements Clonea return OTHER_INDENT_OPTIONS; } + /** + * If the document has an associated PsiFile, returns options for this file. Otherwise attempts to find associated VirtualFile and + * return options for corresponding FileType. If none are found, other indent options are returned. + * + * @param project The project in which PsiFile should be searched. + * @param document The document to search indent options for. + * @return Indent options from the indent options providers or file type indent options or OTHER_INDENT_OPTIONS. + * @see FileIndentOptionsProvider + * @see FileTypeIndentOptionsProvider + * @see LanguageCodeStyleSettingsProvider + */ @NotNull public IndentOptions getIndentOptionsByDocument(@Nullable Project project, @NotNull Document document) { PsiFile file = project != null ? PsiDocumentManager.getInstance(project).getPsiFile(document) : null; From d9a1f7cfd639d0aaa24fd03368ff8375d63cf5a8 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Tue, 22 Sep 2015 14:07:03 +0300 Subject: [PATCH 03/18] extra space --- platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java b/platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java index bb36b35e7f82..a6a444a47f87 100644 --- a/platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java +++ b/platform/vcs-api/src/com/intellij/vcsUtil/UIVcsUtil.java @@ -31,7 +31,7 @@ public class UIVcsUtil { @NotNull public static String spaceAndThinSpace() { - return " " + FontUtil.canDisplay(UIUtil.getLabelFont(), '\u2009', ""); + return " " + FontUtil.canDisplay(UIUtil.getLabelFont(), '\u2009', " "); } public static JPanel errorPanel(final String text, boolean isError) { From 7e5812dbabc0edd1bf2f71d3119ae4eb6a945d29 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Tue, 22 Sep 2015 14:15:08 +0300 Subject: [PATCH 04/18] NPE in the boot jdk action --- .../openapi/util/SwitchBootJdkAction.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java index 52d50ee38f9d..6d42647ba651 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/SwitchBootJdkAction.java @@ -162,7 +162,7 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { @NotNull private final ComboBox myComboBox; - protected SwitchBootJdkDialog(@Nullable Project project, List jdkBundlesList) { + protected SwitchBootJdkDialog(@Nullable Project project, final List jdkBundlesList) { super(project, false); final ArrayList pathsList = JdkUtil.findJdkPaths(); @@ -175,7 +175,9 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { DefaultComboBoxModel model = new DefaultComboBoxModel(); for (JdkBundleDescriptor jdkBundlePath : pathsList) { - if (!jdkBundlesList.isEmpty() && FileUtil.filesEqual(jdkBundlePath.getBundleAsFile(),jdkBundlesList.get(0).getBundleAsFile())) { + if (!(jdkBundlesList.isEmpty() || jdkBundlePath == null) + && FileUtil.filesEqual(jdkBundlePath.getBundleAsFile(),jdkBundlesList.get(0).getBundleAsFile())) + { continue; } model.addElement(jdkBundlePath); @@ -185,8 +187,20 @@ public class SwitchBootJdkAction extends AnAction implements DumbAware { myComboBox.setRenderer(new ListCellRendererWrapper() { @Override public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) { - JdkBundleDescriptor jdkBundleDescriptor = ((JdkBundleDescriptor)value); - setText(jdkBundleDescriptor.getVisualRepresentation()); + if (value != null) { + JdkBundleDescriptor jdkBundleDescriptor = ((JdkBundleDescriptor)value); + setText(jdkBundleDescriptor.getVisualRepresentation()); + } else { + LOG.error("Null value has been passed to a cell renderer. Available JDKs count: " + pathsList.size()); + StringBuilder jdkNames = new StringBuilder(); + for (JdkBundleDescriptor jdkBundlePath : pathsList) { + if (!jdkBundlesList.isEmpty()) { + continue; + } + jdkNames.append(jdkBundlePath.getVisualRepresentation()).append("; "); + } + LOG.error("Available JDKs names: " + jdkNames.toString()); + } } }); From c34eed42eb937046ae3af0e0fc63d174d836aff1 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Mon, 21 Sep 2015 17:36:18 +0300 Subject: [PATCH 05/18] notnull --- platform/core-api/src/com/intellij/psi/impl/ElementBase.java | 2 +- platform/core-api/src/com/intellij/util/PsiIconUtil.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/core-api/src/com/intellij/psi/impl/ElementBase.java b/platform/core-api/src/com/intellij/psi/impl/ElementBase.java index 702411925593..aff2ecf633b2 100644 --- a/platform/core-api/src/com/intellij/psi/impl/ElementBase.java +++ b/platform/core-api/src/com/intellij/psi/impl/ElementBase.java @@ -128,7 +128,7 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable } @Nullable - private static Icon computeIconNow(PsiElement element, @Iconable.IconFlags int flags) { + private static Icon computeIconNow(@NotNull PsiElement element, @Iconable.IconFlags int flags) { final Icon providersIcon = PsiIconUtil.getProvidersIcon(element, flags); if (providersIcon != null) { return providersIcon instanceof RowIcon ? (RowIcon)providersIcon : createLayeredIcon(element, providersIcon, flags); diff --git a/platform/core-api/src/com/intellij/util/PsiIconUtil.java b/platform/core-api/src/com/intellij/util/PsiIconUtil.java index e46ba964a752..485242b1a955 100644 --- a/platform/core-api/src/com/intellij/util/PsiIconUtil.java +++ b/platform/core-api/src/com/intellij/util/PsiIconUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Iconable; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -31,7 +32,7 @@ import javax.swing.*; public class PsiIconUtil { @Nullable - public static Icon getProvidersIcon(PsiElement element, @Iconable.IconFlags int flags) { + public static Icon getProvidersIcon(@NotNull PsiElement element, @Iconable.IconFlags int flags) { final boolean dumb = DumbService.getInstance(element.getProject()).isDumb(); for (final IconProvider iconProvider : getIconProviders()) { if (dumb && !DumbService.isDumbAware(iconProvider)) { From 04fb864cc4bfc3951565a3990f13df15ee562a8e Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 22 Sep 2015 14:23:18 +0300 Subject: [PATCH 06/18] Reverted --- .../unusedLibrary/simple/expected.xml | 2 +- .../testFramework/PlatformTestCase.java | 19 +------- .../testFramework/UsefulTestCase.java | 3 +- .../com/intellij/testFramework/FixtureRule.kt | 2 +- .../intellij/openapi/util/io/FileUtilRt.java | 47 ++++++++++++------- 5 files changed, 33 insertions(+), 40 deletions(-) diff --git a/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml b/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml index 9cd23b0df42b..8184735d55cf 100644 --- a/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml +++ b/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml @@ -1,7 +1,7 @@ - testSimple.iml + testSimple_0.iml Unused library Unused library 'JUnit' diff --git a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java index 86738af62f47..9ddb3b4c53a7 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java @@ -54,7 +54,6 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl; -import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS; import com.intellij.openapi.vfs.newvfs.persistent.PersistentFSImpl; @@ -192,7 +191,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro @Override protected void setUp() throws Exception { super.setUp(); - myFilesToDelete.add(new File(FileUtilRt.getTempDirectory())); if (ourTestCase != null) { String message = "Previous test " + ourTestCase + " hasn't called tearDown(). Probably overridden without super call."; ourTestCase = null; @@ -264,22 +262,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro @NotNull public static Project createProject(@NotNull String path, String creationPlace) { - return createProject(path, creationPlace, false); - } - - @NotNull - public static Project createProject(@NotNull String path, String creationPlace, boolean clearVfs) { String fileName = PathUtilRt.getFileName(path); - if (clearVfs) { - VirtualFile projectBase = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(fileName.endsWith( - ProjectFileType.DOT_DEFAULT_EXTENSION) ? PathUtilRt.getParentPath(path) : path)); - if (projectBase != null) { - // must be leftovers from the previous test run - for (VirtualFile file : ((NewVirtualFile)projectBase).iterInDbChildren()) { - delete(file); - } - } - } try { String projectName = FileUtilRt.getNameWithoutExtension(fileName); @@ -324,7 +307,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro } protected File getIprFile() throws IOException { - File tempFile = FileUtil.createTempFile(getName(), ProjectFileType.DOT_DEFAULT_EXTENSION); + File tempFile = FileUtil.createTempFile(getName() + "_", ProjectFileType.DOT_DEFAULT_EXTENSION); myFilesToDelete.add(tempFile); return tempFile; } diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index 2496c7deb3d2..fcc8bee14fb6 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -139,8 +139,7 @@ public abstract class UsefulTestCase extends TestCase { String testName = FileUtil.sanitizeFileName(getTestName(true)); if (StringUtil.isEmptyOrSpaces(testName)) testName = ""; testName = new File(testName).getName(); // in case the test name contains file separators - File tempDirectory = FileUtil.createTempDirectory(new File(ORIGINAL_TEMP_DIR), TEMP_DIR_MARKER + testName, ""); - myTempDir = tempDirectory.getPath(); + myTempDir = FileUtil.toSystemDependentName(ORIGINAL_TEMP_DIR + "/" + TEMP_DIR_MARKER + testName + "_"+ RNG.nextInt(1000)); FileUtil.resetCanonicalTempPathCache(myTempDir); } ApplicationInfoImpl.setInPerformanceTest(isPerformanceTest()); diff --git a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt index 87de6b1d6434..bb8ddc710b74 100644 --- a/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt +++ b/platform/testFramework/testSrc/com/intellij/testFramework/FixtureRule.kt @@ -72,7 +72,7 @@ public class ProjectRule() : ExternalResource() { val buffer = ByteArrayOutputStream() java.lang.Throwable(projectPath).printStackTrace(PrintStream(buffer)) - val project = PlatformTestCase.createProject(projectPath, "Light project: $buffer", false) as ProjectEx + val project = PlatformTestCase.createProject(projectPath, "Light project: $buffer") as ProjectEx Disposer.register(ApplicationManager.getApplication(), Disposable { try { disposeProject() diff --git a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java index fe7fdf648c90..8a48ba176218 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java @@ -385,14 +385,12 @@ public class FileUtilRt { if (suffix == null) { suffix = ".tmp"; } - // normalize and use only the file name from the prefix - prefix = new File(prefix).getName(); int exceptionsCount = 0; - int i = 0; while (true) { try { - final File temp = callCreate(dir, prefix, suffix, isDirectory, i); + // If there was an IOException, there's no reason to do sequential search - fallback to random + final File temp = createTemp(prefix, suffix, dir, isDirectory, exceptionsCount > 0); return normalizeFile(temp); } catch (IOException e) { // Win32 createFileExclusively access denied @@ -400,28 +398,41 @@ public class FileUtilRt { throw e; } } - i++; // for some reason the file1 can't be created (previous file1 was deleted but got locked by anti-virus?). try file2. - if (i > 2) { - i = 2 + (int)(System.nanoTime() % 998); // generate random suffix if too many failures - } } } @NotNull - private static File callCreate(@NotNull File directory, - @NotNull String prefix, + private static File createTemp(@NotNull String prefix, @NotNull String suffix, + @NotNull File directory, boolean isDirectory, - int i) throws IOException { - prefix += i == 0 ? "" : i; - if (prefix.endsWith(".") && suffix.startsWith(".")) { - prefix = prefix.substring(0, prefix.length() - 1); + boolean randomName) throws IOException { + // Fallback to the original File.createTempFile + if (randomName) { + @SuppressWarnings("SSBasedInspection") + File res = File.createTempFile(prefix, suffix, directory); + if (isDirectory) { + if (!res.delete() || !res.mkdir()) { + throw new IOException("Cannot create directory: " + res); + } + } + return res; } - String name = prefix + suffix; - File f = new File(directory, name); - if (!name.equals(f.getName())) { - throw new IOException("Unable to create temporary file " + f + " for name " + name); + + // normalize and use only the file name from the prefix + prefix = new File(prefix).getName(); + + File f; + int i = 0; + do { + String name = prefix + i + suffix; + f = new File(directory, name); + if (!name.equals(f.getName())) { + throw new IOException("Unable to create temporary file " + f + " for name " + name); + } + i++; } + while (f.exists()); boolean success = isDirectory ? f.mkdir() : f.createNewFile(); if (!success) { From c3c2221197c38caf2988da86c634ace9c8622523 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 22 Sep 2015 14:38:18 +0300 Subject: [PATCH 07/18] declare collections as interface: cleanup duplicated code; fix 'weaken to null' suggestion for variables; weakest type finder: ignore calls with type cast as parent (IDEA-145398) --- ...eclareCollectionAsInterfaceInspection.java | 109 ++++-------------- .../siyeh/ig/psiutils/WeakestTypeFinder.java | 5 +- .../DeclareCollectionAsInterface.java | 9 ++ ...reCollectionAsInterfaceInspectionTest.java | 2 + 4 files changed, 38 insertions(+), 87 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspection.java index 7f5012f2be76..23158c5fbe57 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspection.java @@ -31,7 +31,6 @@ import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.CollectionUtils; import com.siyeh.ig.psiutils.LibraryUtil; -import com.siyeh.ig.psiutils.TypeUtils; import com.siyeh.ig.psiutils.WeakestTypeFinder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -93,8 +92,7 @@ public class DeclareCollectionAsInterfaceInspection extends BaseInspection { return new DeclareCollectionAsInterfaceFix((String)infos[0]); } - private static class DeclareCollectionAsInterfaceFix - extends InspectionGadgetsFix { + private static class DeclareCollectionAsInterfaceFix extends InspectionGadgetsFix { private final String typeString; @@ -124,42 +122,18 @@ public class DeclareCollectionAsInterfaceInspection extends BaseInspection { return; } final StringBuilder newElementText = new StringBuilder(typeString); - final PsiJavaCodeReferenceElement referenceElement = - (PsiJavaCodeReferenceElement)parent; - final PsiReferenceParameterList parameterList = - referenceElement.getParameterList(); + final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)parent; + final PsiReferenceParameterList parameterList = referenceElement.getParameterList(); if (parameterList != null) { - final PsiTypeElement[] typeParameterElements = - parameterList.getTypeParameterElements(); - if (typeParameterElements.length > 0) { - newElementText.append('<'); - final PsiTypeElement typeParameterElement1 = - typeParameterElements[0]; - newElementText.append(typeParameterElement1.getText()); - for (int i = 1; i < typeParameterElements.length; i++) { - newElementText.append(','); - final PsiTypeElement typeParameterElement = - typeParameterElements[i]; - newElementText.append(typeParameterElement.getText()); - } - newElementText.append('>'); - } + newElementText.append(parameterList.getText()); } final PsiElement grandParent = parent.getParent(); if (!(grandParent instanceof PsiTypeElement)) { return; } - final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); - final PsiElementFactory factory = facade.getElementFactory(); - final PsiType type = factory.createTypeFromText( - newElementText.toString(), element); - final PsiTypeElement newTypeElement = factory.createTypeElement( - type); - final PsiElement insertedElement = - grandParent.replace(newTypeElement); - final JavaCodeStyleManager styleManager = - JavaCodeStyleManager.getInstance(project); - styleManager.shortenClassReferences(insertedElement); + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + final PsiTypeElement newTypeElement = factory.createTypeElementFromText(newElementText.toString(), element); + JavaCodeStyleManager.getInstance(project).shortenClassReferences(grandParent.replace(newTypeElement)); } } @@ -168,8 +142,7 @@ public class DeclareCollectionAsInterfaceInspection extends BaseInspection { return new DeclareCollectionAsInterfaceVisitor(); } - private class DeclareCollectionAsInterfaceVisitor - extends BaseInspectionVisitor { + private class DeclareCollectionAsInterfaceVisitor extends BaseInspectionVisitor { @Override public void visitVariable(@NotNull PsiVariable variable) { @@ -205,40 +178,8 @@ public class DeclareCollectionAsInterfaceInspection extends BaseInspection { if (!CollectionUtils.isConcreteCollectionClass(type) || LibraryUtil.isOverrideOfLibraryMethodParameter(variable)) { return; } - final PsiTypeElement typeElement = variable.getTypeElement(); - if (typeElement == null) { - return; - } - final PsiJavaCodeReferenceElement reference = - typeElement.getInnermostComponentReferenceElement(); - if (reference == null) { - return; - } - final PsiElement nameElement = reference.getReferenceNameElement(); - if (nameElement == null) { - return; - } - final Collection weaklings = - WeakestTypeFinder.calculateWeakestClassesNecessary(variable, - false, true); - if (weaklings.isEmpty()) { - return; - } - final List weaklingList = new ArrayList(weaklings); - final PsiClassType javaLangObject = TypeUtils.getObjectType(variable); - final PsiClass objectClass = javaLangObject.resolve(); - weaklingList.remove(objectClass); - if (weaklingList.isEmpty()) { - final String typeText = type.getCanonicalText(); - final String interfaceText = - CollectionUtils.getInterfaceForClass(typeText); - registerError(nameElement, interfaceText); - } - else { - final PsiClass weakling = weaklingList.get(0); - final String qualifiedName = weakling.getQualifiedName(); - registerError(nameElement, qualifiedName); - } + + registerWeakenError(type, variable.getTypeElement(), variable); } @Override @@ -252,34 +193,31 @@ public class DeclareCollectionAsInterfaceInspection extends BaseInspection { return; } final PsiType type = method.getReturnType(); - if (!CollectionUtils.isConcreteCollectionClass(type)) { + if (!CollectionUtils.isConcreteCollectionClass(type) || LibraryUtil.isOverrideOfLibraryMethod(method)) { return; } - if (LibraryUtil.isOverrideOfLibraryMethod(method)) { - return; - } - final PsiTypeElement typeElement = method.getReturnTypeElement(); + + registerWeakenError(type, method.getReturnTypeElement(), method); + } + + private void registerWeakenError(PsiType type, PsiTypeElement typeElement, PsiElement variable) { if (typeElement == null) { return; } - final PsiJavaCodeReferenceElement referenceElement = - typeElement.getInnermostComponentReferenceElement(); - if (referenceElement == null) { + final PsiJavaCodeReferenceElement reference = typeElement.getInnermostComponentReferenceElement(); + if (reference == null) { return; } - final PsiElement nameElement = - referenceElement.getReferenceNameElement(); + final PsiElement nameElement = reference.getReferenceNameElement(); if (nameElement == null) { return; } - final Collection weaklings = - WeakestTypeFinder.calculateWeakestClassesNecessary(method, - false, true); + final Collection weaklings = WeakestTypeFinder.calculateWeakestClassesNecessary(variable, false, true); if (weaklings.isEmpty()) { return; } - final List weaklingList = new ArrayList(weaklings); - final PsiClassType javaLangObject = TypeUtils.getObjectType(method); + final PsiClassType javaLangObject = PsiType.getJavaLangObject(nameElement.getManager(), nameElement.getResolveScope()); + final List weaklingList = new ArrayList(weaklings); final PsiClass objectClass = javaLangObject.resolve(); weaklingList.remove(objectClass); if (weaklingList.isEmpty()) { @@ -292,7 +230,8 @@ public class DeclareCollectionAsInterfaceInspection extends BaseInspection { } else { final PsiClass weakling = weaklingList.get(0); - registerError(nameElement, weakling.getQualifiedName()); + final String qualifiedName = weakling.getQualifiedName(); + registerError(nameElement, qualifiedName); } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java index 53f943fdf3f1..499f9c618d19 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/WeakestTypeFinder.java @@ -126,7 +126,8 @@ public class WeakestTypeFinder { } else if (referenceGrandParent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)referenceGrandParent; - if (!findWeakestType(methodCallExpression, weakestTypeClasses)) { + if (PsiUtil.skipParenthesizedExprUp(methodCallExpression.getParent()) instanceof PsiTypeCastExpression || + !findWeakestType(methodCallExpression, weakestTypeClasses)) { return Collections.emptyList(); } } @@ -408,7 +409,7 @@ public class WeakestTypeFinder { } private static List findAllSuperMethods(PsiMethod method) { - final List result = new ArrayList(); + final List result = new ArrayList(); SuperMethodsSearch.search(method, null, true, false).forEach(new Processor() { @Override diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/declare_collection_as_interface/DeclareCollectionAsInterface.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/declare_collection_as_interface/DeclareCollectionAsInterface.java index f21cc080de25..107257587625 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/declare_collection_as_interface/DeclareCollectionAsInterface.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/abstraction/declare_collection_as_interface/DeclareCollectionAsInterface.java @@ -70,4 +70,13 @@ public class DeclareCollectionAsInterface String s = stringToProperties2(""); s = stringToProperties3(""); } + + private Properties properties; + public void setProperties(Properties properties) { + if (properties == null) { + this.properties = new Properties(); + } else { + this.properties = (Properties) properties.clone(); + } + } } diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspectionTest.java index 5553d2585199..d5429383c643 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/abstraction/DeclareCollectionAsInterfaceInspectionTest.java @@ -1,7 +1,9 @@ package com.siyeh.ig.abstraction; import com.intellij.codeInspection.InspectionProfileEntry; +import com.intellij.testFramework.LightProjectDescriptor; import com.siyeh.ig.LightInspectionTestCase; +import org.jetbrains.annotations.NotNull; public class DeclareCollectionAsInterfaceInspectionTest extends LightInspectionTestCase { From 3b054a1d89cb6c6b702fdf8bda0aa2ce289c3128 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Tue, 22 Sep 2015 14:36:51 +0300 Subject: [PATCH 08/18] cleanup --- .../lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java b/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java index 023ed3998829..cf2fa8d6609e 100644 --- a/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java +++ b/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,7 @@ import javax.swing.tree.TreeNode; /** * @author Konstantin Bulenkov * @deprecated - * @see com.intellij.ui.popup.HintUpdateSupply + * @see HintUpdateSupply */ public class JBTreeWithHintProvider extends DnDAwareTree { { From b7dc05bc1ad886ccd792f1ff87ec7fe46f00b591 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Tue, 22 Sep 2015 14:41:02 +0300 Subject: [PATCH 09/18] DBE-1039 SQL: execute selected statements from the file structure --- .../newStructureView/StructureViewComponent.java | 13 ++++++++++++- .../com/intellij/ide/util/FileStructurePopup.java | 7 ++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index a3b45f166fc3..9619043e859d 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -130,7 +130,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre }; final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.getRootElement())); - JTree tree = new JBTreeWithHintProvider(model); + JTree tree = new MyTree(model); tree.setRootVisible(showRootNode); tree.setShowsRootHandles(true); @@ -168,6 +168,17 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre } }; } + + private static class MyTree extends JBTreeWithHintProvider implements PlaceProvider { + public MyTree(javax.swing.tree.TreeModel treemodel) { + super(treemodel); + } + + @Override + public String getPlace() { + return ActionPlaces.STRUCTURE_VIEW_TOOLBAR; + } + } public void showToolbar() { setToolbar(createToolbar()); diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java index 3fc771141d10..5e67fe6cc371 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java @@ -1112,7 +1112,7 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner { } } - class FileStructureTree extends JBTreeWithHintProvider implements AlwaysExpandedTree { + class FileStructureTree extends JBTreeWithHintProvider implements AlwaysExpandedTree, PlaceProvider { private final boolean fast; public FileStructureTree(Object rootElement, boolean fastExpand) { @@ -1157,5 +1157,10 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner { //noinspection ConstantConditions return getPsi((FilteringTreeStructure.FilteringNode)((DefaultMutableTreeNode)selectedValue).getUserObject()); } + + @Override + public String getPlace() { + return ActionPlaces.STRUCTURE_VIEW_POPUP; + } } } From 3c3f90ef545ab2b0844ff4e2ea34ef59910ba248 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 22 Sep 2015 13:57:34 +0200 Subject: [PATCH 10/18] better recursive NIO deletion fix --- .../com/intellij/openapi/util/io/FileUtilRt.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java index 8a48ba176218..3c1cfabb1acb 100644 --- a/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java +++ b/platform/util-rt/src/com/intellij/openapi/util/io/FileUtilRt.java @@ -97,9 +97,7 @@ public class FileUtilRt { ourPathToFileMethod = pathClass.getMethod("toFile"); ourFilesWalkMethod = filesClass.getMethod("walkFileTree", pathClass, visitorClass); ourFilesDeleteIfExistsMethod = filesClass.getMethod("deleteIfExists", pathClass); - final Class fileVisitResultClass = Class.forName("java.nio.file.FileVisitResult"); - final Object Result_Continue = fileVisitResultClass.getDeclaredField("CONTINUE").get(null); - final Object Result_Terminate = fileVisitResultClass.getDeclaredField("TERMINATE").get(null); + final Object Result_Continue = Class.forName("java.nio.file.FileVisitResult").getDeclaredField("CONTINUE").get(null); ourDeletionVisitor = Proxy.newProxyInstance(FileUtilRt.class.getClassLoader(), new Class[]{visitorClass}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { @@ -111,7 +109,13 @@ public class FileUtilRt { final String methodName = method.getName(); if ("visitFile".equals(methodName) || "postVisitDirectory".equals(methodName)) { if (!performDelete(args[0])) { - return Result_Terminate; + throw new IOException("Failed to delete " + args[0]) { + // optimization: the stacktrace is not needed: the exception is used to terminate tree walkup and to pass the result + @Override + public synchronized Throwable fillInStackTrace() { + return this; + } + }; } } } @@ -712,7 +716,7 @@ public class FileUtilRt { logger().info(e); return false; } - return !file.exists(); + return true; } private static boolean deleteRecursively(@NotNull File file) { From 39f147c11da2fb7b0879b226456b6b2e4b3212f0 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 21 Sep 2015 19:58:09 +0300 Subject: [PATCH 11/18] add filters for daltonization and simulation ColorBlindness --- .../intellij/ide/ui/DaltonizationFilter.java | 57 ++++++++++ .../com/intellij/ide/ui/SimulationFilter.java | 101 ++++++++++++++++++ .../src/com/intellij/ide/ui/WeightFilter.java | 34 ++++++ 3 files changed, 192 insertions(+) create mode 100644 platform/editor-ui-api/src/com/intellij/ide/ui/DaltonizationFilter.java create mode 100644 platform/editor-ui-api/src/com/intellij/ide/ui/SimulationFilter.java create mode 100644 platform/editor-ui-api/src/com/intellij/ide/ui/WeightFilter.java diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/DaltonizationFilter.java b/platform/editor-ui-api/src/com/intellij/ide/ui/DaltonizationFilter.java new file mode 100644 index 000000000000..ced72d726d5c --- /dev/null +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/DaltonizationFilter.java @@ -0,0 +1,57 @@ +package com.intellij.ide.ui; + +import java.awt.image.ImageFilter; + +final class DaltonizationFilter extends WeightFilter { + public static final ImageFilter protanopia = forProtanopia(null); + public static final ImageFilter deuteranopia = forDeuteranopia(null); + public static final ImageFilter tritanopia = forTritanopia(null); + + public static ImageFilter forProtanopia(Double weight) { + return new DaltonizationFilter(weight, 0, 2.02344, -2.52581, 0, 1, 0, 0, 0, 1); + } + + public static ImageFilter forDeuteranopia(Double weight) { + return new DaltonizationFilter(weight, 1, 0, 0, 0.494207, 0, 1.24827, 0, 0, 1); + } + + public static ImageFilter forTritanopia(Double weight) { + return new DaltonizationFilter(weight, 1, 0, 0, 0, 1, 0, -0.395913, 0.801109, 0); + } + + private final double[] myMatrix; + + private DaltonizationFilter(Double weight, double... matrix) { + super(weight); + myMatrix = matrix; + } + + @Override + int toRGB(int srcR, int srcG, int srcB) { + // RGB to LMS matrix conversion + double L = (17.8824 * srcR) + (43.5161 * srcG) + (4.11935 * srcB); + double M = (3.45565 * srcR) + (27.1554 * srcG) + (3.86714 * srcB); + double S = (0.0299566 * srcR) + (0.184309 * srcG) + (1.46709 * srcB); + // Simulate color blindness + double l = L * myMatrix[0] + M * myMatrix[1] + S * myMatrix[2]; + double m = L * myMatrix[3] + M * myMatrix[4] + S * myMatrix[5]; + double s = L * myMatrix[6] + M * myMatrix[7] + S * myMatrix[8]; + // LMS to RGB matrix conversion + double R = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s); + double G = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s); + double B = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s); + // Isolate invisible colors to color vision deficiency (calculate error matrix) + R = srcR - R; + G = srcG - G; + B = srcB - B; + // Shift colors towards visible spectrum (apply error modifications) + // and add compensation to original values + double dstR = srcR + (0.0 * R) + (0.0 * G) + (0.0 * B); + double dstG = srcG + (0.7 * R) + (1.0 * G) + (0.0 * B); + double dstB = srcB + (0.7 * R) + (0.0 * G) + (1.0 * B); + return toRGB(srcR, srcG, srcB, + dstR < 0 ? 0 : dstR > 255 ? 255 : dstR, + dstR < 0 ? 0 : dstR > 255 ? 255 : dstG, + dstR < 0 ? 0 : dstR > 255 ? 255 : dstB); + } +} diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/SimulationFilter.java b/platform/editor-ui-api/src/com/intellij/ide/ui/SimulationFilter.java new file mode 100644 index 000000000000..86137be69739 --- /dev/null +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/SimulationFilter.java @@ -0,0 +1,101 @@ +package com.intellij.ide.ui; + +import java.awt.image.ImageFilter; + +final class SimulationFilter extends WeightFilter { + public static final ImageFilter protanopia = forProtanopia(null); + public static final ImageFilter deuteranopia = forDeuteranopia(null); + public static final ImageFilter tritanopia = forTritanopia(null); + public static final ImageFilter achromatopsia = forAchromatopsia(null); + + public static ImageFilter forProtanopia(Double weight) { + return new SimulationFilter(weight, 0.7465, 0.2535, 1.273463, -0.073894); + } + + public static ImageFilter forDeuteranopia(Double weight) { + return new SimulationFilter(weight, 1.4, -0.4, 0.968437, 0.003331); + } + + public static ImageFilter forTritanopia(Double weight) { + return new SimulationFilter(weight, 0.1748, 0, 0.062921, 0.292119); + } + + public static ImageFilter forAchromatopsia(Double weight) { + return new WeightFilter(weight) { + @Override + int toRGB(int srcR, int srcG, int srcB) { + double gray = 0.212656 * srcR + 0.715158 * srcG + 0.072186 * srcB; + return toRGB(srcR, srcG, srcB, gray, gray, gray); + } + }; + } + + private final double myConfuseX; + private final double myConfuseY; + private final double myConfuseM; + private final double myConfuseYint; + + private SimulationFilter(Double weight, double x, double y, double m, double yint) { + super(weight); + myConfuseX = x; + myConfuseY = y; + myConfuseM = m; + myConfuseYint = yint; + } + + @Override + int toRGB(int srcR, int srcG, int srcB) { + // Convert source color into XYZ color space + double powR = Math.pow(srcR, 2.2); + double powG = Math.pow(srcG, 2.2); + double powB = Math.pow(srcB, 2.2); + // RGB->XYZ (sRGB:D65) + double X = 0.4124240 * powR + 0.357579 * powG + 0.1804640 * powB; + double Y = 0.2126560 * powR + 0.715158 * powG + 0.0721856 * powB; + double Z = 0.0193324 * powR + 0.119193 * powG + 0.9504440 * powB; + // Convert XYZ into xyY Chromacity Coordinates (xy) and Luminance (Y) + double chroma_x = X / (X + Y + Z); + double chroma_y = Y / (X + Y + Z); + // Generate the "Confusion Line" between the source color and the Confusion Point + double m = (chroma_y - myConfuseY) / (chroma_x - myConfuseX); // slope of Confusion Line + double yint = chroma_y - chroma_x * m; // y-intercept of confusion line (x-intercept = 0.0) + // How far the xy coords deviate from the simulation + double deviate_x = (myConfuseYint - yint) / (m - myConfuseM); + double deviate_y = (m * deviate_x) + yint; + // Compute the simulated color's XYZ coords + X = deviate_x * Y / deviate_y; + Z = (1.0 - (deviate_x + deviate_y)) * Y / deviate_y; + // Neutral grey calculated from luminance (in D65) + double neutral_X = Y * 0.312713 / 0.329016; + double neutral_Z = Y * 0.358271 / 0.329016; + // Difference between simulated color and neutral grey + double diffX = neutral_X - X; + double diffZ = neutral_Z - Z; + // XYZ->RGB (sRGB:D65) + double diffR = +3.2407100 * diffX - 0.4985710 * diffZ; + double diffG = -0.9692580 * diffX + 0.0415557 * diffZ; + double diffB = +0.0556352 * diffX + 1.0570700 * diffZ; + // Convert to RGB color space + // XYZ->RGB (sRGB:D65) + double dstR = +3.2407100 * X - 1.537260 * Y - 0.4985710 * Z; + double dstG = -0.9692580 * X + 1.875990 * Y + 0.0415557 * Z; + double dstB = +0.0556352 * X - 0.203996 * Y + 1.0570700 * Z; + // Compensate simulated color towards a neutral fit in RGB space + double fitR = ((dstR < 0 ? 0 : 1) - dstR) / diffR; + double fitG = ((dstG < 0 ? 0 : 1) - dstG) / diffG; + double fitB = ((dstB < 0 ? 0 : 1) - dstB) / diffB; + double adjust = Math.max(Math.max( // highest value + (fitR < 0 || 1 < fitR) ? 0 : fitR, + (fitG < 0 || 1 < fitG) ? 0 : fitG), + (fitB < 0 || 1 < fitB) ? 0 : fitB); + // Shift proportional to the greatest shift + dstR += adjust * diffR; + dstG += adjust * diffG; + dstB += adjust * diffB; + // Apply gamma correction + dstR = Math.pow(dstR, 1 / 2.2); + dstG = Math.pow(dstG, 1 / 2.2); + dstB = Math.pow(dstB, 1 / 2.2); + return toRGB(srcR, srcG, srcB, dstR, dstG, dstB); + } +} diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/WeightFilter.java b/platform/editor-ui-api/src/com/intellij/ide/ui/WeightFilter.java new file mode 100644 index 000000000000..69d6e0ae997d --- /dev/null +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/WeightFilter.java @@ -0,0 +1,34 @@ +package com.intellij.ide.ui; + +import java.awt.image.RGBImageFilter; + +abstract class WeightFilter extends RGBImageFilter { + private final Double myWeight; + + WeightFilter(Double weight) { + if (weight != null && (weight < 0 || 1 < weight)) { + throw new IllegalArgumentException("weight " + weight + " out of [0..1]"); + } + myWeight = weight; + canFilterIndexColorModel = true; + } + + @Override + public final int filterRGB(int x, int y, int rgb) { + return (0xFF000000 & rgb) | toRGB(0xFF & (rgb >> 16), 0xFF & (rgb >> 8), 0xFF & rgb); + } + + abstract int toRGB(int srcR, int srcG, int srcB); + + final int toRGB(int srcR, int srcG, int srcB, double dstR, double dstG, double dstB) { + if (myWeight != null) { + dstR = dstR * myWeight + srcR * (1 - myWeight); + dstG = dstG * myWeight + srcG * (1 - myWeight); + dstB = dstB * myWeight + srcB * (1 - myWeight); + } + srcR = (int)dstR; + srcG = (int)dstG; + srcB = (int)dstB; + return (srcR << 16) | (srcG << 8) | srcB; + } +} From 46f772ca7889ef7f4020169896011eb02e18d6cc Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 21 Sep 2015 20:30:44 +0300 Subject: [PATCH 12/18] add utility method to filter images --- .../platform-impl/src/com/intellij/ui/BalloonImpl.java | 3 +-- .../util/src/com/intellij/openapi/util/IconLoader.java | 10 +--------- platform/util/src/com/intellij/util/ui/ImageUtil.java | 8 +++++++- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index bcec64bb14af..a84317dc5f3b 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -1433,8 +1433,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui { } } }; - ImageProducer prod = new FilteredImageSource(image.getSource(), filter); - return Toolkit.getDefaultToolkit().createImage(prod); + return ImageUtil.filter(image, filter); } @Override diff --git a/platform/util/src/com/intellij/openapi/util/IconLoader.java b/platform/util/src/com/intellij/openapi/util/IconLoader.java index c653cdb2172a..bd8d065bbf34 100644 --- a/platform/util/src/com/intellij/openapi/util/IconLoader.java +++ b/platform/util/src/com/intellij/openapi/util/IconLoader.java @@ -36,8 +36,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; -import java.awt.image.FilteredImageSource; -import java.awt.image.ImageProducer; import java.lang.ref.Reference; import java.lang.reflect.Field; import java.net.URL; @@ -286,7 +284,7 @@ public final class IconLoader { graphics.dispose(); - Image img = createDisabled(image); + Image img = ImageUtil.filter(image, UIUtil.getGrayFilter()); if (UIUtil.isRetina()) img = RetinaImage.createFrom(img, 2, ImageLoader.ourComponent); disabledIcon = new JBImageIcon(img); @@ -295,12 +293,6 @@ public final class IconLoader { return disabledIcon; } - private static Image createDisabled(BufferedImage image) { - final GrayFilter filter = UIUtil.getGrayFilter(); - final ImageProducer prod = new FilteredImageSource(image.getSource(), filter); - return Toolkit.getDefaultToolkit().createImage(prod); - } - public static Icon getTransparentIcon(@NotNull final Icon icon) { return getTransparentIcon(icon, 0.5f); } diff --git a/platform/util/src/com/intellij/util/ui/ImageUtil.java b/platform/util/src/com/intellij/util/ui/ImageUtil.java index 3832c767fe51..af8565e2cec8 100644 --- a/platform/util/src/com/intellij/util/ui/ImageUtil.java +++ b/platform/util/src/com/intellij/util/ui/ImageUtil.java @@ -18,7 +18,7 @@ package com.intellij.util.ui; import org.jetbrains.annotations.NotNull; import java.awt.*; -import java.awt.image.BufferedImage; +import java.awt.image.*; /** * @author Konstantin Bulenkov @@ -36,4 +36,10 @@ public class ImageUtil { g.dispose(); return bufferedImage; } + + public static Image filter(Image image, ImageFilter filter) { + if (image == null || filter == null) return image; + return Toolkit.getDefaultToolkit().createImage( + new FilteredImageSource(image.getSource(), filter)); + } } From 7750a361d76687c0af3f171f08f85500704b4f1e Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 22 Sep 2015 14:22:17 +0300 Subject: [PATCH 13/18] add base test for color-blindness simulation/daltonization --- .../src/com/intellij/ide/ui/WeightFilter.java | 3 + .../intellij/ide/ui/ColorBlindnessTest.java | 58 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 platform/platform-tests/testSrc/com/intellij/ide/ui/ColorBlindnessTest.java diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/WeightFilter.java b/platform/editor-ui-api/src/com/intellij/ide/ui/WeightFilter.java index 69d6e0ae997d..8e00effef346 100644 --- a/platform/editor-ui-api/src/com/intellij/ide/ui/WeightFilter.java +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/WeightFilter.java @@ -21,6 +21,9 @@ abstract class WeightFilter extends RGBImageFilter { abstract int toRGB(int srcR, int srcG, int srcB); final int toRGB(int srcR, int srcG, int srcB, double dstR, double dstG, double dstB) { + if (Double.isNaN(dstR)) dstR = 0; + if (Double.isNaN(dstG)) dstG = 0; + if (Double.isNaN(dstB)) dstB = 0; if (myWeight != null) { dstR = dstR * myWeight + srcR * (1 - myWeight); dstG = dstG * myWeight + srcG * (1 - myWeight); diff --git a/platform/platform-tests/testSrc/com/intellij/ide/ui/ColorBlindnessTest.java b/platform/platform-tests/testSrc/com/intellij/ide/ui/ColorBlindnessTest.java new file mode 100644 index 000000000000..361c262adf6d --- /dev/null +++ b/platform/platform-tests/testSrc/com/intellij/ide/ui/ColorBlindnessTest.java @@ -0,0 +1,58 @@ +package com.intellij.ide.ui; + +import junit.framework.TestCase; + +import java.awt.image.ImageFilter; +import java.awt.image.RGBImageFilter; + +public final class ColorBlindnessTest extends TestCase { + public void testProtanopiaDaltonization() { + testZeroFilter(DaltonizationFilter.forProtanopia(0.0)); + compareFilters(DaltonizationFilter.forProtanopia(1.0), DaltonizationFilter.protanopia); + } + + public void testDeuteranopiaDaltonization() { + testZeroFilter(DaltonizationFilter.forDeuteranopia(0.0)); + compareFilters(DaltonizationFilter.forDeuteranopia(1.0), DaltonizationFilter.deuteranopia); + } + + public void testTritanopiaDaltonization() { + testZeroFilter(DaltonizationFilter.forTritanopia(0.0)); + compareFilters(DaltonizationFilter.forTritanopia(1.0), DaltonizationFilter.tritanopia); + } + + public void testProtanopiaSimulation() { + testZeroFilter(SimulationFilter.forProtanopia(0.0)); + compareFilters(SimulationFilter.forProtanopia(1.0), SimulationFilter.protanopia); + } + + public void testDeuteranopiaSimulation() { + testZeroFilter(SimulationFilter.forDeuteranopia(0.0)); + compareFilters(SimulationFilter.forDeuteranopia(1.0), SimulationFilter.deuteranopia); + } + + public void testTritanopiaSimulation() { + testZeroFilter(SimulationFilter.forTritanopia(0.0)); + compareFilters(SimulationFilter.forTritanopia(1.0), SimulationFilter.tritanopia); + } + + public void testAchromatopsiaSimulation() { + testZeroFilter(SimulationFilter.forAchromatopsia(0.0)); + compareFilters(SimulationFilter.forAchromatopsia(1.0), SimulationFilter.achromatopsia); + } + + private static void testZeroFilter(ImageFilter filter) { + RGBImageFilter rgb = (RGBImageFilter)filter; + for (int i = 0; i < 0x01000000; i++) { + assertEquals(i, rgb.filterRGB(0, 0, i)); + } + } + + private static void compareFilters(ImageFilter one, ImageFilter two) { + RGBImageFilter rgb1 = (RGBImageFilter)one; + RGBImageFilter rgb2 = (RGBImageFilter)two; + for (int i = 0; i < 0x01000000; i++) { + assertEquals(rgb1.filterRGB(0, 0, i), rgb2.filterRGB(0, 0, i)); + } + } +} From 4527f3e65e02110466f8480af388d6ccaecdf799 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 22 Sep 2015 14:55:32 +0300 Subject: [PATCH 14/18] add filter for icons --- .../src/com/intellij/ide/ui/UISettings.java | 8 ++++++ .../util/resources/misc/registry.properties | 2 ++ .../com/intellij/openapi/util/IconLoader.java | 28 +++++++++++++++---- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java index 0617189a53c8..5f0fb7766179 100644 --- a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java @@ -20,6 +20,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.*; +import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SimpleModificationTracker; import com.intellij.openapi.util.SystemInfo; @@ -167,6 +168,13 @@ public class UISettings extends SimpleModificationTracker implements PersistentS incModificationCount(); myDispatcher.getMulticaster().uiSettingsChanged(this); ApplicationManager.getApplication().getMessageBus().syncPublisher(UISettingsListener.TOPIC).uiSettingsChanged(this); + IconLoader.setFilter(COLOR_BLINDNESS == ColorBlindness.protanopia + ? DaltonizationFilter.protanopia + : COLOR_BLINDNESS == ColorBlindness.deuteranopia + ? DaltonizationFilter.deuteranopia + : COLOR_BLINDNESS == ColorBlindness.tritanopia + ? DaltonizationFilter.tritanopia + : null); } public void removeUISettingsListener(UISettingsListener listener) { diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 55eb0e82bf3b..f91ff7f4a3fb 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -42,6 +42,8 @@ actionSystem.assertFocusAccessFromEdt=true actionSystem.enableAbbreviations=true actionSystem.extendedKeyCode.disabled=false +color.blindness.icon.filter=false + ide.firstStartup=true ide.debugMode=false ide.debugger.inline=true diff --git a/platform/util/src/com/intellij/openapi/util/IconLoader.java b/platform/util/src/com/intellij/openapi/util/IconLoader.java index bd8d065bbf34..d80db55011af 100644 --- a/platform/util/src/com/intellij/openapi/util/IconLoader.java +++ b/platform/util/src/com/intellij/openapi/util/IconLoader.java @@ -16,6 +16,7 @@ package com.intellij.openapi.util; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.reference.SoftReference; import com.intellij.util.ConcurrencyUtil; @@ -36,6 +37,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; +import java.awt.image.ImageFilter; import java.lang.ref.Reference; import java.lang.reflect.Field; import java.net.URL; @@ -49,6 +51,7 @@ public final class IconLoader { public static boolean STRICT = false; private static boolean USE_DARK_ICONS = UIUtil.isUnderDarcula(); private static float SCALE = JBUI.scale(1f); + private static ImageFilter IMAGE_FILTER; @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private static final ConcurrentMap ourIconsCache = ContainerUtil.newConcurrentMap(100, 0.9f, 2); @@ -115,6 +118,16 @@ public final class IconLoader { } } + public static void setFilter(ImageFilter filter) { + if (!Registry.is("color.blindness.icon.filter")) { + filter = null; + } + if (IMAGE_FILTER != filter) { + IMAGE_FILTER = filter; + clearCache(); + } + } + private static void clearCache() { ourIconsCache.clear(); ourIcon2DisabledIcon.clear(); @@ -326,22 +339,25 @@ public final class IconLoader { private final URL myUrl; private boolean dark; private float scale; + private ImageFilter filter; private HashMap scaledIcons; public CachedImageIcon(@NotNull URL url) { myUrl = url; dark = USE_DARK_ICONS; scale = SCALE; + filter = IMAGE_FILTER; } @NotNull private synchronized Icon getRealIcon() { - if (isLoaderDisabled() && (myRealIcon == null || dark != USE_DARK_ICONS || scale != SCALE)) return EMPTY_ICON; + if (isLoaderDisabled() && (myRealIcon == null || dark != USE_DARK_ICONS || scale != SCALE || filter != IMAGE_FILTER)) return EMPTY_ICON; - if (dark != USE_DARK_ICONS || scale != SCALE) { + if (dark != USE_DARK_ICONS || scale != SCALE || filter != IMAGE_FILTER) { myRealIcon = null; dark = USE_DARK_ICONS; scale = SCALE; + filter = IMAGE_FILTER; } Object realIcon = myRealIcon; if (realIcon instanceof Icon) return (Icon)realIcon; @@ -352,7 +368,7 @@ public final class IconLoader { if (icon != null) return icon; } - Image image = ImageLoader.loadFromUrl(myUrl); + Image image = ImageUtil.filter(ImageLoader.loadFromUrl(myUrl), filter); icon = checkIcon(image, myUrl); if (icon != null) { @@ -402,7 +418,7 @@ public final class IconLoader { return result; } - final Image image = ImageLoader.loadFromUrl(myUrl, UIUtil.isUnderDarcula(), scaleFactor >= 1.5f); + final Image image = ImageUtil.filter(ImageLoader.loadFromUrl(myUrl, UIUtil.isUnderDarcula(), scaleFactor >= 1.5f), filter); if (image != null) { int width = (int)(getIconWidth() * scaleFactor); int height = (int)(getIconHeight() * scaleFactor); @@ -421,6 +437,7 @@ public final class IconLoader { private Icon myIcon; private boolean isDarkVariant = USE_DARK_ICONS; private float scale = SCALE; + private ImageFilter filter = IMAGE_FILTER; @Override public void paintIcon(Component c, Graphics g, int x, int y) { @@ -443,9 +460,10 @@ public final class IconLoader { } protected final synchronized Icon getOrComputeIcon() { - if (!myWasComputed || isDarkVariant != USE_DARK_ICONS || scale != SCALE) { + if (!myWasComputed || isDarkVariant != USE_DARK_ICONS || scale != SCALE || filter != IMAGE_FILTER) { isDarkVariant = USE_DARK_ICONS; scale = SCALE; + filter = IMAGE_FILTER; myWasComputed = true; myIcon = compute(); } From 96441d887af6346456341d4eb2ae4df59cacc8d3 Mon Sep 17 00:00:00 2001 From: "liana.bakradze" Date: Tue, 22 Sep 2015 15:06:04 +0300 Subject: [PATCH 15/18] added missing icon for action --- python/ide/src/META-INF/pycharm-core.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ide/src/META-INF/pycharm-core.xml b/python/ide/src/META-INF/pycharm-core.xml index be2d315adf7d..c016203dc1dc 100644 --- a/python/ide/src/META-INF/pycharm-core.xml +++ b/python/ide/src/META-INF/pycharm-core.xml @@ -126,7 +126,7 @@ - + From b77b6e05d8e54b85e5a5a91f8b3ed282bfb90ef4 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Tue, 22 Sep 2015 15:53:58 +0300 Subject: [PATCH 16/18] get rid of unused methods --- .../com/intellij/ui/JBTreeWithHintProvider.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java b/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java index cf2fa8d6609e..d3a823d63b01 100644 --- a/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java +++ b/platform/lang-impl/src/com/intellij/ui/JBTreeWithHintProvider.java @@ -18,10 +18,8 @@ package com.intellij.ui; import com.intellij.ide.DataManager; import com.intellij.ide.dnd.aware.DnDAwareTree; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.psi.PsiElement; import com.intellij.ui.popup.HintUpdateSupply; -import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.Nullable; import javax.swing.tree.TreeModel; @@ -57,19 +55,4 @@ public class JBTreeWithHintProvider extends DnDAwareTree { protected PsiElement getPsiElementForHint(final Object selectedValue) { return CommonDataKeys.PSI_ELEMENT.getData(DataManager.getInstance().getDataContext(this)); } - - @Deprecated - public void registerHint(JBPopup hint) { - ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).registerHint(hint); - } - - @Deprecated - public void hideHint() { - ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).hideHint(); - } - - @Deprecated - public void updateHint(PsiElement element) { - ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).updateHint(element); - } } From d3a19d74a05979731a24d02a0ccc5995c07fd059 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 22 Sep 2015 15:57:19 +0300 Subject: [PATCH 17/18] class escapes declared scope: ignore local and anonymous classes; replace duplicated code (IDEA-143851) --- .../ClassEscapesItsScopeInspection.java | 80 +++++-------------- .../ClassEscapesItsScope.java | 23 ++++++ 2 files changed, 42 insertions(+), 61 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ClassEscapesItsScopeInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ClassEscapesItsScopeInspection.java index 0b7b4197706b..e6c12bb0dd52 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ClassEscapesItsScopeInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ClassEscapesItsScopeInspection.java @@ -32,15 +32,13 @@ public class ClassEscapesItsScopeInspection extends BaseInspection { @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "class.escapes.defined.scope.display.name"); + return InspectionGadgetsBundle.message("class.escapes.defined.scope.display.name"); } @Override @NotNull public String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "class.escapes.defined.scope.problem.descriptor"); + return InspectionGadgetsBundle.message("class.escapes.defined.scope.problem.descriptor"); } @Override @@ -48,8 +46,7 @@ public class ClassEscapesItsScopeInspection extends BaseInspection { return new ClassEscapesItsScopeVisitor(); } - private static class ClassEscapesItsScopeVisitor - extends BaseInspectionVisitor { + private static class ClassEscapesItsScopeVisitor extends BaseInspectionVisitor { @Override public void visitMethod(@NotNull PsiMethod method) { @@ -60,31 +57,7 @@ public class ClassEscapesItsScopeInspection extends BaseInspection { if (method.hasModifierProperty(PsiModifier.PRIVATE)) { return; } - final PsiType returnType = method.getReturnType(); - if (returnType == null) { - return; - } - final PsiType componentType = returnType.getDeepComponentType(); - if (!(componentType instanceof PsiClassType)) { - return; - } - final PsiClass returnClass = ((PsiClassType)componentType).resolve(); - if (returnClass == null || returnClass instanceof PsiTypeParameter) { - return; - } - if (!isLessRestrictiveScope(method, returnClass)) { - return; - } - final PsiTypeElement typeElement = method.getReturnTypeElement(); - if (typeElement == null) { - return; - } - final PsiJavaCodeReferenceElement baseTypeElement = - typeElement.getInnermostComponentReferenceElement(); - if (baseTypeElement == null) { - return; - } - registerError(baseTypeElement); + registerError(method, method.getReturnType(), method.getReturnTypeElement()); } @Override @@ -100,7 +73,13 @@ public class ClassEscapesItsScopeInspection extends BaseInspection { if (containingClass.hasModifierProperty(PsiModifier.PRIVATE)) { return; } - final PsiType type = field.getType(); + registerError(field, field.getType(), field.getTypeElement()); + } + + private void registerError(PsiMember member, PsiType type, PsiTypeElement typeElement) { + if (type == null || typeElement == null) { + return; + } final PsiType componentType = type.getDeepComponentType(); if (!(componentType instanceof PsiClassType)) { return; @@ -109,52 +88,31 @@ public class ClassEscapesItsScopeInspection extends BaseInspection { if (fieldClass == null || fieldClass instanceof PsiTypeParameter) { return; } - if (!fieldHasLessRestrictiveScope(field, fieldClass)) { + if (!isLessRestrictiveScope(member, fieldClass)) { return; } - final PsiTypeElement typeElement = field.getTypeElement(); - if (typeElement == null) { - return; - } - final PsiJavaCodeReferenceElement baseTypeElement = - typeElement.getInnermostComponentReferenceElement(); + + final PsiJavaCodeReferenceElement baseTypeElement = typeElement.getInnermostComponentReferenceElement(); if (baseTypeElement == null) { return; } registerError(baseTypeElement); } - - private static boolean isLessRestrictiveScope(PsiMethod method, - PsiClass aClass) { + private static boolean isLessRestrictiveScope(PsiMember method, PsiClass aClass) { final int methodScopeOrder = getScopeOrder(method); final int classScopeOrder = getScopeOrder(aClass); final PsiClass containingClass = method.getContainingClass(); - final int containingClassScopeOrder = - getScopeOrder(containingClass); - if (methodScopeOrder <= classScopeOrder || - containingClassScopeOrder <= classScopeOrder) { + if (containingClass != null && containingClass.getQualifiedName() == null) { return false; } - final PsiMethod[] superMethods = method.findSuperMethods(); - for (PsiMethod superMethod : superMethods) { - if (!isLessRestrictiveScope(superMethod, aClass)) { - return false; - } + final int containingClassScopeOrder = getScopeOrder(containingClass); + if (methodScopeOrder <= classScopeOrder || containingClassScopeOrder <= classScopeOrder) { + return false; } return true; } - private static boolean fieldHasLessRestrictiveScope(PsiField field, - PsiClass aClass) { - final int fieldScopeOrder = getScopeOrder(field); - final PsiClass containingClass = field.getContainingClass(); - final int containingClassScopeOrder = getScopeOrder(containingClass); - final int classScopeOrder = getScopeOrder(aClass); - return fieldScopeOrder > classScopeOrder && - containingClassScopeOrder > classScopeOrder; - } - private static int getScopeOrder(PsiModifierListOwner element) { if (element.hasModifierProperty(PsiModifier.PUBLIC)) { return 4; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ClassEscapesItsScope.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ClassEscapesItsScope.java index df6b98f3bf8e..923bb756e4cf 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ClassEscapesItsScope.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ClassEscapesItsScope.java @@ -6,4 +6,27 @@ public class ClassEscapesItsScope { return new A(); } private class A {} +} + +class BarInside { + private static class Bar {} + void foo() { + class LocalClass implements F { + public Bar bar; + public Bar apply(String s) { + throw new UnsupportedOperationException(); + } + } + } + + class InnerClass implements F { + public Bar bar; + public Bar apply(String s) { + throw new UnsupportedOperationException(); + } + } + + interface F { + R apply(T t); + } } \ No newline at end of file From 37d6e154ae2242be72d269bf4d88744bf3f9389a Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 22 Sep 2015 16:07:43 +0300 Subject: [PATCH 18/18] inherit some text attributes in the darcula color scheme --- .../src/DefaultColorSchemesManager.xml | 77 ------------------- .../resources/colorSchemes/GroovyDarcula.xml | 22 ------ 2 files changed, 99 deletions(-) diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml index b6d950475c56..e6681e5a1f4e 100644 --- a/platform/platform-resources/src/DefaultColorSchemesManager.xml +++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml @@ -1705,12 +1705,6 @@ - - - - - - - - - - - - - -