From 56f6f05c952660cce09c82098d48d115464bb03f Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 12 Jul 2016 13:44:12 +0200 Subject: [PATCH 01/21] force RoamingType.DISABLED for other.xml --- .../src/StateStorageManagerImpl.kt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt index a191aef4b218..9b3a803ea398 100644 --- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt +++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt @@ -223,7 +223,14 @@ open class StateStorageManagerImpl(private val rootTagName: String, throw IllegalArgumentException("Extension is missing for storage file: $filePath") } - val effectiveRoamingType = if (roamingType == RoamingType.DEFAULT && collapsedPath == StoragePathMacros.WORKSPACE_FILE) RoamingType.DISABLED else roamingType + val effectiveRoamingType: RoamingType + if (roamingType != RoamingType.DISABLED && (collapsedPath == StoragePathMacros.WORKSPACE_FILE || collapsedPath == "other.xml")) { + effectiveRoamingType = RoamingType.DISABLED + } + else { + effectiveRoamingType = roamingType + } + val storage = createFileBasedStorage(filePath, collapsedPath, effectiveRoamingType) if (isUseVfsListener == ThreeState.YES && storage is StorageVirtualFileTracker.TrackedStorage) { virtualFileTracker?.put(filePath, storage) From bd99bd6180ab145aab9b7bc6c3f64e5dfefbd8da Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 12 Jul 2016 13:54:26 +0200 Subject: [PATCH 02/21] remove other.xml if was added by incorrect component roaming type --- .../src/BaseRepositoryManager.kt | 5 ++- plugins/settings-repository/src/IcsManager.kt | 35 ++++++++++--------- .../src/RepositoryManager.kt | 2 +- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/plugins/settings-repository/src/BaseRepositoryManager.kt b/plugins/settings-repository/src/BaseRepositoryManager.kt index 8d8ca968ebe0..35029871070e 100644 --- a/plugins/settings-repository/src/BaseRepositoryManager.kt +++ b/plugins/settings-repository/src/BaseRepositoryManager.kt @@ -130,7 +130,7 @@ abstract class BaseRepositoryManager(protected val dir: Path) : RepositoryManage */ protected abstract fun addToIndex(file: Path, path: String, content: ByteArray, size: Int) - override fun delete(path: String) { + override fun delete(path: String): Boolean { LOG.debug { "Remove $path"} lock.write { @@ -138,8 +138,11 @@ abstract class BaseRepositoryManager(protected val dir: Path) : RepositoryManage // delete could be called for non-existent file if (file.exists()) { delete(file, path) + return true } } + + return false } private fun delete(file: Path, path: String) { diff --git a/plugins/settings-repository/src/IcsManager.kt b/plugins/settings-repository/src/IcsManager.kt index 7e6217b1ed84..568156f900d7 100644 --- a/plugins/settings-repository/src/IcsManager.kt +++ b/plugins/settings-repository/src/IcsManager.kt @@ -242,23 +242,26 @@ class IcsApplicationLoadListener : ApplicationLoadListener { val repositoryManager = icsManager.repositoryManager if (repositoryManager.isRepositoryExists() && repositoryManager is GitRepositoryManager) { - if (repositoryManager.renameDirectory(linkedMapOf( - Pair("\$ROOT_CONFIG$", null), - Pair("_mac/\$ROOT_CONFIG$", "_mac"), - Pair("_windows/\$ROOT_CONFIG$", "_windows"), - Pair("_linux/\$ROOT_CONFIG$", "_linux"), - Pair("_freebsd/\$ROOT_CONFIG$", "_freebsd"), - Pair("_unix/\$ROOT_CONFIG$", "_unix"), - Pair("_unknown/\$ROOT_CONFIG$", "_unknown"), + val migrateSchemes = repositoryManager.renameDirectory(linkedMapOf( + Pair("\$ROOT_CONFIG$", null), + Pair("_mac/\$ROOT_CONFIG$", "_mac"), + Pair("_windows/\$ROOT_CONFIG$", "_windows"), + Pair("_linux/\$ROOT_CONFIG$", "_linux"), + Pair("_freebsd/\$ROOT_CONFIG$", "_freebsd"), + Pair("_unix/\$ROOT_CONFIG$", "_unix"), + Pair("_unknown/\$ROOT_CONFIG$", "_unknown"), - Pair("\$APP_CONFIG$", null), - Pair("_mac/\$APP_CONFIG$", "_mac"), - Pair("_windows/\$APP_CONFIG$", "_windows"), - Pair("_linux/\$APP_CONFIG$", "_linux"), - Pair("_freebsd/\$APP_CONFIG$", "_freebsd"), - Pair("_unix/\$APP_CONFIG$", "_unix"), - Pair("_unknown/\$APP_CONFIG$", "_unknown") - ))) { + Pair("\$APP_CONFIG$", null), + Pair("_mac/\$APP_CONFIG$", "_mac"), + Pair("_windows/\$APP_CONFIG$", "_windows"), + Pair("_linux/\$APP_CONFIG$", "_linux"), + Pair("_freebsd/\$APP_CONFIG$", "_freebsd"), + Pair("_unix/\$APP_CONFIG$", "_unix"), + Pair("_unknown/\$APP_CONFIG$", "_unknown") + )) + + val removeOtherXml = repositoryManager.delete("other.xml") + if (migrateSchemes || removeOtherXml) { // schedule push to avoid merge conflicts application.invokeLater({ icsManager.autoSyncManager.autoSync(force = true) }) } diff --git a/plugins/settings-repository/src/RepositoryManager.kt b/plugins/settings-repository/src/RepositoryManager.kt index 223471a6014f..c743e6ae9de1 100644 --- a/plugins/settings-repository/src/RepositoryManager.kt +++ b/plugins/settings-repository/src/RepositoryManager.kt @@ -46,7 +46,7 @@ interface RepositoryManager { */ fun write(path: String, content: ByteArray, size: Int): Boolean - fun delete(path: String) + fun delete(path: String): Boolean fun processChildren(path: String, filter: (name: String) -> Boolean, processor: (name: String, inputStream: InputStream) -> Boolean) From 9d3bc93d90f8d0bd2aebb4e8707c86c239280a77 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 12 Jul 2016 15:37:01 +0300 Subject: [PATCH 03/21] build scripts: reverted changes in 'bundledJDKs' methods to fix AppCode build (these functions aren't called from new scripts anymore) --- build/scripts/utils.gant | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 594ee94fa111..4e7deb43a979 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -876,16 +876,14 @@ binding.setVariable("signExecutableFiles", { String binDir -> }) binding.setVariable("bundledJDKs"){ - bundledJDK(false, paths.sandbox) + bundledJDK(false) } binding.setVariable("bundledJDK64s"){ - bundledJDK(true, paths.sandbox) + bundledJDK(true) } -binding.setVariable("prepareBundledJDKs", { String targetDir -> bundledJDK(false, targetDir)}) - -private bundledJDK(boolean win64, String targetDir) { +private bundledJDK(boolean win64) { requireProperty("artifact.linux.no.jdk", "true") requireProperty("artifact.mac.no.jdk", "true") requireProperty("jdk.oracle.win", "jdk8u") @@ -897,11 +895,11 @@ private bundledJDK(boolean win64, String targetDir) { def jdkDir = new File("${home}/build/jdk/win") if (p("jdk.oracle.win") != "false" && (jdkDir.exists() && jdkDir.isDirectory())) { setProperty("winJDK", getPathToBundledJDK(jdkDir, p("jdk.oracle.win"), (win64 ? "x64.tar.gz": "x86.tar.gz"))) - extractRedistJre(winJDK, "$targetDir/jdk.oracle.win/jre") + extractRedistJre(winJDK, "${paths.sandbox}/jdk.oracle.win/jre") } if (p("jdk.win") != "false" && (jdkDir.exists() && jdkDir.isDirectory())) { setProperty("winCustomJDKx32", getPathToBundledJDK(jdkDir, p("jdk.win"), (win64 ? "x64.tar.gz": "x86.tar.gz"))) - extractRedistJre(winCustomJDKx32, "$targetDir/jdk.win/jre") + extractRedistJre(winCustomJDKx32, "${paths.sandbox}/jdk.win/jre") } jdkDir = new File("${home}/build/jdk/mac") if (p("jdk.mac") != "false" && (jdkDir.exists() && jdkDir.isDirectory())) { @@ -910,7 +908,7 @@ private bundledJDK(boolean win64, String targetDir) { jdkDir = new File("${home}/build/jdk/linux") if (p("jdk.linux") != "false" && (jdkDir.exists() && jdkDir.isDirectory())) { setProperty("linuxJDK", getPathToBundledJDK(jdkDir, p("jdk.linux"), ".tar.gz")) - extractRedistJre(linuxJDK, "$targetDir/jdk.linux/jre") + extractRedistJre(linuxJDK, "${paths.sandbox}/jdk.linux/jre") } } } From 624157a42d53f1ab29c181121f712614f1055629 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Tue, 12 Jul 2016 16:02:20 +0300 Subject: [PATCH 04/21] github: fix "Checkout from GitHub" action with token without "user" scope --- .../src/org/jetbrains/plugins/github/api/GithubApiUtil.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java index 02c42d9cbb2f..cd44a84a63b1 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java @@ -26,6 +26,7 @@ import org.apache.http.message.BasicHeader; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.api.GithubConnection.PagedRequest; +import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException; import org.jetbrains.plugins.github.exceptions.GithubConfusingException; import org.jetbrains.plugins.github.exceptions.GithubJsonException; import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException; @@ -289,12 +290,12 @@ public class GithubApiUtil { try { repos.addAll(getMembershipRepos(connection)); } - catch (GithubStatusCodeException ignore) { + catch (GithubAuthenticationException | GithubStatusCodeException ignore) { } try { repos.addAll(getWatchedRepos(connection)); } - catch (GithubStatusCodeException ignore) { + catch (GithubAuthenticationException | GithubStatusCodeException ignore) { } return repos; From 191bc68923c2f7487a864b7d32676ad1b93fd4d1 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 12 Jul 2016 15:59:41 +0300 Subject: [PATCH 05/21] inspection view: comparator replace with utility builder --- .../ui/ProblemPreviewEditorPresentation.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemPreviewEditorPresentation.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemPreviewEditorPresentation.java index 62693a2c477a..fba7c51962cc 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemPreviewEditorPresentation.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/ProblemPreviewEditorPresentation.java @@ -19,7 +19,6 @@ import com.intellij.codeInspection.CommonProblemDescriptor; import com.intellij.codeInspection.ProblemDescriptorBase; import com.intellij.diff.tools.util.FoldingModelSupport; import com.intellij.diff.util.DiffDrawUtil; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.editor.ex.DocumentEx; @@ -39,19 +38,10 @@ import java.util.stream.Collectors; */ public class ProblemPreviewEditorPresentation { private final static int VIEW_ADDITIONAL_OFFSET = 4; - private final static Logger LOG = Logger.getInstance(ProblemPreviewEditorPresentation.class); private final EditorEx myEditor; private final InspectionResultsView myView; - private final SortedSet myFoldedRegions = new TreeSet<>(new Comparator() { - @Override - public int compare(PreviewEditorFoldingRegion r1, PreviewEditorFoldingRegion r2) { - if (r1 == r2) return 0; - final int diff = r1.startLine - r2.startLine; - LOG.assertTrue(diff != 0); - return diff; - } - }); + private final SortedSet myFoldedRegions = new TreeSet<>(Comparator.comparing(x -> x.startLine)); private final DocumentEx myDocument; public ProblemPreviewEditorPresentation(EditorEx editor, InspectionResultsView view) { From 8787fba3de0ccf0f29a74356baebf864afea3430 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 12 Jul 2016 16:03:21 +0300 Subject: [PATCH 06/21] inspection view: allow to invoke other suppression actions in when element is already suppressed in case of unused declaration inspection (IDEA-156821) --- .../deadCode/UnusedDeclarationPresentation.java | 10 +++++++++- .../codeInspection/ui/RefElementNode.java | 2 +- .../suppress/SuppressActionSequentialTask.java | 17 ++++++++++++----- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java index 3d80600dd0bb..9ae03ce3cef9 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java @@ -167,7 +167,15 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta @Override public QuickFixAction[] getQuickFixes(@NotNull final RefEntity[] refElements, CommonProblemDescriptor[] allowedDescriptors) { - return myQuickFixActions; + boolean showFixes = false; + for (RefEntity element : refElements) { + if (!getIgnoredRefElements().contains(element) && element.isValid()) { + showFixes = true; + break; + } + } + + return showFixes ? myQuickFixActions : QuickFixAction.EMPTY; } final QuickFixAction[] myQuickFixActions; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java index d534377431b2..68a0d15c9479 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java @@ -122,7 +122,7 @@ public class RefElementNode extends SuppressableInspectionTreeNode { @Override public int getProblemCount(boolean allowSuppressed) { - return isLeaf() ? myPresentation.getIgnoredRefElements().contains(getElement()) ? 0 : 1 : super.getProblemCount(allowSuppressed); + return isLeaf() ? myPresentation.getIgnoredRefElements().contains(getElement()) && !(allowSuppressed && isAlreadySuppressedFromView() && isValid()) ? 0 : 1 : super.getProblemCount(allowSuppressed); } @Override diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/suppress/SuppressActionSequentialTask.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/suppress/SuppressActionSequentialTask.java index 24b20e1b0289..7025422712d4 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/suppress/SuppressActionSequentialTask.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/suppress/SuppressActionSequentialTask.java @@ -21,6 +21,7 @@ import com.intellij.codeInspection.ex.InspectionManagerEx; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.codeInspection.ui.ProblemDescriptionNode; import com.intellij.codeInspection.ui.SuppressableInspectionTreeNode; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -38,6 +39,7 @@ import com.intellij.util.containers.Queue; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -137,16 +139,19 @@ public class SuppressActionSequentialTask implements SequentialTask { } final RefElement containerRef = refEntity.getRefManager().getReference(container); + final Set suppressedNodes = myContext.getView().getSuppressedNodes(wrapper.getShortName()); if (containerRef != null) { Queue toIgnoreInView = new Queue(1); toIgnoreInView.addLast(containerRef); while (!toIgnoreInView.isEmpty()) { final RefEntity entity = toIgnoreInView.pullFirst(); - final CommonProblemDescriptor[] descriptors = myContext.getPresentation(wrapper).getIgnoredElements().get(entity); - if (descriptors != null) { - for (CommonProblemDescriptor problemDescriptor : descriptors) { - myContext.getView().getSuppressedNodes(wrapper.getShortName()).add(problemDescriptor); + if (node instanceof ProblemDescriptionNode) { + final CommonProblemDescriptor[] descriptors = myContext.getPresentation(wrapper).getIgnoredElements().get(entity); + if (descriptors != null) { + Collections.addAll(suppressedNodes, descriptors); } + } else { + suppressedNodes.add(entity); } final List children = entity.getChildren(); if (children != null) { @@ -156,7 +161,9 @@ public class SuppressActionSequentialTask implements SequentialTask { } } } - myContext.getView().getSuppressedNodes(wrapper.getShortName()).add(descriptor); + if (node instanceof ProblemDescriptionNode) { + suppressedNodes.add(descriptor); + } } catch (IncorrectOperationException e1) { LOG.error(e1); From b7c079b643585f21257ef3dea70abb47c9fc3ee2 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 12 Jul 2016 16:12:44 +0300 Subject: [PATCH 07/21] IDEA-122083 Show shadow for popups optimize performance --- .../openapi/wm/impl/WindowShadowPainter.java | 62 ++++++++++++++++--- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java index 3828fcf90257..ca92ddde8c4f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java @@ -21,38 +21,80 @@ import com.intellij.util.ui.UIUtil; import javax.swing.*; import java.awt.*; +import java.awt.event.AWTEventListener; +import java.util.List; import static com.intellij.icons.AllIcons.Ide.Shadow.Popup.*; +import static com.intellij.util.containers.ContainerUtil.newArrayList; /** * @author Sergey.Malenkov */ -final class WindowShadowPainter extends AbstractPainter { +final class WindowShadowPainter extends AbstractPainter implements AWTEventListener { private static final ShadowPainter PAINTER = new ShadowPainter(Top, Top_right, Right, Bottom_right, Bottom, Bottom_left, Left, Top_left); + private static final long MASK = AWTEvent.WINDOW_EVENT_MASK | AWTEvent.WINDOW_STATE_EVENT_MASK | AWTEvent.COMPONENT_EVENT_MASK; + private List myShadows; + private Component myComponent; WindowShadowPainter() { setNeedsRepaint(true); } @Override - public void executePaint(Component component, Graphics2D g) { + public void eventDispatched(AWTEvent event) { + Component component = myComponent; + if (component == null) return; Window window = UIUtil.getWindow(component); - if (window != null) { - Point point = new Point(); - SwingUtilities.convertPointToScreen(point, component); - paintShadows(component, g, point, window.getOwnedWindows()); - setNeedsRepaint(true); + if (window == null) return; + Object source = event.getSource(); + if (source instanceof Window && SwingUtilities.isDescendingFrom((Window)source, window)) { + myShadows = getShadows(component, window); + setNeedsRepaint(myShadows != null); } } - private static void paintShadows(Component component, Graphics2D g, Point point, Window... windows) { + @Override + public void executePaint(Component component, Graphics2D g) { + Window window = UIUtil.getWindow(component); + if (window != null) { + if (myComponent != component) { + boolean add = myComponent == null; + myComponent = component; + myShadows = getShadows(component, window); + if (add) Toolkit.getDefaultToolkit().addAWTEventListener(this, MASK); + } + List shadows = myShadows; + if (shadows != null) { + for (Rectangle bounds : shadows) { + PAINTER.paintShadow(component, g, bounds.x, bounds.y, bounds.width, bounds.height); + } + setNeedsRepaint(true); + } + } + else if (myComponent != null) { + Toolkit.getDefaultToolkit().removeAWTEventListener(this); + myComponent = null; + } + } + + private static List getShadows(Component component, Window window) { + Point point = new Point(); + SwingUtilities.convertPointToScreen(point, component); + return getShadows(null, point, window.getOwnedWindows()); + } + + private static List getShadows(List list, Point point, Window... windows) { if (windows != null) { for (Window window : windows) { Rectangle bounds = getShadowBounds(point, window); - if (bounds != null) PAINTER.paintShadow(component, g, bounds.x, bounds.y, bounds.width, bounds.height); - paintShadows(component, g, point, window.getOwnedWindows()); + if (bounds != null) { + if (list == null) list = newArrayList(); + list.add(bounds); + } + list = getShadows(list, point, window.getOwnedWindows()); } } + return list; } private static Rectangle getShadowBounds(Point point, Window window) { From 30f7c339b18b35ae7972ee4a2697db062508323d Mon Sep 17 00:00:00 2001 From: "Dmitry.Krasilschikov" Date: Tue, 12 Jul 2016 16:43:57 +0300 Subject: [PATCH 08/21] #RUBY-9955 don't insert call element if it isn't needed; replace duplicates with proper let name --- .../extractMethod/ExtractMethodHelper.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHelper.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHelper.java index ccfbe6ccce4b..e2937666a4a4 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHelper.java +++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHelper.java @@ -42,6 +42,7 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.ui.ReplacePromptDialog; import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -49,7 +50,7 @@ import java.util.*; * @author Dennis.Ushakov */ public class ExtractMethodHelper { - public static void processDuplicates(@NotNull final PsiElement callElement, + public static void processDuplicates(@Nullable final PsiElement callElement, @NotNull final PsiElement generatedMethod, @NotNull final List scope, @NotNull final SimpleDuplicatesFinder finder, @@ -60,7 +61,7 @@ public class ExtractMethodHelper { replaceDuplicates(callElement, editor, replacer, finder.findDuplicates(scope, generatedMethod)); return; } - final Project project = callElement.getProject(); + final Project project = generatedMethod.getProject(); ProgressManager.getInstance().run(new Task.Backgroundable(project, RefactoringBundle.message("searching.for.duplicates"), true) { public void run(@NotNull ProgressIndicator indicator) { if (myProject == null || myProject.isDisposed()) return; @@ -115,7 +116,7 @@ public class ExtractMethodHelper { * @param duplicates discovered duplicates of extracted code fragment * @see #collectDuplicates(SimpleDuplicatesFinder, List, PsiElement) */ - public static void replaceDuplicates(@NotNull PsiElement callElement, + public static void replaceDuplicates(@Nullable PsiElement callElement, @NotNull Editor editor, @NotNull Consumer> replacer, @NotNull List duplicates) { @@ -124,7 +125,12 @@ public class ExtractMethodHelper { .message("0.has.detected.1.code.fragments.in.this.file.that.can.be.replaced.with.a.call.to.extracted.method", ApplicationNamesInfo.getInstance().getProductName(), duplicates.size()); final boolean isUnittest = ApplicationManager.getApplication().isUnitTestMode(); - final Project project = callElement.getProject(); + final Project project = callElement != null ? callElement.getProject() : editor.getProject(); + if (project == null) { + Messages.showErrorDialog(editor.getComponent(), "Cannot find project."); + return; + } + final int exitCode = !isUnittest ? Messages.showYesNoDialog(project, message, RefactoringBundle.message("refactoring.extract.method.dialog.title"), Messages.getInformationIcon()) : From 75d0f4bcf2c5d78ece3a5d306de914752a00fa4a Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 12 Jul 2016 16:50:15 +0300 Subject: [PATCH 09/21] obsolete test removed --- .../devkit/testSources/PluginProjectWizardTest.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/plugins/devkit/testSources/PluginProjectWizardTest.java b/plugins/devkit/testSources/PluginProjectWizardTest.java index 1be1b1db4f8a..98e69e0071fe 100644 --- a/plugins/devkit/testSources/PluginProjectWizardTest.java +++ b/plugins/devkit/testSources/PluginProjectWizardTest.java @@ -18,7 +18,6 @@ package org.jetbrains.idea.devkit; import com.intellij.execution.RunManager; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.configurations.ConfigurationType; -import com.intellij.ide.IdeBundle; import com.intellij.ide.projectWizard.NewProjectWizardTestCase; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; @@ -46,14 +45,4 @@ public class PluginProjectWizardTest extends NewProjectWizardTestCase { VirtualFile[] files = FileEditorManager.getInstance(project).getOpenFiles(); assertEquals(1, files.length); } - - public void testProjectWithoutSdk() throws Exception { - try { - createProjectFromTemplate(PluginModuleType.getInstance().getName(), null, null); - fail("Exception should be thrown"); - } - catch (Exception e) { - assertEquals(IdeBundle.message("prompt.confirm.project.no.jdk"), e.getMessage()); - } - } } From 95803d387238cbdc5711af9bd58f8295b32dff4b Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 12 Jul 2016 17:08:46 +0300 Subject: [PATCH 10/21] IDEA-122083 Show shadow for popups do not repaint after painting --- .../intellij/openapi/wm/impl/WindowShadowPainter.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java index ca92ddde8c4f..5a6784a55596 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowShadowPainter.java @@ -23,6 +23,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.AWTEventListener; import java.util.List; +import java.util.Objects; import static com.intellij.icons.AllIcons.Ide.Shadow.Popup.*; import static com.intellij.util.containers.ContainerUtil.newArrayList; @@ -36,8 +37,9 @@ final class WindowShadowPainter extends AbstractPainter implements AWTEventListe private List myShadows; private Component myComponent; - WindowShadowPainter() { - setNeedsRepaint(true); + @Override + public boolean needsRepaint() { + return true; } @Override @@ -48,8 +50,9 @@ final class WindowShadowPainter extends AbstractPainter implements AWTEventListe if (window == null) return; Object source = event.getSource(); if (source instanceof Window && SwingUtilities.isDescendingFrom((Window)source, window)) { + List shadows = myShadows; myShadows = getShadows(component, window); - setNeedsRepaint(myShadows != null); + if (!Objects.equals(myShadows, shadows)) component.repaint(); } } @@ -68,7 +71,6 @@ final class WindowShadowPainter extends AbstractPainter implements AWTEventListe for (Rectangle bounds : shadows) { PAINTER.paintShadow(component, g, bounds.x, bounds.y, bounds.width, bounds.height); } - setNeedsRepaint(true); } } else if (myComponent != null) { From fa9c0ebd28b2a6288ccdd46e1b8fa8fe178f0c9d Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Mon, 11 Jul 2016 21:46:54 +0300 Subject: [PATCH 11/21] PY-19220 Detect type hinting comments that follow multi-line assignments --- .../jetbrains/python/psi/impl/PyPsiUtils.java | 18 +++++++++ .../python/psi/PyFileElementType.java | 2 +- .../src/com/jetbrains/python/psi/PyUtil.java | 10 +++++ .../python/psi/impl/PyFunctionImpl.java | 6 +-- .../psi/impl/PyTargetExpressionImpl.java | 37 +++++++------------ .../com/jetbrains/python/PyTypingTest.java | 11 ++++++ 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java b/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java index 46f07970447a..0f6eff9b153b 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java +++ b/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java @@ -113,6 +113,24 @@ public class PyPsiUtils { return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class); } + /** + * Finds first non-whitespace sibling after given PSI element but stops at first whitespace containing line feed. + */ + @Nullable + public static PsiElement getNextNonWhitespaceSiblingOnSameLine(@NotNull PsiElement element) { + PsiElement cur = element.getNextSibling(); + while (cur != null) { + if (!(cur instanceof PsiWhiteSpace)) { + return cur; + } + else if (cur.textContains('\n')) { + break; + } + cur = cur.getNextSibling(); + } + return null; + } + /** * Finds first non-whitespace sibling after given AST node. */ diff --git a/python/src/com/jetbrains/python/psi/PyFileElementType.java b/python/src/com/jetbrains/python/psi/PyFileElementType.java index c89e07f22a99..3fc046be1632 100644 --- a/python/src/com/jetbrains/python/psi/PyFileElementType.java +++ b/python/src/com/jetbrains/python/psi/PyFileElementType.java @@ -62,7 +62,7 @@ public class PyFileElementType extends IStubFileElementType { @Override public int getStubVersion() { // Don't forget to update versions of indexes that use the updated stub-based elements - return 56; + return 57; } @Nullable diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index bdf133eed108..91e91d57f70e 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -890,6 +890,16 @@ public class PyUtil { } } + /** + * Returns the line comment that immediately precedes statement list of the given compound statement. Python parser ensures + * that it follows the statement header, i.e. it's directly after the colon, not on its own line. + */ + @Nullable + public static PsiComment getCommentOnHeaderLine(@NotNull PyStatementListContainer container) { + final PyStatementList statementList = container.getStatementList(); + return as(PyPsiUtils.getPrevNonWhitespaceSibling(statementList), PsiComment.class); + } + public static class KnownDecoratorProviderHolder { public static PyKnownDecoratorProvider[] KNOWN_DECORATOR_PROVIDERS = Extensions.getExtensions(PyKnownDecoratorProvider.EP_NAME); diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 0ffadde2d42c..3614bc520557 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -579,12 +579,12 @@ public class PyFunctionImpl extends PyBaseElementImpl implements @Nullable @Override public PsiComment getTypeComment() { - final PyStatementList statements = getStatementList(); - final PsiComment inlineComment = as(PyPsiUtils.getPrevNonWhitespaceSibling(statements), PsiComment.class); + final PsiComment inlineComment = PyUtil.getCommentOnHeaderLine(this); if (inlineComment != null && PyTypingTypeProvider.getTypeCommentValue(inlineComment.getText()) != null) { return inlineComment; } - + + final PyStatementList statements = getStatementList(); if (statements.getStatements().length != 0) { final PsiComment comment = as(statements.getFirstChild(), PsiComment.class); if (comment != null && PyTypingTypeProvider.getTypeCommentValue(comment.getText()) != null) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java index 31c8f4711f32..28fc40cc833e 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java @@ -62,6 +62,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import static com.jetbrains.python.psi.PyUtil.as; + /** * @author yole */ @@ -682,34 +684,21 @@ public class PyTargetExpressionImpl extends PyBaseElementImpl Date: Tue, 12 Jul 2016 17:47:37 +0300 Subject: [PATCH 12/21] Java inspection: Removed the "Add Braces" intention, because it can be replaced with "Control flow statement without braces" inspection (IDEA-157727) --- .../src/META-INF/IntentionPowerPack.xml | 5 -- .../siyeh/IntentionPowerPackBundle.properties | 2 - .../siyeh/ipp/braces/AddBracesIntention.java | 51 ------------------- .../AddBracesIntention/after.java.template | 8 --- .../AddBracesIntention/before.java.template | 6 --- .../AddBracesIntention/description.html | 6 --- 6 files changed, 78 deletions(-) delete mode 100644 plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddBracesIntention.java delete mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/after.java.template delete mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/before.java.template delete mode 100644 plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/description.html diff --git a/plugins/IntentionPowerPak/src/META-INF/IntentionPowerPack.xml b/plugins/IntentionPowerPak/src/META-INF/IntentionPowerPack.xml index f53563be74fe..9ed5d7fa3a5d 100644 --- a/plugins/IntentionPowerPak/src/META-INF/IntentionPowerPack.xml +++ b/plugins/IntentionPowerPak/src/META-INF/IntentionPowerPack.xml @@ -351,11 +351,6 @@ com.siyeh.IntentionPowerPackBundle intention.category.control.flow - - com.siyeh.ipp.braces.AddBracesIntention - com.siyeh.IntentionPowerPackBundle - intention.category.control.flow - com.siyeh.ipp.braces.RemoveBracesIntention com.siyeh.IntentionPowerPackBundle diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 17284cd00e7f..30b6f9c3a113 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -90,7 +90,6 @@ flip.comparison.intention.family.name=Flip Comparison flip.conjunction.intention.family.name=Flip Conjunction Operands negate.comparison.intention.family.name=Negate Comparison remove.braces.intention.family.name=Remove Braces -add.braces.intention.family.name=Add Braces flip.commutative.method.call.intention.family.name=Flip Commutative Method Call constant.subexpression.intention.family.name=Compute Constant Value for Subexpression extract.increment.intention.family.name=Extract Increment @@ -172,7 +171,6 @@ flip.smth.intention.name1=Flip ''{0}'' (changes semantics) flip.comparison.intention.name=Flip ''{0}'' to ''{1}'' negate.comparison.intention.name=Negate ''{0}'' negate.comparison.intention.name1=Negate ''{0}'' to ''{1}'' -add.braces.intention.name=Add braces to ''{0}'' statement remove.braces.intention.name=Remove braces from ''{0}'' statement flip.commutative.method.call.intention.name=Flip ''.{0}()'' flip.commutative.method.call.intention.name1=Flip ''.{0}()'' (may change semantics) diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddBracesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddBracesIntention.java deleted file mode 100644 index f51759f6a171..000000000000 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/AddBracesIntention.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2003-2006 Dave Griffith, Bas Leijdekkers - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.siyeh.ipp.braces; - -import com.intellij.psi.*; -import com.intellij.util.IncorrectOperationException; -import com.siyeh.ig.PsiReplacementUtil; -import com.siyeh.ipp.base.PsiElementPredicate; -import org.jetbrains.annotations.NotNull; - -public class AddBracesIntention extends BaseBracesIntention { - - @NotNull - protected PsiElementPredicate getElementPredicate() { - return new PsiElementPredicate() { - @Override - public boolean satisfiedBy(PsiElement element) { - final PsiStatement statement = getSurroundingStatement(element); - return statement != null && !(statement instanceof PsiBlockStatement); - } - }; - } - - @NotNull - @Override - protected String getMessageKey() { - return "add.braces.intention.name"; - } - - protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { - final PsiStatement statement = getSurroundingStatement(element); - if (statement == null) { - return; - } - final String newStatement = "{\n" + statement.getText() + "\n}"; - PsiReplacementUtil.replaceStatement(statement, newStatement); - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/after.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/after.java.template deleted file mode 100644 index 7777953c60cc..000000000000 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/after.java.template +++ /dev/null @@ -1,8 +0,0 @@ -public class X { - int f(boolean b) { - if (b) { - return 1; - } - return 0; - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/before.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/before.java.template deleted file mode 100644 index d45dc00808ae..000000000000 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/before.java.template +++ /dev/null @@ -1,6 +0,0 @@ -public class X { - int f(boolean b) { - if (b) return 1; - return 0; - } -} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/description.html deleted file mode 100644 index fb832c3844f6..000000000000 --- a/plugins/IntentionPowerPak/src/intentionDescriptions/AddBracesIntention/description.html +++ /dev/null @@ -1,6 +0,0 @@ - - -This intention adds braces to control flow statements without -braces. - - From 0cc8cec43445c64e7c6e9576989cdd54793ef20e Mon Sep 17 00:00:00 2001 From: Pavel Dolgov Date: Tue, 12 Jul 2016 17:50:46 +0300 Subject: [PATCH 13/21] Java inspection: Enabled by default the "Control flow statement without braces" inspection at INFORMATION level. Tests added. (IDEA-157727) --- .../src/META-INF/InspectionGadgets.xml | 2 +- .../siyeh/InspectionGadgetsBundle.properties | 3 +- .../com/siyeh/ig/BaseInspectionVisitor.java | 30 ++++-- ...lFlowStatementWithoutBracesInspection.java | 102 ++++++++++++++---- .../DoBody.after.java | 9 ++ .../statement_without_braces/DoBody.java | 7 ++ .../DoExpression.after.java | 9 ++ .../DoExpression.java | 7 ++ .../DoMiddle.after.java | 9 ++ .../statement_without_braces/DoMiddle.java | 7 ++ .../ForEachBody.after.java | 7 ++ .../statement_without_braces/ForEachBody.java | 6 ++ .../ForEachExpression.after.java | 7 ++ .../ForEachExpression.java | 6 ++ .../ForEachKeyword.after.java | 7 ++ .../ForEachKeyword.java | 6 ++ .../ForIndex.after.java | 7 ++ .../statement_without_braces/ForIndex.java | 6 ++ .../FullIfBody.after.java | 8 ++ .../statement_without_braces/FullIfBody.java | 8 ++ .../FullIfElseBody.after.java | 9 ++ .../FullIfElseBody.java | 8 ++ .../FullIfElseKeyword.after.java | 9 ++ .../FullIfElseKeyword.java | 8 ++ .../FullIfKeyword.after.java | 8 ++ .../FullIfKeyword.java | 8 ++ .../FullIfMiddle.java | 8 ++ .../SimpleIfBody.after.java | 7 ++ .../SimpleIfBody.java | 6 ++ .../SimpleIfExpression.after.java | 7 ++ .../SimpleIfExpression.java | 6 ++ .../SimpleIfKeyword.after.java | 7 ++ .../SimpleIfKeyword.java | 6 ++ .../statement_without_braces/While.after.java | 8 ++ .../statement_without_braces/While.java | 7 ++ .../WhileOutside.java | 7 ++ .../ControlFlowStatements.java | 29 +++++ .../statements_without_braces/expected.xml | 60 +++++++++++ .../com/siyeh/ig/IGQuickFixesTestCase.java | 3 +- ...trolFlowStatementWithoutBracesFixTest.java | 75 +++++++++++++ ...wStatementWithoutBracesInspectionTest.java | 27 +++++ 41 files changed, 536 insertions(+), 30 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfMiddle.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.after.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/WhileOutside.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/ControlFlowStatements.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/expected.xml create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/ControlFlowStatementWithoutBracesFixTest.java create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspectionTest.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml index 60a07b4452ab..e319cbf64794 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml @@ -2385,7 +2385,7 @@ level="WARNING" implementationClass="com.siyeh.ig.style.ConstantOnRHSOfComparisonInspection"/> #ref is too br return.this.problem.descriptor=Return of #ref #loc constant.on.lhs.of.comparison.problem.descriptor=#ref: constant on left side of comparison #loc constant.on.rhs.of.comparison.problem.descriptor=#ref: constant on right side of comparison #loc -control.flow.statement.without.braces.problem.descriptor=#ref without braces #loc +control.flow.statement.without.braces.problem.descriptor={0} without braces #loc missorted.modifiers.problem.descriptor=Missorted modifiers #ref #loc cstyle.array.variable.declaration.problem.descriptor=C-style array declaration of {0, choice, 1#field|2#parameter|3#local variable} #ref #loc cstyle.array.method.declaration.problem.descriptor=C-style array declaration of the return type of method #ref()#loc @@ -1335,6 +1335,7 @@ introduce.variable.quickfix=Introduce variable introduce.variable.may.change.semantics.quickfix=Introduce variable (may change semantics) flip.comparison.quickfix=Flip comparison control.flow.statement.without.braces.add.quickfix=Add braces +control.flow.statement.without.braces.message=Add braces to ''{0}'' statement extends.object.remove.quickfix=Remove redundant 'extends Object' implicit.call.to.super.ignore.option=Ignore for direct subclasses of 'java.lang.Object' implicit.call.to.super.make.explicit.quickfix=Make call to 'super()' explicit diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java index 06c90eacee02..4d4d8aae6fbf 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/BaseInspectionVisitor.java @@ -15,6 +15,8 @@ */ package com.siyeh.ig; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.codeInspection.ProblemsHolder; import com.intellij.openapi.util.TextRange; @@ -183,10 +185,7 @@ public abstract class BaseInspectionVisitor extends JavaElementVisitor { if (!location.isPhysical() || location.getTextLength() == 0 && !(location instanceof PsiFile)) { return; } - final InspectionGadgetsFix[] fixes = createFixes(infos); - for (InspectionGadgetsFix fix : fixes) { - fix.setOnTheFly(onTheFly); - } + final LocalQuickFix[] fixes = createAndInitFixes(infos); final String description = inspection.buildErrorString(infos); holder.registerProblem(location, description, highlightType, fixes); } @@ -201,13 +200,30 @@ public abstract class BaseInspectionVisitor extends JavaElementVisitor { if (location.getTextLength() == 0 || length == 0) { return; } + final LocalQuickFix[] fixes = createAndInitFixes(infos); + final String description = inspection.buildErrorString(infos); + final TextRange range = new TextRange(offset, offset + length); + holder.registerProblem(location, description, highlightType, range, fixes); + } + + protected final void registerErrorAtRange(@NotNull PsiElement startLocation, @NotNull PsiElement endLocation, Object... infos) { + if (startLocation.getTextLength() == 0 && startLocation == endLocation) { + return; + } + final LocalQuickFix[] fixes = createAndInitFixes(infos); + final String description = inspection.buildErrorString(infos); + final ProblemDescriptor problemDescriptor = holder.getManager() + .createProblemDescriptor(startLocation, endLocation, description, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, onTheFly, fixes); + holder.registerProblem(problemDescriptor); + } + + @NotNull + private LocalQuickFix[] createAndInitFixes(Object[] infos) { final InspectionGadgetsFix[] fixes = createFixes(infos); for (InspectionGadgetsFix fix : fixes) { fix.setOnTheFly(onTheFly); } - final String description = inspection.buildErrorString(infos); - final TextRange range = new TextRange(offset, offset + length); - holder.registerProblem(location, description, highlightType, range, fixes); + return fixes; } @NotNull diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java index 78804d9e766d..33aa3659e804 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java @@ -15,8 +15,12 @@ */ package com.siyeh.ig.style; +import com.intellij.codeHighlighting.HighlightDisplayLevel; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInspection.InspectionProfile; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; @@ -24,12 +28,17 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.PsiReplacementUtil; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; public class ControlFlowStatementWithoutBracesInspection extends BaseInspection { + private static final String DO_TEXT = "do"; + private static final String ELSE_TEXT = "else"; + private static final String FOR_TEXT = "for"; + private static final String IF_TEXT = "if"; + private static final String WHILE_TEXT = "while"; + @Override @NotNull public String getDisplayName() { @@ -41,38 +50,49 @@ public class ControlFlowStatementWithoutBracesInspection @NotNull protected String buildErrorString(Object... infos) { return InspectionGadgetsBundle.message( - "control.flow.statement.without.braces.problem.descriptor"); + "control.flow.statement.without.braces.problem.descriptor", infos); } @Override public InspectionGadgetsFix buildFix(Object... infos) { - return new ControlFlowStatementFix(); + return new ControlFlowStatementFix(infos); } private static class ControlFlowStatementFix extends InspectionGadgetsFix { + private final Object[] myInfos; + + public ControlFlowStatementFix(Object[] infos) { + myInfos = infos; + } @Override @NotNull public String getName() { return InspectionGadgetsBundle.message( - "control.flow.statement.without.braces.add.quickfix"); + "control.flow.statement.without.braces.message", myInfos); } @Override @NotNull public String getFamilyName() { - return getName(); + return InspectionGadgetsBundle.message( + "control.flow.statement.without.braces.add.quickfix"); } @Override protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { - final PsiElement element = descriptor.getPsiElement(); + final PsiElement element = descriptor.getStartElement(); final PsiElement parent = element.getParent(); - if (!(parent instanceof PsiStatement)) { + final PsiStatement statement; + if (element instanceof PsiStatement) { + statement = (PsiStatement)element; + } + else if ((parent instanceof PsiStatement)) { + statement = (PsiStatement)parent; + } + else { return; } - final PsiStatement statement = (PsiStatement)parent; - @NonNls final String elementText = element.getText(); final PsiStatement statementWithoutBraces; if (statement instanceof PsiLoopStatement) { final PsiLoopStatement loopStatement = @@ -81,7 +101,10 @@ public class ControlFlowStatementWithoutBracesInspection } else if (statement instanceof PsiIfStatement) { final PsiIfStatement ifStatement = (PsiIfStatement)statement; - if ("if".equals(elementText)) { + if (element == ifStatement.getElseElement()) { + statementWithoutBraces = ifStatement.getElseBranch(); + } + else { statementWithoutBraces = ifStatement.getThenBranch(); if (statementWithoutBraces == null) { return; @@ -93,9 +116,6 @@ public class ControlFlowStatementWithoutBracesInspection nextSibling.delete(); } } - else { - statementWithoutBraces = ifStatement.getElseBranch(); - } } else { return; @@ -111,11 +131,18 @@ public class ControlFlowStatementWithoutBracesInspection @Override public BaseInspectionVisitor buildVisitor() { - return new ControlFlowStatementVisitor(); + final String shortName = getShortName(); + final HighlightDisplayKey key = HighlightDisplayKey.find(shortName); + return new ControlFlowStatementVisitor(key); } private static class ControlFlowStatementVisitor extends BaseInspectionVisitor { + private HighlightDisplayKey myKey; + + public ControlFlowStatementVisitor(HighlightDisplayKey key) { + myKey = key; + } @Override public void visitDoWhileStatement(PsiDoWhileStatement statement) { @@ -124,7 +151,7 @@ public class ControlFlowStatementWithoutBracesInspection if (body == null || body instanceof PsiBlockStatement) { return; } - registerStatementError(statement); + registerKeywordOrStatementError(statement, DO_TEXT); } @Override @@ -134,7 +161,7 @@ public class ControlFlowStatementWithoutBracesInspection if (body == null || body instanceof PsiBlockStatement) { return; } - registerStatementError(statement); + registerKeywordOrStatementError(statement, FOR_TEXT); } @Override @@ -144,7 +171,7 @@ public class ControlFlowStatementWithoutBracesInspection if (body == null || body instanceof PsiBlockStatement) { return; } - registerStatementError(statement); + registerKeywordOrStatementError(statement, FOR_TEXT); } @Override @@ -154,8 +181,15 @@ public class ControlFlowStatementWithoutBracesInspection if (thenBranch == null) { return; } + boolean highlightOnlyKeyword = isHighlightOnlyKeyword(statement); if (!(thenBranch instanceof PsiBlockStatement)) { - registerStatementError(statement); + if (highlightOnlyKeyword) { + registerStatementError(statement, IF_TEXT); + } + else { + final PsiElement startElement = statement.getFirstChild(); + registerErrorAtRange(startElement != null ? startElement : thenBranch, thenBranch, IF_TEXT); + } } final PsiStatement elseBranch = statement.getElseBranch(); if (elseBranch == null) { @@ -167,7 +201,12 @@ public class ControlFlowStatementWithoutBracesInspection if (elseKeyword == null) { return; } - registerError(elseKeyword); + if (highlightOnlyKeyword) { + registerError(elseKeyword, ELSE_TEXT); + } + else { + registerErrorAtRange(elseKeyword, elseBranch, ELSE_TEXT); + } } } @@ -178,7 +217,30 @@ public class ControlFlowStatementWithoutBracesInspection if (body == null || body instanceof PsiBlockStatement) { return; } - registerStatementError(statement); + registerKeywordOrStatementError(statement, WHILE_TEXT); + } + + private void registerKeywordOrStatementError(PsiStatement statement, String text) { + boolean highlightOnlyKeyword = isHighlightOnlyKeyword(statement); + if (highlightOnlyKeyword) { + registerStatementError(statement, text); + } + else { + registerError(statement, text); + } + } + + private boolean isHighlightOnlyKeyword(PsiElement element) { + if (!isOnTheFly()) { + return true; + } + if (myKey != null) { + final Project project = element.getProject(); + final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); + HighlightDisplayLevel errorLevel = profile.getErrorLevel(myKey, element); + return !HighlightDisplayLevel.DO_NOT_SHOW.equals(errorLevel); + } + return false; } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.after.java new file mode 100644 index 000000000000..f6a1323f4e5f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + int j = 0; + do { + System.out.println(a[j++]); + } + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.java new file mode 100644 index 000000000000..d06d1f35f337 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoBody.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int j = 0; + do System.out.println(a[j++]); + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.after.java new file mode 100644 index 000000000000..f6a1323f4e5f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + int j = 0; + do { + System.out.println(a[j++]); + } + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.java new file mode 100644 index 000000000000..eaedfb956318 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoExpression.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int j = 0; + do System.out.println(a[j++]); + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.after.java new file mode 100644 index 000000000000..f6a1323f4e5f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + int j = 0; + do { + System.out.println(a[j++]); + } + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.java new file mode 100644 index 000000000000..ae9eeaa86d2c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/DoMiddle.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int j = 0; + do System.out.println(a[j++]); + while (j < a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.after.java new file mode 100644 index 000000000000..f3fc6d139b34 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + for (String s : a) { + System.out.println(s); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.java new file mode 100644 index 000000000000..00b8c9f34831 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachBody.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + for (String s : a) + System.out.println(s); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.after.java new file mode 100644 index 000000000000..f3fc6d139b34 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + for (String s : a) { + System.out.println(s); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.java new file mode 100644 index 000000000000..c0aa6b8c763a --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachExpression.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + for (String s : a) + System.out.println(s); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.after.java new file mode 100644 index 000000000000..f3fc6d139b34 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + for (String s : a) { + System.out.println(s); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.java new file mode 100644 index 000000000000..c10dc13fc45a --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForEachKeyword.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + for (String s : a) + System.out.println(s); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.after.java new file mode 100644 index 000000000000..67ba7f8d5b20 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + for (int i = 0; i < a.length; i++) { + System.out.println(a[i]); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.java new file mode 100644 index 000000000000..7e6eb6a3c5c0 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/ForIndex.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + for (int i = 0; i < a.length; i++) + System.out.println(a[i]); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.after.java new file mode 100644 index 000000000000..3ac6e8522f60 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.after.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.java new file mode 100644 index 000000000000..e6167755562d --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfBody.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.after.java new file mode 100644 index 000000000000..0ce38894f421 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else { + System.out.println(a.length); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.java new file mode 100644 index 000000000000..3679e2b894a4 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseBody.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.after.java new file mode 100644 index 000000000000..0ce38894f421 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.after.java @@ -0,0 +1,9 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else { + System.out.println(a.length); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.java new file mode 100644 index 000000000000..c8affc66625c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfElseKeyword.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.after.java new file mode 100644 index 000000000000..3ac6e8522f60 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.after.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.java new file mode 100644 index 000000000000..dfbe50f8feb3 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfKeyword.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfMiddle.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfMiddle.java new file mode 100644 index 000000000000..d01a75370a53 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/FullIfMiddle.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.after.java new file mode 100644 index 000000000000..36d1699c71e6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.java new file mode 100644 index 000000000000..5b5c4961efad --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfBody.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.after.java new file mode 100644 index 000000000000..36d1699c71e6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.java new file mode 100644 index 000000000000..e1eb7631230a --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfExpression.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.after.java new file mode 100644 index 000000000000..36d1699c71e6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.after.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + if (a.length == 0) { + System.out.println("no"); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.java new file mode 100644 index 000000000000..111f51f1b28c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/SimpleIfKeyword.java @@ -0,0 +1,6 @@ +class T { + void f(String[] a) { + if (a.length == 0) + System.out.println("no"); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.after.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.after.java new file mode 100644 index 000000000000..6ca70967cdcf --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.after.java @@ -0,0 +1,8 @@ +class T { + void f(String[] a) { + int k = 0; + while (k < a.length) { + System.out.println(a[k++]); + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.java new file mode 100644 index 000000000000..70519665401c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/While.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int k = 0; + while (k < a.length) + System.out.println(a[k++]); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/WhileOutside.java b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/WhileOutside.java new file mode 100644 index 000000000000..0e098b101df4 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igfixes/statement_without_braces/WhileOutside.java @@ -0,0 +1,7 @@ +class T { + void f(String[] a) { + int k = 0; + while (k < a.length) + System.out.println(a[k++]); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/ControlFlowStatements.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/ControlFlowStatements.java new file mode 100644 index 000000000000..5b6f9a1da573 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/ControlFlowStatements.java @@ -0,0 +1,29 @@ +class T { + void f(String[] a) { + for (String s : a) + System.out.println(s); + + if (a.length == 0) + System.out.println("no"); + else + System.out.println(a.length); + + for (int i = 0; i < a.length; i++) + System.out.println(a[i]); + + int j = 0; + do System.out.println(a[j++]); + while (j < a.length); + + int k = 0; + while (k < a.length) + System.out.println(a[k++]); + + if (a.length == 0) + System.out.println("no"); + + if (a.length == 0) { + } else + System.out.println(a.length); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/expected.xml new file mode 100644 index 000000000000..e5869a1c602e --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/statements_without_braces/expected.xml @@ -0,0 +1,60 @@ + + + + + ControlFlowStatements.java + 3 + Control flow statement without braces + <code>for</code> without braces #loc + + + + ControlFlowStatements.java + 6 + Control flow statement without braces + <code>if</code> without braces #loc + + + + ControlFlowStatements.java + 8 + Control flow statement without braces + <code>else</code> without braces #loc + + + + ControlFlowStatements.java + 11 + Control flow statement without braces + <code>for</code> without braces #loc + + + + ControlFlowStatements.java + 15 + Control flow statement without braces + <code>do</code> without braces #loc + + + + ControlFlowStatements.java + 19 + Control flow statement without braces + <code>while</code> without braces #loc + + + + ControlFlowStatements.java + 22 + Control flow statement without braces + <code>if</code> without braces #loc + + + + ControlFlowStatements.java + 26 + Control flow statement without braces + <code>else</code> without braces #loc + + + \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java index b281d4bfe380..f184c962d5ac 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/IGQuickFixesTestCase.java @@ -116,8 +116,9 @@ public abstract class IGQuickFixesTestCase extends JavaCodeInsightFixtureTestCas } public IntentionAction findIntention(@NotNull final String hint) { + final List allIntentions = myFixture.getAvailableIntentions(); final List intentions = - ContainerUtil.findAll(myFixture.getAvailableIntentions(), + ContainerUtil.findAll(allIntentions, intentionAction -> intentionAction instanceof QuickFixWrapper && intentionAction.getText().equals(hint)); Assert.assertFalse("\"" + hint + "\" not in " + intentions, intentions.isEmpty()); diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/ControlFlowStatementWithoutBracesFixTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/ControlFlowStatementWithoutBracesFixTest.java new file mode 100644 index 000000000000..2d1f76a267fc --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/fixes/braces/ControlFlowStatementWithoutBracesFixTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.fixes.braces; + +import com.siyeh.InspectionGadgetsBundle; +import com.siyeh.ig.BaseInspection; +import com.siyeh.ig.IGQuickFixesTestCase; +import com.siyeh.ig.style.ControlFlowStatementWithoutBracesInspection; + +/** + * @author Pavel.Dolgov + */ +public class ControlFlowStatementWithoutBracesFixTest extends IGQuickFixesTestCase { + + public void testSimpleIfBody() { doTest("if"); } + public void testSimpleIfExpression() { doTest("if"); } + public void testSimpleIfKeyword() { doTest("if"); } + + public void testFullIfBody() { doTest("if"); } + public void testFullIfKeyword() { doTest("if"); } + public void testFullIfElseBody() { doTest("else"); } + public void testFullIfElseKeyword() { doTest("else"); } + public void testFullIfMiddle() { assertQuickfixNotAvailable(getMessagePrefix()); } + + public void testDoBody() { doTest("do"); } + public void testDoExpression() { doTest("do"); } + public void testDoMiddle() { doTest("do"); } + + public void testForEachBody() { doTest("for"); } + public void testForEachExpression() { doTest("for"); } + public void testForEachKeyword() { doTest("for"); } + public void testForIndex() { doTest("for"); } + + public void testWhile() { doTest("while"); } + public void testWhileOutside() { assertQuickfixNotAvailable(getMessagePrefix()); } + + @Override + protected void setUp() throws Exception { + super.setUp(); + myRelativePath = "statement_without_braces"; + } + + @Override + protected BaseInspection getInspection() { + return new ControlFlowStatementWithoutBracesInspection(); + } + + protected void doTest(String keyword) { + super.doTest(getMessage(keyword)); + } + + private static String getMessage(String keyword) { + return InspectionGadgetsBundle.message("control.flow.statement.without.braces.message", keyword); + } + + private static String getMessagePrefix() { + final String message = InspectionGadgetsBundle.message("control.flow.statement.without.braces.message", "@"); + final int index = message.indexOf("@"); + if (index >= 0) return message.substring(0, index); + return message; + } +} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspectionTest.java new file mode 100644 index 000000000000..d7ac2b40792e --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspectionTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.style; + +import com.siyeh.ig.IGInspectionTestCase; + +/** + * @author Pavel.Dolgov + */ +public class ControlFlowStatementWithoutBracesInspectionTest extends IGInspectionTestCase { + public void test() { + doTest("com/siyeh/igtest/style/statements_without_braces", new ControlFlowStatementWithoutBracesInspection()); + } +} From 4254a9b50caa398e58c97aa31942d2fb087e577f Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 12 Jul 2016 18:12:31 +0300 Subject: [PATCH 14/21] build scripts: javadocs --- .../build/LinuxDistributionCustomizer.groovy | 4 ++++ .../intellij/build/MacDistributionCustomizer.groovy | 12 ++++++++++++ .../intellij/build/ProductProperties.groovy | 4 ++++ .../build/WindowsDistributionCustomizer.groovy | 5 +++++ 4 files changed, 25 insertions(+) diff --git a/build/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy b/build/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy index 37dcd5fc0c81..c8fdb2b44a56 100644 --- a/build/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy +++ b/build/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy @@ -34,5 +34,9 @@ abstract class LinuxDistributionCustomizer { */ abstract String rootDirectoryName(String buildNumber) + /** + * Override this method to copy additional files to Linux distribution of the product. + * @param targetDirectory contents of this directory will be packed into .tar.gz archive under {@link #rootDirectoryName(java.lang.String)} + */ void copyAdditionalFiles(BuildContext context, String targetDirectory) {} } diff --git a/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy b/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy index 92af4d0350e5..fea25a526f62 100644 --- a/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy +++ b/build/groovy/org/jetbrains/intellij/build/MacDistributionCustomizer.groovy @@ -19,12 +19,24 @@ package org.jetbrains.intellij.build * @author nik */ abstract class MacDistributionCustomizer { + /** + * Path to icns file containing 32x32 product icon for Mac OS distribution + */ String icnsPath + + /** + * The minimum version of Mac OS where the product is allowed to be installed + */ String minOSXVersion = "10.8" String helpId = "" String docTypes = null List urlSchemes = [] List architectures = ["x86_64"] + + /** + * If {@code true} YourKit agent will be automatically attached when an EAP build of the product starts under Mac OS. This property is + * taken into account only if {@link ProductProperties#enableYourkitAgentInEAP} is {@code true}. + */ boolean enableYourkitAgentInEAP = true /** diff --git a/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy b/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy index f0ce127c24b2..a15fb138f608 100644 --- a/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/ProductProperties.groovy @@ -106,6 +106,10 @@ public abstract class ProductProperties { * directories of Windows, Linux and Mac OS distributions. If {@code null} no agent files will be bundled. */ String yourkitAgentBinariesDirectoryPath = null + + /** + * If {@code true} YourKit agent will be automatically attached when an EAP build of the product starts. It makes sense only if {@link #yourkitAgentBinariesDirectoryPath} is non-null. + */ boolean enableYourkitAgentInEAP = false List excludedPlugins = [] diff --git a/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy b/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy index c814d2d2601d..ef315aaa7dfa 100644 --- a/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy +++ b/build/groovy/org/jetbrains/intellij/build/WindowsDistributionCustomizer.groovy @@ -54,6 +54,11 @@ abstract class WindowsDistributionCustomizer { */ abstract String rootDirectoryName(String buildNumber) + /** + * Override this method to copy additional files to Windows distribution of the product. + * @param targetDirectory contents of this directory will be packed into zip archive and exe installer, so when the product is installed + * it'll be placed under its root directory. + */ void copyAdditionalFiles(BuildContext context, String targetDirectory) {} String uninstallFeedbackPageUrl(ApplicationInfoProperties applicationInfo) { From 4d7bc4561aa31f4bb19324038f56ed1c0f091d0a Mon Sep 17 00:00:00 2001 From: Pavel Dolgov Date: Tue, 12 Jul 2016 18:47:27 +0300 Subject: [PATCH 15/21] Java inspection: In "Control flow statement without braces" inspection make sure the PSI data isn't held by the quick fix. (IDEA-157727) --- ...ControlFlowStatementWithoutBracesInspection.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java index 33aa3659e804..c450f7f96ee7 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/style/ControlFlowStatementWithoutBracesInspection.java @@ -55,21 +55,24 @@ public class ControlFlowStatementWithoutBracesInspection @Override public InspectionGadgetsFix buildFix(Object... infos) { - return new ControlFlowStatementFix(infos); + if (infos.length == 1 && infos[0] instanceof String) { + return new ControlFlowStatementFix((String)infos[0]); + } + return null; } private static class ControlFlowStatementFix extends InspectionGadgetsFix { - private final Object[] myInfos; + private final String myKeywordText; - public ControlFlowStatementFix(Object[] infos) { - myInfos = infos; + public ControlFlowStatementFix(String keywordText) { + myKeywordText = keywordText; } @Override @NotNull public String getName() { return InspectionGadgetsBundle.message( - "control.flow.statement.without.braces.message", myInfos); + "control.flow.statement.without.braces.message", myKeywordText); } @Override @NotNull From 316af6285d4b1351dd7ac6e92c65ef9d2f88b57d Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 12 Jul 2016 17:23:42 +0200 Subject: [PATCH 16/21] avoid strong reference to Splash after loading finished --- .../com/intellij/openapi/application/impl/ApplicationImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 7d53a913907b..8c5255d63f3b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -112,7 +112,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private int myInEditorPaintCounter; // EDT only private final long myStartTime; @Nullable - private final Splash mySplash; + private Splash mySplash; private boolean myDoNotSave; private volatile boolean myDisposeInProgress; @@ -420,6 +420,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App token.finish(); } myLoaded = true; + mySplash = null; createLocatorFile(); } From 06ed3f5f2a418071bfceb3b03cb7a1c7095ffe0f Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 12 Jul 2016 02:12:28 +0300 Subject: [PATCH 17/21] index scratch roots --- .../ide/scratch/ScratchFileServiceImpl.java | 27 ++++++++++++++++--- .../src/META-INF/LangExtensions.xml | 1 + 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java index 8f990bcc2237..b75266ac7d20 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java @@ -52,6 +52,7 @@ import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.PairConsumer; import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.indexing.IndexableSetContributor; import com.intellij.util.messages.MessageBus; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -59,9 +60,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.IOException; -import java.util.Collection; -import java.util.List; -import java.util.Set; +import java.util.*; @State(name = "ScratchFileService", storages = @Storage("scratches.xml")) @@ -314,4 +313,26 @@ public class ScratchFileServiceImpl extends ScratchFileService implements Persis private static Language getLanguageByFileName(@Nullable VirtualFile file) { return file == null ? null : LanguageUtil.getFileTypeLanguage(FileTypeManager.getInstance().getFileTypeByFileName(file.getName())); } + + public static class IndexSetContributor extends IndexableSetContributor { + + @NotNull + @Override + public Set getAdditionalRootsToIndex() { + ScratchFileService instance = ScratchFileService.getInstance(); + LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + HashSet result = ContainerUtil.newHashSet(); + for (RootType rootType : RootType.getAllRootIds()) { + if (rootType.isHidden()) continue; + ContainerUtil.addIfNotNull(result, fileSystem.findFileByPath(instance.getRootPath(rootType))); + } + return result; + } + + @NotNull + @Override + public Set getAdditionalProjectRootsToIndex(@NotNull Project project) { + return Collections.emptySet(); + } + } } \ No newline at end of file diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index f292a189d63d..5a3e3d9b91a4 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -359,6 +359,7 @@ + From 9acb0afe8e8087c35e4db8f16ed3f92729db81b2 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 12 Jul 2016 20:02:01 +0300 Subject: [PATCH 18/21] extract hasInvalidFiles() to VfsUtil --- .../src/com/intellij/openapi/vfs/VfsUtilCore.java | 9 +++++++++ .../util/indexing/AdditionalIndexableFileSet.java | 11 +---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java index ebe812819b61..2868e00897b8 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java @@ -663,6 +663,15 @@ public class VfsUtilCore { return components; } + public static boolean hasInvalidFiles(@NotNull Iterable files) { + for (VirtualFile file : files) { + if (!file.isValid()) { + return true; + } + } + return false; + } + /** * this collection will keep only distinct files/folders, e.g. C:\foo\bar will be removed when C:\foo is added */ diff --git a/platform/indexing-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java b/platform/indexing-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java index f08d23cf143e..e2adf3250ced 100644 --- a/platform/indexing-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java +++ b/platform/indexing-impl/src/com/intellij/util/indexing/AdditionalIndexableFileSet.java @@ -55,7 +55,7 @@ public class AdditionalIndexableFileSet implements IndexableFileSet { private Set getDirectories() { Set directories = cachedDirectories; - if (directories == null || filesInvalidated(directories) || filesInvalidated(cachedFiles)) { + if (directories == null || VfsUtilCore.hasInvalidFiles(directories) || VfsUtilCore.hasInvalidFiles(cachedFiles)) { directories = collectFilesAndDirectories(); } return directories; @@ -83,15 +83,6 @@ public class AdditionalIndexableFileSet implements IndexableFileSet { return directories; } - public static boolean filesInvalidated(Set files) { - for (VirtualFile file : files) { - if (!file.isValid()) { - return true; - } - } - return false; - } - @Override public boolean isInSet(@NotNull VirtualFile file) { return VfsUtilCore.isUnder(file, getDirectories()) || cachedFiles.contains(file); From c93a65d85f02e86674e0be9081a387712e8bcc00 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 12 Jul 2016 20:25:50 +0300 Subject: [PATCH 19/21] extract LightDirectoryIndex --- .../ide/scratch/ScratchFileServiceImpl.java | 27 +++++--------- .../indexing}/LightDirectoryIndex.java | 37 ++++++++++++------- 2 files changed, 33 insertions(+), 31 deletions(-) rename platform/lang-impl/src/com/intellij/{ide/scratch => util/indexing}/LightDirectoryIndex.java (75%) diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java index b75266ac7d20..68ca22e30bca 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchFileServiceImpl.java @@ -22,6 +22,7 @@ import com.intellij.lang.LanguageUtil; import com.intellij.lang.PerFileMappings; import com.intellij.lang.PerFileMappingsBase; import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.PersistentStateComponent; @@ -44,15 +45,14 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.psi.LanguageSubstitutor; import com.intellij.psi.LanguageSubstitutors; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiUtilCore; -import com.intellij.util.PairConsumer; import com.intellij.util.PathUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.IndexableSetContributor; +import com.intellij.util.indexing.LightDirectoryIndex; import com.intellij.util.messages.MessageBus; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -71,22 +71,14 @@ public class ScratchFileServiceImpl extends ScratchFileService implements Persis private final LightDirectoryIndex myIndex; private final MyLanguages myScratchMapping = new MyLanguages(); - protected ScratchFileServiceImpl(MessageBus messageBus) { - myIndex = new LightDirectoryIndex(messageBus.connect(), NULL_TYPE) { - - @Override - protected void collectRoots(@NotNull PairConsumer consumer) { - LocalFileSystem fileSystem = LocalFileSystem.getInstance(); - for (RootType r : RootType.getAllRootIds()) { - String root = getRootPath(r); - VirtualFile rootFile = fileSystem.findFileByPath(root); - if (rootFile != null) { - consumer.consume(rootFile, r); - } - } + protected ScratchFileServiceImpl(Application application) { + myIndex = new LightDirectoryIndex(application, NULL_TYPE, index -> { + LocalFileSystem fileSystem = LocalFileSystem.getInstance(); + for (RootType r : RootType.getAllRootIds()) { + index.putInfo(fileSystem.findFileByPath(getRootPath(r)), r); } - }; - initFileOpenedListener(messageBus); + }); + initFileOpenedListener(application.getMessageBus()); } @NotNull @@ -100,7 +92,6 @@ public class ScratchFileServiceImpl extends ScratchFileService implements Persis public RootType getRootType(@Nullable VirtualFile file) { if (file == null) return null; VirtualFile directory = file.isDirectory() ? file : file.getParent(); - if (!(directory instanceof VirtualFileWithId)) return null; RootType result = myIndex.getInfoForFile(directory); return result == NULL_TYPE ? null : result; } diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/LightDirectoryIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/LightDirectoryIndex.java similarity index 75% rename from platform/lang-impl/src/com/intellij/ide/scratch/LightDirectoryIndex.java rename to platform/lang-impl/src/com/intellij/util/indexing/LightDirectoryIndex.java index 9b965a02128b..d6a828370c3a 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/LightDirectoryIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/LightDirectoryIndex.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.ide.scratch; +package com.intellij.util.indexing; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileTypes.FileTypeEvent; import com.intellij.openapi.fileTypes.FileTypeListener; import com.intellij.openapi.fileTypes.FileTypeManager; @@ -23,7 +25,7 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; -import com.intellij.util.PairConsumer; +import com.intellij.util.Consumer; import com.intellij.util.containers.ConcurrentIntObjectMap; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBusConnection; @@ -33,23 +35,27 @@ import org.jetbrains.annotations.Nullable; import java.util.List; /** - * This is a light version of DirectoryIndexImpl. + * This is a light version of DirectoryIndexImpl * * @author gregsh */ -abstract class LightDirectoryIndex { +public final class LightDirectoryIndex { private final ConcurrentIntObjectMap myInfoCache = ContainerUtil.createConcurrentIntObjectMap(); private final T myDefValue; + private final Consumer> myInitializer; - public LightDirectoryIndex(@NotNull MessageBusConnection connection, @NotNull T defValue) { + public LightDirectoryIndex(@NotNull Disposable parentDisposable, @NotNull T defValue, @NotNull Consumer> initializer) { myDefValue = defValue; - reinitRoots(); + myInitializer = initializer; + resetIndex(); + MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(parentDisposable); connection.subscribe(FileTypeManager.TOPIC, new FileTypeListener.Adapter() { @Override public void fileTypesChanged(@NotNull FileTypeEvent event) { - reinitRoots(); + resetIndex(); } }); + connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() { @Override public void before(@NotNull List events) { @@ -60,7 +66,7 @@ abstract class LightDirectoryIndex { for (VFileEvent event : events) { VirtualFile file = event.getFile(); if (file == null || file.isDirectory()) { - reinitRoots(); + resetIndex(); break; } } @@ -68,15 +74,20 @@ abstract class LightDirectoryIndex { }); } - public void reinitRoots() { + public void resetIndex() { myInfoCache.clear(); - collectRoots((file, info) -> cacheInfo(file, info)); + myInitializer.consume(this); } - protected abstract void collectRoots(@NotNull PairConsumer consumer); + public void putInfo(@Nullable VirtualFile file, @NotNull T value) { + if (!(file instanceof VirtualFileWithId)) return; + cacheInfo(file, value); + } @NotNull - public T getInfoForFile(@NotNull VirtualFile file) { + public T getInfoForFile(@Nullable VirtualFile file) { + if (!(file instanceof VirtualFileWithId)) return myDefValue; + VirtualFile dir; if (!file.isDirectory()) { T info = getCachedInfo(file); From 336c99ec2c0550ea4a188ce5761b62ee11408796 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Tue, 12 Jul 2016 20:24:07 +0300 Subject: [PATCH 20/21] PY-18816 Remove failing tests from PyStubsTest since they check not existing functionality We decided to broaden the scope of PY-18816 so that Python 3-style function annotations (PEP 3107) are persisted in stub files as well. Since it requires much more efforts and won't be implemented soon it doesn't make much sense to keep these tests in the trunk. Dedicated feature branch contains them anyway. --- .../com/jetbrains/python/PyStubsTest.java | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/python/testSrc/com/jetbrains/python/PyStubsTest.java b/python/testSrc/com/jetbrains/python/PyStubsTest.java index 8c2cedbb3451..60eaac935e80 100644 --- a/python/testSrc/com/jetbrains/python/PyStubsTest.java +++ b/python/testSrc/com/jetbrains/python/PyStubsTest.java @@ -36,7 +36,6 @@ import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher; import com.jetbrains.python.psi.stubs.PyClassNameIndex; import com.jetbrains.python.psi.stubs.PyNamedTupleStub; import com.jetbrains.python.psi.stubs.PyVariableNameIndex; -import com.jetbrains.python.psi.types.PyClassType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; import com.jetbrains.python.toolbox.Maybe; @@ -439,39 +438,6 @@ public class PyStubsTest extends PyTestCase { assertNotParsed(file); } - // PY-18741 - public void testParameterTypeComment() { - final PyFile file = getTestFile(); - final PyFunction func = file.findTopLevelFunction("func"); - assertNotNull(func); - final PyParameter[] parameters = func.getParameterList().getParameters(); - assertSize(2, parameters); - final PyNamedParameter param = assertInstanceOf(parameters[0], PyNamedParameter.class); - final String annotation = param.getTypeCommentAnnotation(); - assertEquals("int", annotation); - assertNotParsed(file); - - final TypeEvalContext context = TypeEvalContext.codeAnalysis(myFixture.getProject(), file); - final PyType paramType = context.getType(param); - assertInstanceOf(paramType, PyClassType.class); - assertNotParsed(file); - } - - public void testTargetExpressionTypeComment() { - final PyFile file = getTestFile(); - final PyTargetExpression target = file.findTopLevelAttribute("x"); - assertNotNull(target); - - final String annotation = target.getTypeCommentAnnotation(); - assertEquals("int", annotation); - assertNotParsed(file); - - final TypeEvalContext context = TypeEvalContext.codeAnalysis(myFixture.getProject(), file); - final PyType paramType = context.getType(target); - assertInstanceOf(paramType, PyClassType.class); - assertNotParsed(file); - } - public void testFullyQualifiedNamedTuple() { doTestNamedTuple( QualifiedName.fromDottedString("collections.namedtuple") From e7a55718c9aad3fcd46b0061b0b3188333b5021d Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 12 Jul 2016 20:57:43 +0300 Subject: [PATCH 21/21] IDEA-97406 tune effect painter on Windows w/o HiDPI --- .../src/com/intellij/ui/EffectPainter.java | 25 +++++++------------ .../util/resources/misc/registry.properties | 2 -- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/EffectPainter.java b/platform/platform-api/src/com/intellij/ui/EffectPainter.java index d245349105a0..b22244b9644e 100644 --- a/platform/platform-api/src/com/intellij/ui/EffectPainter.java +++ b/platform/platform-api/src/com/intellij/ui/EffectPainter.java @@ -39,8 +39,7 @@ public enum EffectPainter implements RegionPainter { } else if (paint != null && width > 0 && height > 0) { int h = height > 6 && Registry.is("ide.text.effect.wave.new.scale") ? height >> 1 : 3; - double pos = Registry.doubleValue("ide.text.effect.line.new.pos"); - y += height < 3 ? 1 : (int)((double)height - h * pos); + y += height - 1 - h / 2; g.setPaint(paint); g.drawLine(x, y, x + width, y); } @@ -60,25 +59,17 @@ public enum EffectPainter implements RegionPainter { WavePainter.forColor(g.getColor()).paint(g, x, x + width, y + height); } else if (paint != null && width > 0 && height > 0) { - boolean simple = height < 5; - int h = height > 6 && Registry.is("ide.text.effect.wave.new.scale") ? height >> 1 : 3; - if (h != height) { - y += height - h; - height = h; - } g = (Graphics2D)g.create(x, y, width, height); - g.clipRect(0, -1, width, height + 1); // 1px for Retina painting - g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g.setPaint(paint); - - int length = 2 * height - 2; // the spatial period of the wave + g.clipRect(0, 0, width, height); + int h = height > 6 && Registry.is("ide.text.effect.wave.new.scale") ? height >> 1 : 3; + int length = 2 * h - 2; // the spatial period of the wave double dx = -((x % length + length) % length); // normalize - double upper = 0; + double upper = height - h; double lower = height - 1; Path2D path = new Path2D.Double(); path.moveTo(dx, lower); - if (simple) { + if (height < 6) { g.setStroke(STROKE); double size = (double)length / 2; while (true) { @@ -91,7 +82,7 @@ public enum EffectPainter implements RegionPainter { else { double size = (double)length / 4; double prev = dx - size / 2; - double center = lower / 2; + double center = (upper + lower) / 2; while (true) { path.quadTo(prev += size, lower, dx += size, center); if (dx > width) break; @@ -103,6 +94,8 @@ public enum EffectPainter implements RegionPainter { if (dx > width) break; } } + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setPaint(paint); g.draw(path); g.dispose(); } diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 173902c9773b..12af5cd126b1 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -768,8 +768,6 @@ editor.rainbow.identifiers.description=Rainbow identifiers in editor ide.text.effect.line.new=false ide.text.effect.line.new.description=Enables new line painter for text -ide.text.effect.line.new.pos=0.5 -ide.text.effect.line.new.pos.description=Changes a line position ide.text.effect.wave.new=false ide.text.effect.wave.new.description=Enables new wave painter for text ide.text.effect.wave.new.scale=false