From c8795023fefd7463083d3dab095010e02d6eb787 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 26 Nov 2014 14:11:28 +0100 Subject: [PATCH 01/38] use JBColor.RED --- .../idea/svn/history/SvnMergeInfoRootPanelManual.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java index d4b48281f7ca..350925847ef2 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnMergeInfoRootPanelManual.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,15 +20,16 @@ import com.intellij.openapi.ui.FixedSizeButton; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.JBColor; import com.intellij.util.NullableFunction; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager; import org.jetbrains.idea.svn.SvnBundle; import org.jetbrains.idea.svn.SvnUtil; import org.jetbrains.idea.svn.branchConfig.SelectBranchPopup; import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew; +import org.jetbrains.idea.svn.branchConfig.SvnBranchMapperManager; import org.jetbrains.idea.svn.dialogs.WCInfoWithBranches; import org.jetbrains.idea.svn.integrate.IntegratedSelectedOptionsDialog; import org.jetbrains.idea.svn.integrate.WorkingCopyInfo; @@ -196,7 +197,7 @@ public class SvnMergeInfoRootPanelManual { gb.gridx = 0; gb.gridwidth = 2; myMixedRevisions = new JTextArea("Mixed Revision Working Copy"); - myMixedRevisions.setForeground(Color.red); + myMixedRevisions.setForeground(JBColor.RED); myMixedRevisions.setBackground(myContentPanel.getBackground()); myContentPanel.add(myMixedRevisions, gb); @@ -231,7 +232,7 @@ public class SvnMergeInfoRootPanelManual { private void calculateBranchPathByBranch(final String url, final String localPath) { final String local = url == null ? null : getLocal(url, localPath == null ? myBranchToLocal.get(url) : localPath); if (local == null) { - myLocalArea.setForeground(Color.red); + myLocalArea.setForeground(JBColor.RED); myLocalArea.setText(SvnBundle.message("tab.repository.merge.panel.root.panel.select.local")); } else { myLocalArea.setForeground(UIUtil.getInactiveTextColor()); From 290ad456db942298d2356061cc759cd871124709 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 26 Nov 2014 14:13:25 +0100 Subject: [PATCH 02/38] use JBColor.RED --- .../idea/svn/treeConflict/TreeConflictRefreshablePanel.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/TreeConflictRefreshablePanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/TreeConflictRefreshablePanel.java index 9a68d63527ae..e35ff970d033 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/TreeConflictRefreshablePanel.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/TreeConflictRefreshablePanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangesUtil; import com.intellij.openapi.vcs.history.*; import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; +import com.intellij.ui.JBColor; import com.intellij.util.BeforeAfter; import com.intellij.util.containers.Convertor; import com.intellij.util.ui.UIUtil; @@ -230,7 +231,7 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel { BeforeAfter ba, boolean directory) { if (description == null) return; JLabel descriptionLbl = new JLabel(description.toPresentableString()); - descriptionLbl.setForeground(Color.red); + descriptionLbl.setForeground(JBColor.RED); main.add(descriptionLbl, gb); ++ gb.gridy; //buttons From 23cf7391b5393642eaccfca4b601ea4d9ef365b0 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Wed, 26 Nov 2014 16:18:40 +0300 Subject: [PATCH 03/38] IDEA-112485 Shortcut to maximize toolwindow : improvements Add "resize" and "move to" actions to "Gear" tool window button Rollback to old tool window animation --- .../openapi/ui/ThreeComponentsSplitter.java | 6 +- .../openapi/wm/impl/InternalDecorator.java | 13 +- .../openapi/wm/impl/ToolWindowHeader.java | 21 +- .../openapi/wm/impl/ToolWindowsPane.java | 202 ++++++++++++------ 4 files changed, 157 insertions(+), 85 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java index e6311fbae473..5e92dc130e60 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java @@ -37,7 +37,7 @@ import java.awt.event.MouseEvent; * @author Vladimir Kondratyev */ public class ThreeComponentsSplitter extends JPanel implements Disposable { - public static final int MIN_SIZE = 48; + public static final int MIN_SIZE = 0; private int myDividerWidth; /** @@ -63,8 +63,8 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { @Nullable private JComponent myInnerComponent; @Nullable private JComponent myLastComponent; - private int myFirstSize = 10; - private int myLastSize = 10; + private int myFirstSize = 0; + private int myLastSize = 0; private boolean myShowDividerControls; private int myDividerZone; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java index 371d847f1699..876d4e8c5886 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/InternalDecorator.java @@ -99,7 +99,7 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr myHeader = new ToolWindowHeader(toolWindow, info, new Producer() { @Override public ActionGroup produce() { - return createGearPopupGroup(); + return /*createGearPopupGroup()*/createPopupGroup(true); } }) { @Override @@ -370,6 +370,10 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr public final ActionGroup createPopupGroup() { + return createPopupGroup(false); + } + + public final ActionGroup createPopupGroup(boolean skipHideAction) { final DefaultActionGroup group = createGearPopupGroup(); if (!ToolWindowId.PREVIEW.equals(myInfo.getId())) { group.add(myToggleContentUiTypeAction); @@ -405,9 +409,10 @@ public final class InternalDecorator extends JPanel implements Queryable, DataPr resize.add(ActionManager.getInstance().getAction("MaximizeToolWindow")); group.add(resize); - - group.addSeparator(); - group.add(new HideAction()); + if (!skipHideAction) { + group.addSeparator(); + group.add(new HideAction()); + } return group; } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java index 7d64b1180e15..e3ebfe83a4b3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowHeader.java @@ -25,13 +25,12 @@ import com.intellij.openapi.actionSystem.ex.ActionManagerEx; import com.intellij.openapi.actionSystem.impl.*; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowAnchor; -import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.openapi.wm.ToolWindowType; import com.intellij.openapi.wm.impl.content.ToolWindowContentUi; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.InplaceButton; import com.intellij.ui.PopupHandler; import com.intellij.ui.UIBundle; @@ -91,7 +90,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS Component c = getComponent(0); Dimension size = c.getPreferredSize(); if (size.width < (r.width - insets.left - insets.right)) { - c.setBounds(insets.left, insets.top, r.width, r.height - insets.top - insets.bottom); + c.setBounds(insets.left, insets.top, size.width, r.height - insets.top - insets.bottom); } else { c.setBounds(insets.left, insets.top, r.width - insets.left - insets.right, r.height - insets.top - insets.bottom); } @@ -169,7 +168,7 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS addDefaultActions(eastPanel); myButtonPanel = eastPanel; - addMouseListener(new PopupHandler() { + westPanel.addMouseListener(new PopupHandler() { public void invokePopup(final Component comp, final int x, final int y) { toolWindow.getContentUI().showContextMenu(comp, x, y, toolWindow.getPopupGroup(), toolWindow.getContentManager().getSelectedContent()); } @@ -210,12 +209,14 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS } } }; - } - - void switchMaximizedState(Project project) { - if (project == null || project.isDisposed()) return; - ToolWindowManager mgr = ToolWindowManager.getInstance(project); - mgr.setMaximized(myToolWindow, !mgr.isMaximized(myToolWindow)); + new DoubleClickListener(){ + @Override + protected boolean onDoubleClick(MouseEvent event) { + ToolWindowManagerImpl mgr = toolWindow.getToolWindowManager(); + mgr.setMaximized(myToolWindow, !mgr.isMaximized(myToolWindow)); + return true; + } + }.installOn(westPanel); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java index ffab6a556285..2df9549e8cee 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowsPane.java @@ -22,28 +22,25 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.ui.ThreeComponentsSplitter; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; -import com.intellij.openapi.wm.IdeGlassPaneUtil; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ToolWindowType; import com.intellij.openapi.wm.impl.commands.FinalizableCommand; +import com.intellij.reference.SoftReference; import com.intellij.ui.ScreenUtil; import com.intellij.ui.components.JBLayeredPane; import com.intellij.util.containers.HashMap; -import com.intellij.util.ui.FadeInFadeOut; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; @@ -201,24 +198,6 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable { super.addNotify(); if (ScreenUtil.isStandardAddRemoveNotify(this)) { UISettings.getInstance().addUISettingsListener(myUISettingsListener, myDisposable); - IdeGlassPaneUtil.find(this).addMousePreprocessor(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2 && e.getModifiersEx() == 0) { - e = SwingUtilities.convertMouseEvent(e.getComponent(), e, ToolWindowsPane.this); - Component component = SwingUtilities.getDeepestComponentAt(ToolWindowsPane.this, e.getX(), e.getY()); - Component header = component == null ? null : UIUtil.findParentByCondition((JComponent)component, new Condition() { - @Override - public boolean value(Component component) { - return component instanceof ToolWindowHeader || component instanceof ActionListener; - } - }); - if (header instanceof ToolWindowHeader) { - ((ToolWindowHeader)header).switchMaximizedState(myFrame.getProject()); - } - } - } - }, this); } } @@ -891,36 +870,60 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable { myInfo = info; myDirtyMode = dirtyMode; } - public final void run() { - // Show component. - final UISettings uiSettings = UISettings.getInstance(); - if (!myDirtyMode && uiSettings.ANIMATE_WINDOWS && !UISettings.isRemoteDesktopConnected()) { - myLayeredPane.add(myComponent, JLayeredPane.PALETTE_LAYER); - myLayeredPane.moveToFront(myComponent); - myLayeredPane.setBoundsInPaletteLayer(myComponent, myInfo.getAnchor(), myInfo.getWeight()); - final FadeInFadeOut fadeIn = new FadeInFadeOut(myComponent, 250, true, myId2Button.get(myInfo.getId())); - add(fadeIn, FadeInFadeOut.LAYER); - fadeIn.setBounds(0, 0, getWidth(), getHeight()); - myLayeredPane.remove(myComponent); - fadeIn.doAnimation(new Runnable() { - @Override - public void run() { - remove(fadeIn); + try { + // Show component. + final UISettings uiSettings = UISettings.getInstance(); + if (!myDirtyMode && uiSettings.ANIMATE_WINDOWS && !UISettings.isRemoteDesktopConnected()) { + // Prepare top image. This image is scrolling over bottom image. + final Image topImage = myLayeredPane.getTopImage(); + final Graphics topGraphics = topImage.getGraphics(); + + Rectangle bounds; + + try { myLayeredPane.add(myComponent, JLayeredPane.PALETTE_LAYER); - //myComponent.requestFocus(); - repaint(); - finish(); + myLayeredPane.moveToFront(myComponent); + myLayeredPane.setBoundsInPaletteLayer(myComponent, myInfo.getAnchor(), myInfo.getWeight()); + bounds = myComponent.getBounds(); + myComponent.paint(topGraphics); + myLayeredPane.remove(myComponent); } - }); - } - else { // not animated - myLayeredPane.add(myComponent, JLayeredPane.PALETTE_LAYER); - myLayeredPane.setBoundsInPaletteLayer(myComponent, myInfo.getAnchor(), myInfo.getWeight()); + finally { + topGraphics.dispose(); + } + // Prepare bottom image. + final Image bottomImage = myLayeredPane.getBottomImage(); + final Graphics bottomGraphics = bottomImage.getGraphics(); + try { + bottomGraphics.setClip(0, 0, bounds.width, bounds.height); + bottomGraphics.translate(-bounds.x, -bounds.y); + myLayeredPane.paint(bottomGraphics); + } + finally { + bottomGraphics.dispose(); + } + // Start animation. + final Surface surface = new Surface(topImage, bottomImage, 1, myInfo.getAnchor(), uiSettings.ANIMATION_SPEED); + myLayeredPane.add(surface, JLayeredPane.PALETTE_LAYER); + surface.setBounds(bounds); + myLayeredPane.validate(); + myLayeredPane.repaint(); + + surface.runMovement(); + myLayeredPane.remove(surface); + myLayeredPane.add(myComponent, JLayeredPane.PALETTE_LAYER); + } + else { // not animated + myLayeredPane.add(myComponent, JLayeredPane.PALETTE_LAYER); + myLayeredPane.setBoundsInPaletteLayer(myComponent, myInfo.getAnchor(), myInfo.getWeight()); + } if (!myDirtyMode) { - myLayeredPane.revalidate(); + myLayeredPane.validate(); myLayeredPane.repaint(); } + } + finally { finish(); } } @@ -1076,30 +1079,53 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable { myInfo = info; myDirtyMode = dirtyMode; } - public final void run() { - final UISettings uiSettings = UISettings.getInstance(); - if (!myDirtyMode && uiSettings.ANIMATE_WINDOWS && !UISettings.isRemoteDesktopConnected()) { - // Remove component from the layered pane and start animation. - final FadeInFadeOut fadeOut = new FadeInFadeOut(myComponent, 450, false, getButtonById(myInfo.getId())); - add(fadeOut, FadeInFadeOut.LAYER); - fadeOut.setBounds(0, 0, getWidth(), getHeight()); - myLayeredPane.remove(myComponent); - fadeOut.doAnimation(new Runnable() { - @Override - public void run() { - remove(fadeOut); - repaint(); - finish(); + try { + final UISettings uiSettings = UISettings.getInstance(); + if (!myDirtyMode && uiSettings.ANIMATE_WINDOWS && !UISettings.isRemoteDesktopConnected()) { + final Rectangle bounds = myComponent.getBounds(); + // Prepare top image. This image is scrolling over bottom image. It contains + // picture of component is being removed. + final Image topImage = myLayeredPane.getTopImage(); + final Graphics topGraphics = topImage.getGraphics(); + try { + myComponent.paint(topGraphics); } - }); - } - else { // not animated - myLayeredPane.remove(myComponent); + finally { + topGraphics.dispose(); + } + // Prepare bottom image. This image contains picture of component that is located + // under the component to is being removed. + final Image bottomImage = myLayeredPane.getBottomImage(); + final Graphics bottomGraphics = bottomImage.getGraphics(); + try { + myLayeredPane.remove(myComponent); + bottomGraphics.clipRect(0, 0, bounds.width, bounds.height); + bottomGraphics.translate(-bounds.x, -bounds.y); + myLayeredPane.paint(bottomGraphics); + } + finally { + bottomGraphics.dispose(); + } + // Remove component from the layered pane and start animation. + final Surface surface = new Surface(topImage, bottomImage, -1, myInfo.getAnchor(), uiSettings.ANIMATION_SPEED * 2); + myLayeredPane.add(surface, JLayeredPane.PALETTE_LAYER); + surface.setBounds(bounds); + myLayeredPane.validate(); + myLayeredPane.repaint(); + + surface.runMovement(); + myLayeredPane.remove(surface); + } + else { // not animated + myLayeredPane.remove(myComponent); + } if (!myDirtyMode) { - myLayeredPane.revalidate(); + myLayeredPane.validate(); myLayeredPane.repaint(); } + } + finally { finish(); } } @@ -1166,18 +1192,58 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable { updateLayout(); } } - private final class MyLayeredPane extends JBLayeredPane { /* * These images are used to perform animated showing and hiding of components. * They are the member for performance reason. */ + private SoftReference myBottomImageRef; + private SoftReference myTopImageRef; public MyLayeredPane(final JComponent splitter) { + myBottomImageRef = new SoftReference(null); + myTopImageRef = new SoftReference(null); setOpaque(false); add(splitter, JLayeredPane.DEFAULT_LAYER); } + public final Image getBottomImage() { + Pair> result = getImage(myBottomImageRef); + myBottomImageRef = result.second; + return result.first; + } + + public final Image getTopImage() { + Pair> result = getImage(myTopImageRef); + myTopImageRef = result.second; + return result.first; + } + + private Pair> getImage(SoftReference imageRef) { + LOG.assertTrue(UISettings.getInstance().ANIMATE_WINDOWS); + BufferedImage image = imageRef.get(); + if ( + image == null || + image.getWidth(null) < getWidth() || image.getHeight(null) < getHeight() + ) { + final int width = Math.max(Math.max(1, getWidth()), myFrame.getWidth()); + final int height = Math.max(Math.max(1, getHeight()), myFrame.getHeight()); + if (SystemInfo.isWindows) { + image = myFrame.getGraphicsConfiguration().createCompatibleImage(width, height); + } + else { + // Under Linux we have found that images created by createCompatibleImage(), + // createVolatileImage(), etc extremely slow for rendering. TrueColor buffered image + // is MUCH faster. + // On Mac we create a retina-compatible image + + image = UIUtil.createImage(width, height, BufferedImage.TYPE_INT_RGB); + } + imageRef = new SoftReference(image); + } + return Pair.create(image, imageRef); + } + /** * When component size becomes larger then bottom and top images should be enlarged. */ From ef1fd265ddb9a50db2724b78ba015da5e3374669 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 26 Nov 2014 14:19:54 +0100 Subject: [PATCH 04/38] use JBColor.RED --- .../changes/committed/CommittedChangesFilterDialog.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesFilterDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesFilterDialog.java index a164ea34228c..716df11437fb 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesFilterDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesFilterDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,15 +22,16 @@ */ package com.intellij.openapi.vcs.changes.committed; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.vcs.VcsBundle; import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings; import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor; -import com.intellij.openapi.application.ModalityState; +import com.intellij.ui.JBColor; import com.intellij.util.Alarm; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -54,7 +55,7 @@ public class CommittedChangesFilterDialog extends DialogWrapper { myPanel.setSettings(settings); setTitle(VcsBundle.message("browse.changes.filter.title")); init(); - myErrorLabel.setForeground(Color.red); + myErrorLabel.setForeground(JBColor.RED); validateInput(); myValidateAlarm.addRequest(myValidateRunnable, 500, ModalityState.stateForComponent(myPanel.getComponent())); } From f27c3422ed42cf65dedd525f02204c567d7d0a43 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 26 Nov 2014 16:47:39 +0300 Subject: [PATCH 05/38] EA-62753 - SOE: JComponent.paint --- .../xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java index a346eef46ea0..3f124d04bc7c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java @@ -75,7 +75,7 @@ public class XDebuggerEditorLinePainter extends EditorLinePainter { } Set values = map.get(Pair.create(file, lineNumber)); if (values != null && !values.isEmpty()) { - final int bpLine = getCurrentBreakPointLine(values); + final int bpLine = getCurrentBreakPointLineInFile(values, file); ArrayList result = new ArrayList(); for (XValueNodeImpl value : values) { SimpleColoredText text = new SimpleColoredText(); @@ -147,13 +147,13 @@ public class XDebuggerEditorLinePainter extends EditorLinePainter { return null; } - private static int getCurrentBreakPointLine(Set values) { + private static int getCurrentBreakPointLineInFile(Set values, VirtualFile file) { try { final XValueNodeImpl node = values.iterator().next(); final XDebugSession session = XDebugView.getSession(node.getTree()); if (session != null) { final XSourcePosition position = session.getCurrentPosition(); - if (position != null) { + if (position != null && position.getFile().equals(file)) { return position.getLine(); } } From 54e581f0650ad60a80bf4281b0fcc7df53a9d386 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Wed, 26 Nov 2014 15:44:33 +0200 Subject: [PATCH 06/38] clean up, formatting --- .../psi/formatter/java/AbstractJavaBlock.java | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index c092223ea47a..313718928ef4 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -50,31 +50,24 @@ import static com.intellij.psi.formatter.java.JavaFormatterUtil.getWrapType; public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlock, ReservedWrapsProvider { - /** - * Holds types of the elements for which 'align in column' rule may be preserved. - * - * @see CodeStyleSettings#ALIGN_GROUP_FIELD_DECLARATIONS - */ - protected static final Set ALIGN_IN_COLUMNS_ELEMENT_TYPES = Collections.unmodifiableSet(new HashSet( - Arrays.asList(JavaElementType.FIELD))); - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.formatter.java.AbstractJavaBlock"); - /** - * Shared thread-safe config object to use during 'align in column' processing. - * - * @see CodeStyleSettings#ALIGN_GROUP_FIELD_DECLARATIONS - */ - private static final AlignmentInColumnsConfig ALIGNMENT_IN_COLUMNS_CONFIG = new AlignmentInColumnsConfig( - TokenSet.create(JavaTokenType.IDENTIFIER), JavaJspElementType.WHITE_SPACE_BIT_SET, ElementType.JAVA_COMMENT_BIT_SET, - TokenSet.create(JavaTokenType.EQ), TokenSet.create(JavaElementType.FIELD)); + protected static final Set ALIGN_IN_COLUMNS_ELEMENT_TYPES = ContainerUtil.newHashSet(JavaElementType.FIELD); - /** - * Enumerates types of variable declaration sub-elements that should be aligned in columns. - */ - private static final Set VAR_DECLARATION_ELEMENT_TYPES_TO_ALIGN = new HashSet(Arrays.asList( - JavaElementType.MODIFIER_LIST, JavaElementType.TYPE, JavaTokenType.IDENTIFIER, JavaTokenType.EQ - )); + private static final AlignmentInColumnsConfig ALIGNMENT_IN_COLUMNS_CONFIG = new AlignmentInColumnsConfig( + TokenSet.create(JavaTokenType.IDENTIFIER), + JavaJspElementType.WHITE_SPACE_BIT_SET, + ElementType.JAVA_COMMENT_BIT_SET, + TokenSet.create(JavaTokenType.EQ), + TokenSet.create(JavaElementType.FIELD) + ); + + private static final Set VAR_DECLARATION_ELEMENT_TYPES_TO_ALIGN = ContainerUtil.newHashSet( + JavaElementType.MODIFIER_LIST, + JavaElementType.TYPE, + JavaTokenType.IDENTIFIER, + JavaTokenType.EQ + ); @NotNull protected final CommonCodeStyleSettings mySettings; @NotNull protected final JavaCodeStyleSettings myJavaSettings; From 13101eee41d290306cf5b58df741ba97974156f6 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Wed, 26 Nov 2014 16:27:07 +0200 Subject: [PATCH 07/38] SimpleJavaBlock, minor refactoring --- .../psi/formatter/java/SimpleJavaBlock.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/SimpleJavaBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/SimpleJavaBlock.java index 478f8ba8d065..06a2e136d659 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/SimpleJavaBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/SimpleJavaBlock.java @@ -50,7 +50,11 @@ public class SimpleJavaBlock extends AbstractJavaBlock { @Override protected List buildChildren() { ASTNode child = myNode.getFirstChildNode(); - int offset = myStartOffset != -1 ? myStartOffset : child != null ? child.getTextRange().getStartOffset():0; + int offset = myStartOffset; + if (offset == -1) { + offset = child != null ? child.getTextRange().getStartOffset() : 0; + } + final ArrayList result = new ArrayList(); Indent indent = null; @@ -71,11 +75,9 @@ public class SimpleJavaBlock extends AbstractJavaBlock { myReservedAlignment2 = createChildAlignment2(myReservedAlignment); Wrap childWrap = createChildWrap(); while (child != null) { - if (!FormatterUtil.containsWhiteSpacesOnly(child) && child.getTextLength() > 0){ + if (isNotEmptyNode(child)) { final ASTNode astNode = child; - AlignmentStrategy alignmentStrategyToUse = ALIGN_IN_COLUMNS_ELEMENT_TYPES.contains(myNode.getElementType()) - ? myAlignmentStrategy - : AlignmentStrategy.wrap(chooseAlignment(myReservedAlignment, myReservedAlignment2, child)); + AlignmentStrategy alignmentStrategyToUse = getAlignmentStrategy(child); child = processChild(result, astNode, alignmentStrategyToUse, childWrap, indent, offset); if (astNode != child && child != null) { offset = child.getTextRange().getStartOffset(); @@ -86,6 +88,7 @@ public class SimpleJavaBlock extends AbstractJavaBlock { indent = Indent.getContinuationIndent(myIndentSettings.USE_RELATIVE_INDENTS); } } + if (child != null) { offset += child.getTextLength(); child = child.getTreeNext(); @@ -95,6 +98,16 @@ public class SimpleJavaBlock extends AbstractJavaBlock { return result; } + private AlignmentStrategy getAlignmentStrategy(ASTNode child) { + return ALIGN_IN_COLUMNS_ELEMENT_TYPES.contains(myNode.getElementType()) + ? myAlignmentStrategy + : AlignmentStrategy.wrap(chooseAlignment(myReservedAlignment, myReservedAlignment2, child)); + } + + private boolean isNotEmptyNode(@NotNull ASTNode child) { + return !FormatterUtil.containsWhiteSpacesOnly(child) && child.getTextLength() > 0; + } + @Override @NotNull public TextRange getTextRange() { From b09de7b6bfb2f5cdefd4ee19e945d373d63d08ab Mon Sep 17 00:00:00 2001 From: Sergey Savenko Date: Wed, 26 Nov 2014 17:05:20 +0300 Subject: [PATCH 08/38] EditorImpl: replace 'show placeholder when focused' data key with an instance field --- .../injected/editor/EditorWindowImpl.java | 5 +++++ .../com/intellij/openapi/editor/ex/EditorEx.java | 16 +++++++++++----- .../intellij/openapi/editor/impl/EditorImpl.java | 9 +++++++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java index f1619d483e85..9b25f882e162 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/EditorWindowImpl.java @@ -823,6 +823,11 @@ public class EditorWindowImpl extends UserDataHolderBase implements EditorWindow myDelegate.setPlaceholder(text); } + @Override + public void setShowPlaceholderWhenFocused(boolean show) { + myDelegate.setShowPlaceholderWhenFocused(show); + } + @Override public boolean isStickySelection() { return myDelegate.isStickySelection(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java index 2776693048fa..9e0a49f29b4f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorEx.java @@ -48,7 +48,6 @@ public interface EditorEx extends Editor { @NonNls String PROP_COLUMN_MODE = "columnMode"; @NonNls String PROP_FONT_SIZE = "fontSize"; Key LAST_PASTED_REGION = Key.create("LAST_PASTED_REGION"); - Key SHOW_PLACEHOLDER_WHEN_FOCUSED = Key.create("SHOW_PLACEHOLDER_WHEN_FOCUSED"); @NotNull @Override @@ -199,10 +198,8 @@ public interface EditorEx extends Editor { /** * Allows to define 'placeholder text' for the current editor, i.e. virtual text that will be represented until - * any user data is entered and current editor is not focused. - *

- * If {@link EditorEx#SHOW_PLACEHOLDER_WHEN_FOCUSED} is set to 'true', the placeholder is shown in focused editor as well. - *

+ * any user data is entered. + * * Feel free to see the detailed feature * definition here. * @@ -210,6 +207,15 @@ public interface EditorEx extends Editor { */ void setPlaceholder(@Nullable CharSequence text); + /** + * Controls whether 'placeholder text' is visible when editor is focused. + * + * @param show flag indicating whether placeholder is visible when editor is focused. + * + * @see EditorEx#setPlaceholder(CharSequence) + */ + void setShowPlaceholderWhenFocused(boolean show); + /** * Allows to answer if 'sticky selection' is active for the current editor. *

diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index dab537256527..e4d03477e47d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -276,6 +276,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi @Nullable private CharSequence myPlaceholderText; private int myLastPaintedPlaceholderWidth; + private boolean myShowPlaceholderWhenFocused; private boolean myStickySelection; private int myStickySelectionStart; @@ -2113,6 +2114,11 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi myPlaceholderText = text; } + @Override + public void setShowPlaceholderWhenFocused(boolean show) { + myShowPlaceholderWhenFocused = show; + } + Color getBackgroundColor(@NotNull final TextAttributes attributes) { final Color attrColor = attributes.getBackgroundColor(); return Comparing.equal(attrColor, myScheme.getDefaultBackground()) ? getBackgroundColor() : attrColor; @@ -2930,8 +2936,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi return false; } - if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == myEditorComponent && - !Boolean.TRUE.equals(SHOW_PLACEHOLDER_WHEN_FOCUSED.get(this))) { + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == myEditorComponent && !myShowPlaceholderWhenFocused) { // There is a possible case that placeholder text was painted and the editor gets focus now. We want to over-paint previously // used placeholder text then. myLastBackgroundColor = getBackgroundColor(); From 4b90abf671f4b52125d12b56fb37b13391530cfa Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 26 Nov 2014 15:58:19 +0300 Subject: [PATCH 09/38] cleanup --- .../com/intellij/psi/impl/source/xml/XmlElementImpl.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlElementImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlElementImpl.java index ec5f1d903b37..c49459d67b4e 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlElementImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlElementImpl.java @@ -148,11 +148,10 @@ public abstract class XmlElementImpl extends CompositePsiElement implements XmlE if (super.isEquivalentTo(another)) return true; PsiElement element1 = this; - PsiElement element2 = another; - // TODO: seem to be only necessary for tag dirs equivalens checking. - if (element1 instanceof XmlTag && element2 instanceof XmlTag) { - if (!element1.isPhysical() && !element2.isPhysical()) return element1.getText().equals(element2.getText()); + // TODO: seem to be only necessary for tag dirs equivalents checking. + if (element1 instanceof XmlTag && another instanceof XmlTag) { + if (!element1.isPhysical() && !another.isPhysical()) return element1.getText().equals(another.getText()); } return false; From c7ac8a6d197e16d664664c9de870f2d3375dccbe Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Wed, 26 Nov 2014 17:04:14 +0300 Subject: [PATCH 10/38] IDEA-58299 JSP: Find Usages / Rename works incorrect for variables defined in tag c:forEach --- .../src/com/intellij/testFramework/PsiTestUtil.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java index 659b938b8023..d925a53cfa1d 100644 --- a/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/PsiTestUtil.java @@ -262,6 +262,12 @@ public class PsiTestUtil { Assert.assertEquals(reparsedTree, originalTree); } + public static void addLibrary(final Module module, final String libPath) { + File file = new File(libPath); + String libName = file.getName(); + addLibrary(module, libName, file.getParent(), libName); + } + public static void addLibrary(final Module module, final String libName, final String libPath, final String... jarArr) { ModuleRootModificationUtil.updateModel(module, new Consumer() { @Override From c23ee70b4a83d2b138f53cec52d8e2e05ee626f0 Mon Sep 17 00:00:00 2001 From: irengrig Date: Wed, 26 Nov 2014 15:25:32 +0100 Subject: [PATCH 11/38] v8 profiling, fix filter action position --- .../com/intellij/ui/components/SliderSelectorAction.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/components/SliderSelectorAction.java b/platform/platform-impl/src/com/intellij/ui/components/SliderSelectorAction.java index 39d81e6fb487..189e2d39e0d7 100644 --- a/platform/platform-impl/src/com/intellij/ui/components/SliderSelectorAction.java +++ b/platform/platform-impl/src/com/intellij/ui/components/SliderSelectorAction.java @@ -88,7 +88,7 @@ public class SliderSelectorAction extends DumbAwareAction { }); } - final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(result, slider).createPopup(); + final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(result, slider).setMovable(true).createPopup(); final Runnable finalRunnable = new Runnable() { @Override public void run() { @@ -105,6 +105,10 @@ public class SliderSelectorAction extends DumbAwareAction { }; popup.setFinalRunnable(finalRunnable); InputEvent inputEvent = e.getInputEvent(); + show(e, result, popup, inputEvent); + } + + protected void show(AnActionEvent e, JPanel result, JBPopup popup, InputEvent inputEvent) { if (inputEvent instanceof MouseEvent) { int width = result.getPreferredSize().width; MouseEvent inputEvent1 = (MouseEvent)inputEvent; From f8b36f3452377e8b226109701abf29317605e691 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 26 Nov 2014 18:05:33 +0300 Subject: [PATCH 12/38] UIUtil refactoring --- .../util/src/com/intellij/util/ui/UIUtil.java | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 376b0da273c6..ad8d3eeb36c3 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -2890,13 +2890,29 @@ public class UIUtil { } } + /** + * Adds an empty border with the specified insets to the specified component. + * If the component already has a border it will be preserved. + * + * @param component the component to which border added + * @param top the inset from the top + * @param left the inset from the left + * @param bottom the inset from the bottom + * @param right the inset from the right + */ + public static void addInsets(@NotNull JComponent component, int top, int left, int bottom, int right) { + addBorder(component, BorderFactory.createEmptyBorder(top, left, bottom, right)); + } + + /** + * Adds an empty border with the specified insets to the specified component. + * If the component already has a border it will be preserved. + * + * @param component the component to which border added + * @param insets the top, left, bottom, and right insets + */ public static void addInsets(@NotNull JComponent component, @NotNull Insets insets) { - if (component.getBorder() != null) { - component.setBorder(new CompoundBorder(new EmptyBorder(insets), component.getBorder())); - } - else { - component.setBorder(new EmptyBorder(insets)); - } + addInsets(component, insets.top, insets.left, insets.bottom, insets.right); } public static Dimension addInsets(@NotNull Dimension dimension, @NotNull Insets insets) { @@ -2947,13 +2963,20 @@ public class UIUtil { return null; } + /** + * Adds the specified border to the specified component. + * If the component already has a border it will be preserved. + * If component or border is not specified nothing happens. + * + * @param component the component to which border added + * @param border the border to add to the component + */ public static void addBorder(JComponent component, Border border) { - if (component == null) return; - - if (component.getBorder() != null) { - component.setBorder(new CompoundBorder(border, component.getBorder())); - } - else { + if (component != null && border != null) { + Border old = component.getBorder(); + if (old != null) { + border = BorderFactory.createCompoundBorder(border, old); + } component.setBorder(border); } } From cb92eb7df712e04a11ccac016070a4208b588cc6 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Nov 2014 12:33:32 +0100 Subject: [PATCH 13/38] IndexTestGenerator: support testing for language level changes --- .../intellij/index/IndexTestGenerator.scala | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/index/IndexTestGenerator.scala b/java/java-tests/testSrc/com/intellij/index/IndexTestGenerator.scala index b28b998e65d5..a7327bdfbfe6 100644 --- a/java/java-tests/testSrc/com/intellij/index/IndexTestGenerator.scala +++ b/java/java-tests/testSrc/com/intellij/index/IndexTestGenerator.scala @@ -44,11 +44,13 @@ object IndexTestGenerator { const(InvisiblePsiChange), const(PostponedFormatting), const(Reformat), - const(LoadViewProviderDocument), + const(ForceReloadPsi), + const(AddEnum), const(CheckStamps), for (withImport <- arbitrary[Boolean]; viaDocument <- arbitrary[Boolean]) yield TextChange(viaDocument, withImport), + arbitrary[Boolean] map ChangeLanguageLevel, arbitrary[Boolean] map UpdatePsiClassRef, arbitrary[Boolean] map UpdatePsiFileRef, arbitrary[Boolean] map UpdateASTNodeRef, @@ -97,18 +99,26 @@ case class IndexTestSeq(actions: List[Action]) { |""".stripMargin) } + def printPostponedFormatting = sb.append( + """PostprocessReformattingAspect.getInstance(getProject()). + | doPostponedFormatting() + |""".stripMargin) + + for (action <- actions) { sb.append("\n") action match { case Gc => sb.append("PlatformTestUtil.tryGcSoftlyReachableObjects()\n") - case LoadViewProviderDocument => - sb.append("assert psiManager.findFile(vFile).viewProvider.document\n") case PostponedFormatting => - sb.append( - """PostprocessReformattingAspect.getInstance(getProject()). - | doPostponedFormatting() - |""".stripMargin) + printPostponedFormatting + case ForceReloadPsi => + printPostponedFormatting + sb.append("FileContentUtilCore.reparseFiles(vFile)\n") + case ChangeLanguageLevel(highest) => + printPostponedFormatting + val level = if (highest) "HIGHEST" else "JDK_1_3" + sb.append(s"IdeaTestUtil.setModuleLanguageLevel(myFixture.module, LanguageLevel.$level)\n") case CheckStamps => sb.append( """L:{ @@ -147,6 +157,12 @@ case class IndexTestSeq(actions: List[Action]) { s"""((PsiJavaFile)psiManager.findFile(vFile)).importList.add( | elementFactory.createImportStatementOnDemand("java.io")) |""".stripMargin) + case AddEnum => + printCommit + sb.append( + s"""psiManager.findFile(vFile).add( + | elementFactory.createEnum("SomeEnum")) + |""".stripMargin) case InvisiblePsiChange => printCommit sb.append( @@ -167,14 +183,13 @@ case class IndexTestSeq(actions: List[Action]) { case UpdateDocumentRef(load) => sb.append("document = " + (if (load) "FileDocumentManager.instance.getDocument(vFile)" else "null") + "\n") case TextChange(viaDocument, withImport) => + printPostponedFormatting changeId += 1 docClassName = "Foo" + changeId val newText = (if (withImport) "import zoo.Zoo; " else "") + s"class $docClassName {\\n }" sb.append( - """PostprocessReformattingAspect.getInstance(getProject()). - | doPostponedFormatting() - |counterBefore = + """counterBefore = | psiManager.modificationTracker.javaStructureModificationCount |""".stripMargin) @@ -214,13 +229,14 @@ case class IndexTestSeq(actions: List[Action]) { |import com.intellij.openapi.fileEditor.FileDocumentManager |import com.intellij.openapi.util.Ref |import com.intellij.openapi.vfs.VfsUtil + |import com.intellij.pom.java.* |import com.intellij.psi.* |import com.intellij.psi.codeStyle.* |import com.intellij.psi.impl.source.* |import com.intellij.psi.search.GlobalSearchScope - |import com.intellij.testFramework.PlatformTestUtil + |import com.intellij.testFramework.* |import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase - |import com.intellij.util.ObjectUtils + |import com.intellij.util.* |import com.intellij.openapi.fileEditor.impl.LoadTextUtil |import org.jetbrains.annotations.NotNull |class DummyTest extends JavaCodeInsightFixtureTestCase { @@ -264,5 +280,7 @@ case object PsiChange extends Action case object InvisiblePsiChange extends Action case object PostponedFormatting extends Action case object Reformat extends Action -case object LoadViewProviderDocument extends Action case object CheckStamps extends Action +case object ForceReloadPsi extends Action +case object AddEnum extends Action +case class ChangeLanguageLevel(highest: Boolean) extends Action \ No newline at end of file From d2506fdbb03a9d4f4a250ea1c713952d21b0d347 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Nov 2014 16:07:51 +0100 Subject: [PATCH 14/38] open only project-related files or dirs by a full path in goto file (IDEA-132824) --- .../navigation/ChooseByNameHddTest.groovy | 15 ++++++++----- .../ide/actions/GotoFileItemProvider.java | 22 ++++++++++++------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameHddTest.groovy b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameHddTest.groovy index 5b3e868ecda0..5aba6a066f02 100644 --- a/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameHddTest.groovy +++ b/java/java-tests/testSrc/com/intellij/navigation/ChooseByNameHddTest.groovy @@ -17,6 +17,7 @@ package com.intellij.navigation import com.intellij.ide.actions.GotoFileItemProvider import com.intellij.ide.util.gotoByName.ChooseByNamePopup import com.intellij.ide.util.gotoByName.GotoFileModel +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.util.io.FileUtil import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase import org.jetbrains.annotations.NotNull @@ -27,12 +28,16 @@ class ChooseByNameHddTest extends JavaCodeInsightFixtureTestCase { public void "test go to file by full path"() { def psiFile = myFixture.addFileToProject("foo/index.html", "foo") - def path = psiFile.virtualFile.path + def vFile = psiFile.virtualFile + def path = vFile.path - def popup = ChooseByNamePopup.createPopup(project, new GotoFileModel(project), new GotoFileItemProvider(project, null)) - assert ChooseByNameTest.calcPopupElements(popup, path) == [psiFile] - assert ChooseByNameTest.calcPopupElements(popup, FileUtil.toSystemDependentName(path)) == [psiFile] - popup.close(false) + ApplicationManager.application.runReadAction { + def popup = ChooseByNamePopup.createPopup(project, new GotoFileModel(project), new GotoFileItemProvider(project, null)) + assert ChooseByNameTest.calcPopupElements(popup, path) == [psiFile] + assert ChooseByNameTest.calcPopupElements(popup, FileUtil.toSystemDependentName(path)) == [psiFile] + assert ChooseByNameTest.calcPopupElements(popup, vFile.parent.path) == [psiFile.containingDirectory] + popup.close(false) + } } @Override diff --git a/platform/lang-impl/src/com/intellij/ide/actions/GotoFileItemProvider.java b/platform/lang-impl/src/com/intellij/ide/actions/GotoFileItemProvider.java index 3a2559b5888d..347abd938690 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/GotoFileItemProvider.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/GotoFileItemProvider.java @@ -19,17 +19,17 @@ import com.intellij.ide.util.gotoByName.ChooseByNameBase; import com.intellij.ide.util.gotoByName.DefaultChooseByNameItemProvider; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.PsiManager; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.File; - /** * @author peter */ @@ -48,11 +48,17 @@ public class GotoFileItemProvider extends DefaultChooseByNameItemProvider { @NotNull ProgressIndicator indicator, @NotNull Processor consumer) { if (pattern.contains("/") || pattern.contains("\\")) { - File ioFile = new File(pattern); - VirtualFile vFile = ioFile.exists() ? LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioFile) : null; - PsiFile psiFile = vFile == null ? null : PsiManager.getInstance(myProject).findFile(vFile); - if (psiFile != null && !consumer.process(psiFile)) { - return false; + VirtualFile vFile = LocalFileSystem.getInstance().findFileByPathIfCached(FileUtil.toSystemIndependentName(pattern)); + if (vFile != null) { + ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(myProject); + if (index.isInContent(vFile) || index.isInLibraryClasses(vFile) || index.isInLibrarySource(vFile)) { + PsiFileSystemItem fileOrDir = vFile.isDirectory() ? + PsiManager.getInstance(myProject).findDirectory(vFile) : + PsiManager.getInstance(myProject).findFile(vFile); + if (fileOrDir != null && !consumer.process(fileOrDir)) { + return false; + } + } } } From 3b6014f74074fc24874cdd156307282c07aca05e Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Nov 2014 16:09:30 +0100 Subject: [PATCH 15/38] fix javadoc typo --- .../com/intellij/codeInsight/InferredAnnotationsManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java b/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java index 9ff366aaa7ce..6c2db7a9b952 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java @@ -24,7 +24,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Returns annotations inferred by bytecode our source code, for example contracts and nullity. + * Returns annotations inferred by bytecode or source code, for example contracts and nullity. * * @see com.intellij.codeInsight.NullableNotNullManager * @see org.jetbrains.annotations.Contract From 507aaad51ea9248ad0d71f18dd1f32bd73d199b2 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Wed, 26 Nov 2014 18:13:35 +0300 Subject: [PATCH 16/38] show file-level annotation for EC instead of notification #WEB-14144 fixed --- .../src/icons/EditorconfigIcons.java | 17 +++ .../src/org/editorconfig/Utils.java | 4 - .../annotations/EditorConfigAnnotator.java | 126 ++++++++++++++++++ .../EditorConfigIndentOptionsProvider.java | 4 - .../EditorSettingsManager.java | 1 - .../configmanagement/EncodingManager.java | 1 - .../configmanagement/LineEndingsManager.java | 1 - .../org/editorconfig/icons/editorconfig.png | Bin 0 -> 584 bytes .../editorconfig/icons/editorconfig@2x.png | Bin 0 -> 1393 bytes .../SettingsProviderComponent.java | 17 ++- 10 files changed, 159 insertions(+), 12 deletions(-) create mode 100644 plugins/editorconfig/src/icons/EditorconfigIcons.java create mode 100644 plugins/editorconfig/src/org/editorconfig/annotations/EditorConfigAnnotator.java create mode 100644 plugins/editorconfig/src/org/editorconfig/icons/editorconfig.png create mode 100644 plugins/editorconfig/src/org/editorconfig/icons/editorconfig@2x.png diff --git a/plugins/editorconfig/src/icons/EditorconfigIcons.java b/plugins/editorconfig/src/icons/EditorconfigIcons.java new file mode 100644 index 000000000000..ff1eb313974c --- /dev/null +++ b/plugins/editorconfig/src/icons/EditorconfigIcons.java @@ -0,0 +1,17 @@ +package icons; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +/** + * NOTE THIS FILE IS AUTO-GENERATED + * DO NOT EDIT IT BY HAND, run build/scripts/icons.gant instead + */ +public class EditorconfigIcons { + private static Icon load(String path) { + return IconLoader.getIcon(path, EditorconfigIcons.class); + } + + public static final Icon Editorconfig = load("/org/editorconfig/icons/editorconfig.png"); // 16x16 +} diff --git a/plugins/editorconfig/src/org/editorconfig/Utils.java b/plugins/editorconfig/src/org/editorconfig/Utils.java index 6781229ce405..1f08a0752f91 100644 --- a/plugins/editorconfig/src/org/editorconfig/Utils.java +++ b/plugins/editorconfig/src/org/editorconfig/Utils.java @@ -27,10 +27,6 @@ public class Utils { EditorConfigNotifier.getInstance().error(project, configValue, "\"" + configValue + "\" is not a valid value" + (!configKey.isEmpty() ? " for " + configKey : "") + " for file " + filePath); } - public static void appliedConfigMessage(Project project, String configValue, String configKey, String filePath) { - EditorConfigNotifier.getInstance().info(project, "Applied .editorconfig settings"); - } - public static String getFilePath(Project project, VirtualFile file) { if (!file.isInLocalFileSystem()) { return project.getBasePath() + "/" + file.getNameWithoutExtension() + "." + file.getFileType().getDefaultExtension(); diff --git a/plugins/editorconfig/src/org/editorconfig/annotations/EditorConfigAnnotator.java b/plugins/editorconfig/src/org/editorconfig/annotations/EditorConfigAnnotator.java new file mode 100644 index 000000000000..c4c9eab1a4b1 --- /dev/null +++ b/plugins/editorconfig/src/org/editorconfig/annotations/EditorConfigAnnotator.java @@ -0,0 +1,126 @@ +package org.editorconfig.annotations; + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.lang.annotation.Annotation; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.markup.GutterIconRenderer; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ObjectUtils; +import icons.EditorconfigIcons; +import org.editorconfig.Utils; +import org.editorconfig.core.EditorConfig; +import org.editorconfig.plugincomponents.SettingsProviderComponent; +import org.editorconfig.settings.EditorConfigSettings; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.List; + +/** + * @author Dennis.Ushakov + */ +public class EditorConfigAnnotator implements Annotator { + private static final String EDITOR_CONFIG_ACCEPTED = "editor.config.accepted"; + + @Override + public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { + PsiFile file = ObjectUtils.tryCast(element, PsiFile.class); + if (file == null) { + return; + } + final Project project = file.getProject(); + final CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(project).getCurrentSettings(); + if (!Utils.isEnabled(settings) || PropertiesComponent.getInstance(project).getBoolean(EDITOR_CONFIG_ACCEPTED, false)) return; + final List pairs = SettingsProviderComponent.getInstance().getOutPairs(project, Utils.getFilePath(project, file.getVirtualFile())); + if (!pairs.isEmpty()) { + final Annotation annotation = holder.createInfoAnnotation(file, "EditorConfig is overriding Code Style settings for this file"); + annotation.setFileLevelAnnotation(true); + annotation.setGutterIconRenderer(new MyGutterIconRenderer()); + annotation.registerFix(new IntentionAction() { + @NotNull + @Override + public String getText() { + return "Disable EditorConfig support"; + } + + @NotNull + @Override + public String getFamilyName() { + return "EditorConfig"; + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return true; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + settings.getCustomSettings(EditorConfigSettings.class).ENABLED = false; + DaemonCodeAnalyzer.getInstance(project).restart(); + } + + @Override + public boolean startInWriteAction() { + return false; + } + }); + annotation.registerFix(new IntentionAction() { + @NotNull + @Override + public String getText() { + return "Dismiss"; + } + + @NotNull + @Override + public String getFamilyName() { + return "EditorConfig"; + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return false; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + PropertiesComponent.getInstance(project).setValue(EDITOR_CONFIG_ACCEPTED, "true"); + DaemonCodeAnalyzer.getInstance(project).restart(); + } + + @Override + public boolean startInWriteAction() { + return false; + } + }); + } + } + + private static class MyGutterIconRenderer extends GutterIconRenderer { + @NotNull + @Override + public Icon getIcon() { + return EditorconfigIcons.Editorconfig; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MyGutterIconRenderer; + } + + @Override + public int hashCode() { + return EditorconfigIcons.Editorconfig.hashCode(); + } + } +} diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigIndentOptionsProvider.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigIndentOptionsProvider.java index 273b11e223d2..756377d2e4aa 100644 --- a/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigIndentOptionsProvider.java +++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorConfigIndentOptionsProvider.java @@ -66,7 +66,6 @@ public class EditorConfigIndentOptionsProvider extends FileIndentOptionsProvider final String calculatedTabWidth = calculateTabWidth(tabWidth, indentSize); if (!calculatedIndentSize.isEmpty()) { if (applyIndentSize(indentOptions, calculatedIndentSize)) { - Utils.appliedConfigMessage(project, calculatedIndentSize, indentSizeKey, filePath); changed = true; } else { Utils.invalidConfigMessage(project, calculatedIndentSize, indentSizeKey, filePath); @@ -74,7 +73,6 @@ public class EditorConfigIndentOptionsProvider extends FileIndentOptionsProvider } if (!calculatedContinuationSize.isEmpty()) { if (applyContinuationIndentSize(indentOptions, calculatedContinuationSize)) { - Utils.appliedConfigMessage(project, calculatedContinuationSize, continuationSizeKey, filePath); changed = true; } else { @@ -83,7 +81,6 @@ public class EditorConfigIndentOptionsProvider extends FileIndentOptionsProvider } if (!calculatedTabWidth.isEmpty()) { if (applyTabWidth(indentOptions, calculatedTabWidth)) { - Utils.appliedConfigMessage(project, calculatedTabWidth, tabWidthKey, filePath); changed = true; } else { @@ -92,7 +89,6 @@ public class EditorConfigIndentOptionsProvider extends FileIndentOptionsProvider } if (!indentStyle.isEmpty()) { if (applyIndentStyle(indentOptions, indentStyle)) { - Utils.appliedConfigMessage(project, indentStyle, indentStyleKey, filePath); changed = true; } else { diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorSettingsManager.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorSettingsManager.java index 25cf2d046585..0e4c06929f68 100644 --- a/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorSettingsManager.java +++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/EditorSettingsManager.java @@ -84,7 +84,6 @@ public class EditorSettingsManager extends FileDocumentManagerAdapter { } else { file.putUserData(userDataKey, data); - Utils.appliedConfigMessage(myProject, configValue, editorConfigKey, file.getCanonicalPath()); } } } diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/EncodingManager.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/EncodingManager.java index 8a744f5ff0df..278b684e10d2 100644 --- a/plugins/editorconfig/src/org/editorconfig/configmanagement/EncodingManager.java +++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/EncodingManager.java @@ -67,7 +67,6 @@ public class EncodingManager extends FileDocumentManagerAdapter { if (newCharset != null) { if (Comparing.equal(newCharset, file.getCharset())) return; encodingProjectManager.setEncoding(file, newCharset); - Utils.appliedConfigMessage(myProject, charset, charsetKey, filePath); } else { Utils.invalidConfigMessage(myProject, charset, charsetKey, filePath); } diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/LineEndingsManager.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/LineEndingsManager.java index 03896aa5aaa4..a65d00796699 100644 --- a/plugins/editorconfig/src/org/editorconfig/configmanagement/LineEndingsManager.java +++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/LineEndingsManager.java @@ -84,7 +84,6 @@ public class LineEndingsManager extends FileDocumentManagerAdapter { statusBarUpdated = true; updateStatusBar(); } - Utils.appliedConfigMessage(myProject, lineEndings, lineEndingsKey, filePath); } } catch (IllegalArgumentException e) { diff --git a/plugins/editorconfig/src/org/editorconfig/icons/editorconfig.png b/plugins/editorconfig/src/org/editorconfig/icons/editorconfig.png new file mode 100644 index 0000000000000000000000000000000000000000..636d757dbc42f9fd196bfb4da38ce3f2cafc2021 GIT binary patch literal 584 zcmV-O0=NB%P)*&YAN+KR^G7udlBNNd~yPyO*ChaNs`( zoIi2me`;##R8k$G6%`Tj`NHwz|IeR1`M)SX{}oV77?)x$AZCSeL_|bdBM;lX`pq$HvCOHT?Vc4~${p!Gj0?t*opz1GQ=cF(ZSa zp<&3a3m5+X|NHm<|6jlUUpaN^{|aEpBZEJG{``OQ=FR_Q%a;GYe*MP(6)RT!0cx&+ zd6_LHGIGMTix(lz?z{aPVkuY&=j|QgXJxzyCKV3_g7L@PFpa*?%tpU3lZhjsLG+z50Lq z_HD3uUtixj}lV2c2CnJ*;|XedGltk9XodX5g8eY*w|RapE`xzyLUI!Bfqx-z{|@k zGc`38ML9W8=H=mJTpUtTQXrSh)wZ^_Vxt4_^Yi;jo}3KL!~~$zVNtC{+PQPc%F04U zM#eBL`N*gMJUl#NPgB}ETUxZxXn@&SU~v(@D3wqs6!7==SJJX~jEUh(nM|go)a#y2 zPQC!ZK0l8#rBWLn9q$^f)lXlG`SdiE?lM51_OQz6dN z(-R5t@%Z7)8Js+J4Bs6-jO5d&5q;zcwrtr_ZH%C%wD_92`V*b2DzxHzIl$1asks>rS6djbE-rimW2L~fNJ6pK(n3$vR_1!7x1p{M|N~Z2yaI^D2hiQ!E&S%w^L?{*c6Oq; zScPlXuAz~7#e)YA1a9owwQH2(IISm4AKTm87rVK-j<~tGRZ|uG#-vI}NWjR*$Vy5X zNMz(Un)deg#YxH(gHv<$tYMj%nS2cg)&sy=A4mQH{~$2mbDCRPT5$RDWef}qU}|bg zAl&%)xUQ+Gi6^0z)2~$_ZEbCQ4f*Q<;K1H`zny)3eTSKNJv}{w#+R0sqP)CZxNqhJ zr`Ql_o*+`YySv}#cD~Ur_|@^_$8~F^*HDq#w{PEb+V7K%_hD1h48FtVjSQ9KmjNvC zAmHE30w%0vG;XPfhle+Ga((e)&d_0wzRpncIaNo)g$oy$ga)_f(b3TtdXSU^8ylO8 zuR9sBn#s0r-`>OD16&!a@qvwqstc1!kw}xY7mab|=H@wXY&azkcXoE};*9Xsuxh?+ zMKr3(X~sw;u*?Dacu9NHvm%dh5}KN-N$vV+R#YcZs#PkL(3GmGs)Uj~apDAge0-*9 zZJ;ryWgBwOC8o2W{Yaif9!l=d-!=c4&+EScNfZvdFt4D000000NkvXXu0mjfUI(rp literal 0 HcmV?d00001 diff --git a/plugins/editorconfig/src/org/editorconfig/plugincomponents/SettingsProviderComponent.java b/plugins/editorconfig/src/org/editorconfig/plugincomponents/SettingsProviderComponent.java index d35a216d0b9d..feeebb8de1c0 100644 --- a/plugins/editorconfig/src/org/editorconfig/plugincomponents/SettingsProviderComponent.java +++ b/plugins/editorconfig/src/org/editorconfig/plugincomponents/SettingsProviderComponent.java @@ -1,7 +1,11 @@ package org.editorconfig.plugincomponents; +import com.intellij.lang.LanguageAnnotators; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeManager; +import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; @@ -13,6 +17,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import org.editorconfig.Utils; +import org.editorconfig.annotations.EditorConfigAnnotator; import org.editorconfig.core.EditorConfig; import org.editorconfig.core.EditorConfig.OutPair; import org.editorconfig.core.EditorConfigException; @@ -24,8 +29,18 @@ import java.util.*; public class SettingsProviderComponent implements ApplicationComponent { private EditorConfig editorConfig; - public SettingsProviderComponent() { + public SettingsProviderComponent(FileTypeManager manager) { editorConfig = new EditorConfig(); + registerAnnotator(manager); + } + + public void registerAnnotator(FileTypeManager manager) { + final EditorConfigAnnotator annotator = new EditorConfigAnnotator(); + for (FileType type : manager.getRegisteredFileTypes()) { + if (type instanceof LanguageFileType) { + LanguageAnnotators.INSTANCE.addExplicitExtension(((LanguageFileType)type).getLanguage(), annotator); + } + } } public static SettingsProviderComponent getInstance() { From 3ec9dad76aeaa854375856df4700c9178c781b64 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 26 Nov 2014 16:06:55 +0300 Subject: [PATCH 17/38] cleanup --- .../intellij/compiler/impl/CompilerEncodingServiceImpl.java | 3 ++- .../openapi/vfs/encoding/ChooseFileEncodingAction.java | 6 +++--- .../src/com/intellij/util/containers/ContainerUtil.java | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerEncodingServiceImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerEncodingServiceImpl.java index 34a49096f894..462a73375d3d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerEncodingServiceImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerEncodingServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,6 +60,7 @@ public class CompilerEncodingServiceImpl extends CompilerEncodingService { }, false); } + @NotNull private Map> computeModuleCharsetMap() { final Map> map = new THashMap>(); final Map mappings = EncodingProjectManager.getInstance(myProject).getAllMappings(); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChooseFileEncodingAction.java b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChooseFileEncodingAction.java index 9996800765e5..19d836c480a6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChooseFileEncodingAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/encoding/ChooseFileEncodingAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -68,7 +68,7 @@ public abstract class ChooseFileEncodingAction extends ComboBoxAction { } @Override - public void update(AnActionEvent e) { + public void update(@NotNull AnActionEvent e) { } @Override @@ -89,7 +89,7 @@ public abstract class ChooseFileEncodingAction extends ComboBoxAction { } @Override - public void actionPerformed(final AnActionEvent e) { + public void actionPerformed(@NotNull final AnActionEvent e) { chosen(myFile, NO_ENCODING); } } diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java index 3cb42e33ec47..8a43e245aa14 100644 --- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java +++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java @@ -1426,8 +1426,8 @@ public class ContainerUtil extends ContainerUtilRt { } @Contract(pure=true) - public static T getFirstItem(@Nullable final Collection items, @Nullable final T def) { - return items == null || items.isEmpty() ? def : items.iterator().next(); + public static T getFirstItem(@Nullable final Collection items, @Nullable final T defaultResult) { + return items == null || items.isEmpty() ? defaultResult : items.iterator().next(); } /** From aec89e5351429f7a9d0cb870214dcdd82977c52d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 26 Nov 2014 17:13:00 +0300 Subject: [PATCH 18/38] negative start offset exception --- .../src/com/intellij/usages/UsageInfo2UsageAdapter.java | 6 +++--- platform/util/src/com/intellij/openapi/util/TextRange.java | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java index 71227bd4c64a..c5d758fd0eb7 100644 --- a/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java +++ b/platform/usageView/src/com/intellij/usages/UsageInfo2UsageAdapter.java @@ -242,12 +242,12 @@ public class UsageInfo2UsageAdapter implements UsageInModule, return canNavigate(); } - @Nullable private OpenFileDescriptor getDescriptor() { VirtualFile file = getFile(); if(file == null) return null; Segment range = getNavigationRange(); - if (range != null && file instanceof VirtualFileWindow) { + if (range != null && file instanceof VirtualFileWindow && range.getStartOffset() >= 0) { + // have to use injectedToHost(TextRange) to calculate right offset in case of multiple shreds range = ((VirtualFileWindow)file).getDocumentWindow().injectedToHost(TextRange.create(range)); file = ((VirtualFileWindow)file).getDelegate(); } @@ -272,7 +272,7 @@ public class UsageInfo2UsageAdapter implements UsageInModule, Segment range = getUsageInfo().getNavigationRange(); if (range == null) { ProperTextRange rangeInElement = getUsageInfo().getRangeInElement(); - range = rangeInElement == null ? TextRange.from(myOffset,1) : rangeInElement.shiftRight(myOffset); + range = myOffset < 0 ? new UnfairTextRange(-1,-1) : rangeInElement == null ? TextRange.from(myOffset,1) : rangeInElement.shiftRight(myOffset); } if (range.getEndOffset() >= document.getTextLength()) { int line = Math.max(0, Math.min(myLineNumber, document.getLineCount() - 1)); diff --git a/platform/util/src/com/intellij/openapi/util/TextRange.java b/platform/util/src/com/intellij/openapi/util/TextRange.java index 4c09b969a570..30240b539051 100644 --- a/platform/util/src/com/intellij/openapi/util/TextRange.java +++ b/platform/util/src/com/intellij/openapi/util/TextRange.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,12 +58,14 @@ public class TextRange implements Segment, Serializable { return myEndOffset - myStartOffset; } + @Override public boolean equals(Object obj) { if (!(obj instanceof TextRange)) return false; TextRange range = (TextRange)obj; return myStartOffset == range.myStartOffset && myEndOffset == range.myEndOffset; } + @Override public int hashCode() { return myStartOffset + myEndOffset; } @@ -80,6 +82,7 @@ public class TextRange implements Segment, Serializable { return myStartOffset <= offset && offset <= myEndOffset; } + @Override public String toString() { return "(" + myStartOffset + "," + myEndOffset + ")"; } From 8fa8648369eb6a3aa83befda0d3cdbc15f6439e0 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 26 Nov 2014 18:13:27 +0300 Subject: [PATCH 19/38] made public for upsource --- .../src/com/intellij/psi/impl/PsiDocumentManagerBase.java | 5 +++-- .../src/com/intellij/openapi/util/objectTree/ObjectTree.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java index bdc83f8098cb..4d7b44b8e7f7 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiDocumentManagerBase.java @@ -282,7 +282,8 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen } } - boolean finishCommit(@NotNull final Document document, + // public for Upsource + public boolean finishCommit(@NotNull final Document document, @NotNull final List> finishProcessors, final boolean synchronously, @NotNull final Object reason) { @@ -363,7 +364,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen } } - private void doCommit(@NotNull final Document document) { + protected void doCommit(@NotNull final Document document) { assert !myIsCommitInProgress : "Do not call commitDocument() from inside PSI change listener"; ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override diff --git a/platform/util/src/com/intellij/openapi/util/objectTree/ObjectTree.java b/platform/util/src/com/intellij/openapi/util/objectTree/ObjectTree.java index 3d31f3b771a4..11212543a1d2 100644 --- a/platform/util/src/com/intellij/openapi/util/objectTree/ObjectTree.java +++ b/platform/util/src/com/intellij/openapi/util/objectTree/ObjectTree.java @@ -181,7 +181,8 @@ public final class ObjectTree { } @TestOnly - void assertNoReferenceKeptInTree(@NotNull T disposable) { + // public for Upsource + public void assertNoReferenceKeptInTree(@NotNull T disposable) { synchronized (treeLock) { Collection> nodes = myObject2NodeMap.values(); for (ObjectNode node : nodes) { From 6f8bc227749cd44b2d3e258230d1ef89095865a3 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 26 Nov 2014 18:26:46 +0300 Subject: [PATCH 20/38] moved to core --- .../com/intellij/openapi/application/ApplicationAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename platform/{platform-api => core-api}/src/com/intellij/openapi/application/ApplicationAdapter.java (96%) diff --git a/platform/platform-api/src/com/intellij/openapi/application/ApplicationAdapter.java b/platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java similarity index 96% rename from platform/platform-api/src/com/intellij/openapi/application/ApplicationAdapter.java rename to platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java index ddeaa8c6bcbd..3c3f509ebecb 100644 --- a/platform/platform-api/src/com/intellij/openapi/application/ApplicationAdapter.java +++ b/platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 0f893b25ad0cf9dc9a5d9c029e9f36604af07036 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Wed, 26 Nov 2014 19:00:20 +0300 Subject: [PATCH 21/38] enable dismiss fix --- .../src/org/editorconfig/annotations/EditorConfigAnnotator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/editorconfig/src/org/editorconfig/annotations/EditorConfigAnnotator.java b/plugins/editorconfig/src/org/editorconfig/annotations/EditorConfigAnnotator.java index c4c9eab1a4b1..7df46185c4f2 100644 --- a/plugins/editorconfig/src/org/editorconfig/annotations/EditorConfigAnnotator.java +++ b/plugins/editorconfig/src/org/editorconfig/annotations/EditorConfigAnnotator.java @@ -89,7 +89,7 @@ public class EditorConfigAnnotator implements Annotator { @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - return false; + return true; } @Override From d42ee7a7700bcf3db4deea152b73680184ae6d7d Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 26 Nov 2014 17:17:38 +0100 Subject: [PATCH 22/38] platform: update check diagnostic; test cleanup --- .../updateSettings/impl/PluginDownloader.java | 1 + .../updateSettings/impl/UpdateChecker.java | 7 +++-- .../com/intellij/util/io/HttpRequests.java | 2 +- .../src/messages/IdeBundle.properties | 1 + .../intellij/util/io/HttpRequestsTest.java | 31 ++++++------------- 5 files changed, 17 insertions(+), 25 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java index ed34961d8b30..f346e321f302 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java @@ -113,6 +113,7 @@ public class PluginDownloader { } catch (IOException ex) { myFile = null; + LOG.warn(ex); errorMessage = ex.getMessage(); } if (myFile == null) { diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index fa58f145f771..12d5708f9f78 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -157,9 +157,9 @@ public final class UpdateChecker { settings.setKnownChannelIds(result.getAllChannelsIds()); } else if (result.getState() == UpdateStrategy.State.CONNECTION_ERROR) { - //noinspection ThrowableResultOfMethodCallIgnored - showErrorMessage(manualCheck, - result.getError() instanceof InterruptedIOException ? IdeBundle.message("updates.timeout.error") : IdeBundle.message("updates.error.connection.failed")); + Exception e = result.getError(); + if (e != null) LOG.warn(e); + showErrorMessage(manualCheck, IdeBundle.message(e instanceof InterruptedIOException ? "updates.timeout.error" : "updates.error.connection.failed")); return; } @@ -250,6 +250,7 @@ public final class UpdateChecker { return null; } catch (Exception e) { + LOG.warn(e); showErrorMessage(manualCheck, e.getMessage()); } } diff --git a/platform/platform-impl/src/com/intellij/util/io/HttpRequests.java b/platform/platform-impl/src/com/intellij/util/io/HttpRequests.java index 3ba14daca800..412f22741e42 100644 --- a/platform/platform-impl/src/com/intellij/util/io/HttpRequests.java +++ b/platform/platform-impl/src/com/intellij/util/io/HttpRequests.java @@ -190,6 +190,6 @@ public final class HttpRequests { return connection; } - throw new IOException("Too many redirects"); + throw new IOException(IdeBundle.message("error.connection.failed.redirects")); } } \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 842ae3c5c1f1..7442f86d09fd 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -534,6 +534,7 @@ progress.waiting.for.reply.from.plugin.manager=Waiting for reply from {0} progress.downloading.plugin=Downloading plugin ''{0}'' error.cannot.create.temp.dir=Unable to create temp directory ''{0}'' error.connection.failed.with.http.code.N=Connection failed with HTTP code {0} +error.connection.failed.redirects=Connection failed: too many redirects progress.connecting.to.plugin.manager=Connecting to {0} label.plugin.vendor.email=E-mail: label.plugin.vendor.name=Name: diff --git a/platform/platform-tests/testSrc/com/intellij/util/io/HttpRequestsTest.java b/platform/platform-tests/testSrc/com/intellij/util/io/HttpRequestsTest.java index 2a68a2c98e50..682b646a53e8 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/io/HttpRequestsTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/io/HttpRequestsTest.java @@ -15,6 +15,7 @@ */ package com.intellij.util.io; +import com.intellij.ide.IdeBundle; import org.jetbrains.annotations.NotNull; import org.junit.Test; @@ -41,31 +42,19 @@ public class HttpRequestsTest { fail(); } catch (IOException e) { - assertEquals("Too many redirects", e.getMessage()); + assertEquals(IdeBundle.message("error.connection.failed.redirects"), e.getMessage()); } } - @Test - public void testConnectTimeout() { - try { - HttpRequests.request("http://openjdk.java.net").connectTimeout(1).connect(myProcessor); - fail(); - } - catch (SocketTimeoutException ignore) { } - catch (IOException e) { - fail(e.getMessage()); - } + @Test(timeout = 5000, expected = SocketTimeoutException.class) + public void testConnectTimeout() throws IOException { + HttpRequests.request("http://openjdk.java.net").connectTimeout(1).connect(myProcessor); + fail(); } - @Test - public void testReadTimeout() { - try { - HttpRequests.request("http://openjdk.java.net").readTimeout(1).connect(myProcessor); - fail(); - } - catch (SocketTimeoutException ignore) { } - catch (IOException e) { - fail(e.getMessage()); - } + @Test(timeout = 5000, expected = SocketTimeoutException.class) + public void testReadTimeout() throws IOException { + HttpRequests.request("http://openjdk.java.net").readTimeout(1).connect(myProcessor); + fail(); } } From f852923268232d2440c5aa0a0c382cec8c03a1b3 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 26 Nov 2014 19:31:33 +0300 Subject: [PATCH 23/38] IDEA-111466 Mac OS X keyboard shortcuts with alt don't work under Oracle Java 7 (allow to assign Alt+Key via Keymap settings) --- .../intellij/openapi/keymap/impl/ui/ShortcutTextField.java | 7 +++++++ platform/util/resources/misc/registry.properties | 1 + 2 files changed, 8 insertions(+) diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutTextField.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutTextField.java index bc050403177a..700a27acb0a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutTextField.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutTextField.java @@ -22,6 +22,8 @@ */ package com.intellij.openapi.keymap.impl.ui; +import com.intellij.openapi.util.registry.Registry; + import javax.swing.*; import java.awt.event.KeyEvent; @@ -62,4 +64,9 @@ public class ShortcutTextField extends JTextField { public KeyStroke getKeyStroke() { return myKeyStroke; } + + @Override + public void enableInputMethods(boolean enable) { + super.enableInputMethods(enable && Registry.is("ide.settings.keymap.input.method.enabled")); + } } \ No newline at end of file diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index b6b6da2d28e9..bfbcb49e83ce 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -450,6 +450,7 @@ console.too.much.text.buffer.ratio.description=Used for disabling of console pro The ratio is used against the console cycle buffer size (idea.cycle.buffer.size/theRatio=maxTextLength). ide.settings.appearance.font.family.only=true +ide.settings.keymap.input.method.enabled=false ide.settings.old.style=true ide.new.settings.view=true ide.new.settings.view.description=New view for the Settings dialog From 68cc2ec0a25b76768a27a96ccd1541b3c8485e20 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 26 Nov 2014 13:36:00 +0100 Subject: [PATCH 24/38] method refs: mark as potentially incompatible expression based reference of non-static method with incorrect number of parameters; contradict spec (15.12.2.1) --- .../intellij/psi/PsiMethodReferenceUtil.java | 2 +- .../PsiMethodReferenceExpressionImpl.java | 9 +++-- ...otentialCompatibilityWithInvalidShape.java | 40 +++++++++++++++++++ .../lambda/NewMethodRefHighlightingTest.java | 4 ++ 4 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialCompatibilityWithInvalidShape.java diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java index abe12f445a38..3347d8319c53 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java @@ -178,7 +178,7 @@ public class PsiMethodReferenceUtil { PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type); containingClass = result.getElement(); if (containingClass != null) { - substitutor = result.getSubstitutor(); + return new QualifierResolveResult(containingClass, result.getSubstitutor(), true); } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java index 6484898731f7..a9ba1bbaa5b0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java @@ -97,8 +97,8 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase final PsiElement element = resolveResult.getElement(); if (element instanceof PsiMethod) { final boolean isStatic = ((PsiMethod)element).hasModifierProperty(PsiModifier.STATIC); + final int parametersCount = ((PsiMethod)element).getParameterList().getParametersCount(); if (qualifierResolveResult.isReferenceTypeQualified() && getReferenceNameElement() instanceof PsiIdentifier) { - final int parametersCount = ((PsiMethod)element).getParameterList().getParametersCount(); if (parametersCount == interfaceArity && isStatic) { return true; } @@ -106,8 +106,11 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase return true; } if (((PsiMethod)element).isVarArgs()) return true; - } else if (!isStatic) { - return true; + } + else if (!isStatic) { + if (parametersCount == interfaceArity || ((PsiMethod)element).isVarArgs()) { + return true; + } } } else if (element instanceof PsiClass) { return true; diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialCompatibilityWithInvalidShape.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialCompatibilityWithInvalidShape.java new file mode 100644 index 000000000000..3cfa72c6ee2e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/PotentialCompatibilityWithInvalidShape.java @@ -0,0 +1,40 @@ +import java.util.List; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.function.Function; +class Test { + private List query(String request) { + System.out.println(request); + return null; + } + private List query(String request, Object context) { + System.out.println(request + context); + return null; + } + + private List query1(){ return null;} + private List query1(String request) { + System.out.println(request); + return null; + } + private List query1(String request, Object context) { + System.out.println(request + context); + return null; + } + + private static Set replyWith(Function> futureFn){ + System.out.println(futureFn); + return null; + } + private static Set replyWith(Callable> fn) { + System.out.println(fn); + return null; + } + + { + Set m = replyWith(this::query); + System.out.println(m); + Set m1 = replyWith(this::query1); + System.out.println(m1); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java index 46d8e65308a9..d8b949ec87ba 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java @@ -334,6 +334,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(true); } + public void testPotentialCompatibilityWithInvalidShape() throws Exception { + doTest(true); + } + private void doTest() { doTest(false); } From 4d7d73e3688b8ae296df9b518a3ec9ecee8a1050 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 26 Nov 2014 17:34:31 +0100 Subject: [PATCH 25/38] only those sources associated with generated classes are considered "changed", that were compiled on the current round --- .../java/dependencyView/Mappings.java | 83 ++++++++++--------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java index c17bba46eb92..0de487375e1d 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java @@ -101,7 +101,7 @@ public class Mappings { myLock = base.myLock; myIsDelta = true; myChangedClasses = new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); - myChangedFiles = new THashSet(FileUtil.FILE_HASHING_STRATEGY); + myChangedFiles = new THashSet(FileUtil.FILE_HASHING_STRATEGY); myDeletedClasses = new HashSet>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); myAddedClasses = new HashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR); myDeltaIsTransient = base.myDeltaIsTransient; @@ -2003,51 +2003,60 @@ public class Mappings { debug("Begin of Differentiate:"); debug("Easy mode: ", myEasyMode); - processDisappearedClasses(); + try { + processDisappearedClasses(); - final List newClasses = new ArrayList(); - myDelta.mySourceFileToClasses.forEachEntry(new TObjectObjectProcedure>() { - @Override - public boolean execute(File fileName, Collection classes) { - newClasses.add(new FileClasses(fileName, classes)); - return true; - } - }); + final List newClasses = new ArrayList(); + myDelta.mySourceFileToClasses.forEachEntry(new TObjectObjectProcedure>() { + @Override + public boolean execute(File fileName, Collection classes) { + newClasses.add(new FileClasses(fileName, classes)); + return true; + } + }); - for (final FileClasses compiledFile : newClasses) { - final File fileName = compiledFile.myFileName; - final Set classes = compiledFile.myFileClasses; - final Set pastClasses = (Set)mySourceFileToClasses.get(fileName); - final DiffState state = new DiffState(Difference.make(pastClasses, classes)); - - if (!processChangedClasses(state)) { + for (final FileClasses compiledFile : newClasses) { + final File fileName = compiledFile.myFileName; + final Set classes = compiledFile.myFileClasses; + final Set pastClasses = (Set)mySourceFileToClasses.get(fileName); + final DiffState state = new DiffState(Difference.make(pastClasses, classes)); + + if (!processChangedClasses(state)) { + if (!myEasyMode) { + // turning non-incremental + return false; + } + } + + processRemovedClases(state, fileName); + processAddedClasses(state, fileName); + if (!myEasyMode) { - // turning non-incremental - return false; + calculateAffectedFiles(state); } } - processRemovedClases(state, fileName); - processAddedClasses(state, fileName); + debug("End of Differentiate."); - if (!myEasyMode) { - calculateAffectedFiles(state); + if (myEasyMode) { + return false; + } + + final Collection removed = myDelta.myRemovedFiles; + if (removed != null) { + for (final String r : removed) { + myAffectedFiles.remove(new File(r)); + } + } + return myDelayedWorks.doWork(myAffectedFiles); + } + finally { + if (myFilesToCompile != null) { + // if some class is associated with several sources, + // some of them may not have been compiled in this round, so such files should be considered unchanged + myDelta.myChangedFiles.retainAll(myFilesToCompile); } } - - debug("End of Differentiate."); - - if (myEasyMode) { - return false; - } - - final Collection removed = myDelta.myRemovedFiles; - if (removed != null) { - for (final String r : removed) { - myAffectedFiles.remove(new File(r)); - } - } - return myDelayedWorks.doWork(myAffectedFiles); } } } From 145f701bc1e398bfa950722adc822043b7d1d3b2 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 26 Nov 2014 17:35:45 +0100 Subject: [PATCH 26/38] new overload resolution: integrate isPotentiallyCompatible in isApplicable checks --- .../src/com/intellij/psi/LambdaUtil.java | 26 ++++ .../com/intellij/psi/PsiLambdaExpression.java | 2 - .../intellij/psi/util/TypeConversionUtil.java | 2 +- .../tree/java/PsiLambdaExpressionImpl.java | 134 ++++++++++-------- .../PsiMethodReferenceExpressionImpl.java | 16 ++- .../JavaMethodsConflictResolver.java | 61 +------- .../AmbiguityReturnValueResolution2.java | 2 +- .../highlighting/ConflictResolution.java | 2 +- .../highlighting/ReturnTypeCompatibility.java | 4 +- .../ReturnTypeCompatibility1.java | 6 +- .../lambda/overloadResolution/IDEA102800.java | 2 +- ...oApplicabilityOfExplicitlyTypedLambda.java | 2 +- ...eCompatibilityOfImplicitlyTypedLambda.java | 4 +- .../lambda/params/MethodApplicability.java | 6 +- .../lambda/MostSpecificResolutionTest.java | 5 +- .../util/resources/misc/registry.properties | 5 +- 16 files changed, 140 insertions(+), 139 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 820d9bccd36e..7f707200d6c6 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -18,6 +18,7 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.registry.Registry; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.util.*; @@ -493,6 +494,31 @@ public class LambdaUtil { return expression; } + // http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1 + // A lambda expression or a method reference expression is potentially compatible with a type variable + // if the type variable is a type parameter of the candidate method. + public static boolean isPotentiallyCompatibleWithTypeParameter(PsiFunctionalExpression expression, + PsiExpressionList argsList, + PsiMethod method) { + if (!Registry.is("JDK8042508.bug.fixed", false)) { + final PsiCallExpression callExpression = PsiTreeUtil.getParentOfType(argsList, PsiCallExpression.class); + if (callExpression == null || callExpression.getTypeArguments().length > 0) { + return false; + } + } + + final int lambdaIdx = getLambdaIdx(argsList, expression); + if (lambdaIdx >= 0) { + final PsiParameter[] parameters = method.getParameterList().getParameters(); + final PsiParameter lambdaParameter = parameters[Math.min(lambdaIdx, parameters.length - 1)]; + final PsiClass paramClass = PsiUtil.resolveClassInType(lambdaParameter.getType()); + if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) { + return true; + } + } + return false; + } + public static class TypeParamsChecker extends PsiTypeVisitor { private PsiMethod myMethod; private final PsiClass myClass; diff --git a/java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java b/java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java index a59d1e50f35e..459b9d176af9 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java @@ -46,6 +46,4 @@ public interface PsiLambdaExpression extends PsiFunctionalExpression { * @return true when lambda declares parameter types explicitly */ boolean hasFormalParameterTypes(); - - boolean isAcceptable(PsiType leftType, boolean checkReturnType); } diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java index 1041b9fa1c71..3213970cc260 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java @@ -731,7 +731,7 @@ public class TypeConversionUtil { final PsiType lType = lLambdaExpression.getFunctionalInterfaceType(); return Comparing.equal(rType, lType); } - return !(left instanceof PsiArrayType) && rLambdaExpression.isAcceptable(left, false); + return !(left instanceof PsiArrayType) && rLambdaExpression.isAcceptable(left); } if (left instanceof PsiIntersectionType) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java index 738b835a527d..25151190b2f1 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java @@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.icons.AllIcons; import com.intellij.lang.ASTNode; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.controlFlow.*; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil; @@ -34,6 +33,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.HashMap; +import java.util.Map; public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements PsiLambdaExpression { @@ -168,35 +169,35 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi } @Override - public boolean isAcceptable(PsiType left) { - return isAcceptable(left, false); - } - - @Override - public boolean isAcceptable(PsiType leftType, boolean checkReturnType) { + public boolean isAcceptable(PsiType leftType) { if (leftType instanceof PsiIntersectionType) { for (PsiType conjunctType : ((PsiIntersectionType)leftType).getConjuncts()) { - if (isAcceptable(conjunctType, checkReturnType)) return true; + if (isAcceptable(conjunctType)) return true; } return false; } - final PsiElement argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class); - if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) { - if (!hasFormalParameterTypes()) { - return true; - } - final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList); - if (candidateProperties != null && !InferenceSession.isPertinentToApplicability(this, candidateProperties.getMethod())) { - return true; - } - } + final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class); leftType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(leftType, this); final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(leftType); final PsiClass psiClass = resolveResult.getElement(); if (psiClass instanceof PsiAnonymousClass) { - return isAcceptable(((PsiAnonymousClass)psiClass).getBaseClassType(), checkReturnType); + return isAcceptable(((PsiAnonymousClass)psiClass).getBaseClassType()); + } + + if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) { + final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList); + if (candidateProperties != null) { + final PsiMethod method = candidateProperties.getMethod(); + if (!InferenceSession.isPertinentToApplicability(this, method) && hasFormalParameterTypes()) { + return true; + } + + if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) { + return true; + } + } } final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult); @@ -206,56 +207,77 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, resolveResult); assert leftType != null; - final PsiParameter[] lambdaParameters = getParameterList().getParameters(); - final PsiType[] parameterTypes = interfaceMethod.getSignature(substitutor).getParameterTypes(); - if (lambdaParameters.length != parameterTypes.length) return false; + if (!isPotentiallyCompatible(leftType)) { + return false; + } - for (int lambdaParamIdx = 0, length = lambdaParameters.length; lambdaParamIdx < length; lambdaParamIdx++) { - PsiParameter parameter = lambdaParameters[lambdaParamIdx]; - final PsiTypeElement typeElement = parameter.getTypeElement(); - if (typeElement != null) { - final PsiType lambdaFormalType = toArray(typeElement.getType()); - final PsiType methodParameterType = toArray(parameterTypes[lambdaParamIdx]); - if (!lambdaFormalType.equals(methodParameterType)) { - return false; + if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList) && !hasFormalParameterTypes()) { + return true; + } + + + + if (hasFormalParameterTypes()) { + final PsiParameter[] lambdaParameters = getParameterList().getParameters(); + final PsiType[] parameterTypes = interfaceMethod.getSignature(substitutor).getParameterTypes(); + for (int lambdaParamIdx = 0, length = lambdaParameters.length; lambdaParamIdx < length; lambdaParamIdx++) { + PsiParameter parameter = lambdaParameters[lambdaParamIdx]; + final PsiTypeElement typeElement = parameter.getTypeElement(); + if (typeElement != null) { + final PsiType lambdaFormalType = toArray(typeElement.getType()); + final PsiType methodParameterType = toArray(parameterTypes[lambdaParamIdx]); + if (!lambdaFormalType.equals(methodParameterType)) { + return false; + } } } } - - //A lambda expression (§15.27) is potentially compatible with a functional interface type (§9.8) if all of the following are true: - // The arity of the target type's function type is the same as the arity of the lambda expression. - // If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2). - // If the target type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (§15.27.2). PsiType methodReturnType = interfaceMethod.getReturnType(); - if (checkReturnType) { - final String uniqueVarName = JavaCodeStyleManager.getInstance(getProject()).suggestUniqueVariableName("l", this, true); - final String canonicalText = toArray(leftType).getCanonicalText(); - final PsiStatement assignmentFromText = JavaPsiFacade.getElementFactory(getProject()) - .createStatementFromText(canonicalText + " " + uniqueVarName + " = " + getText(), this); - final PsiLocalVariable localVariable = (PsiLocalVariable)((PsiDeclarationStatement)assignmentFromText).getDeclaredElements()[0]; - if (methodReturnType != null) { - return LambdaHighlightingUtil.checkReturnTypeCompatible((PsiLambdaExpression)localVariable.getInitializer(), - substitutor.substitute(methodReturnType)) == null; + if (methodReturnType != null) { + Map map = LambdaUtil.ourFunctionTypes.get(); + if (map == null) { + map = new HashMap(); + LambdaUtil.ourFunctionTypes.set(map); } - } else { - final PsiElement body = getBody(); - if (methodReturnType == PsiType.VOID) { - if (body instanceof PsiCodeBlock) { - return isVoidCompatible(); - } else { - return LambdaUtil.isExpressionStatementExpression(body); + try { + if (map.put(this, leftType) != null) { + return false; } - } else { - if (body instanceof PsiCodeBlock) { - return isValueCompatible(); - } - return body instanceof PsiExpression; + return LambdaHighlightingUtil.checkReturnTypeCompatible(this, substitutor.substitute(methodReturnType)) == null; + } + finally { + map.remove(this); } } return true; } + //A lambda expression (§15.27) is potentially compatible with a functional interface type (§9.8) if all of the following are true: + // The arity of the target type's function type is the same as the arity of the lambda expression. + // If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2). + // If the target type's function type has a (non-void) return type, then the lambda body is either an expression or a value-compatible block (§15.27.2). + private boolean isPotentiallyCompatible(PsiType left) { + final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(left); + if (interfaceMethod == null) return false; + + if (getParameterList().getParametersCount() != interfaceMethod.getParameterList().getParametersCount()) { + return false; + } + final PsiType methodReturnType = interfaceMethod.getReturnType(); + final PsiElement body = getBody(); + if (methodReturnType == PsiType.VOID) { + if (body instanceof PsiCodeBlock) { + return isVoidCompatible(); + } else { + return LambdaUtil.isExpressionStatementExpression(body); + } + } + else { + return body instanceof PsiCodeBlock && isValueCompatible() || body instanceof PsiExpression; + } + } + private static PsiType toArray(PsiType paramType) { if (paramType instanceof PsiEllipsisType) { return ((PsiEllipsisType)paramType).toArrayType(); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java index a9ba1bbaa5b0..32545c51df0d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java @@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.*; import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil; @@ -373,12 +374,19 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase return false; } - final PsiElement argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class); + final PsiExpressionList argsList = PsiTreeUtil.getParentOfType(this, PsiExpressionList.class); final boolean isExact = isExact(); - if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList) && isExact) { + if (MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argsList)) { final MethodCandidateInfo.CurrentCandidateProperties candidateProperties = MethodCandidateInfo.getCurrentMethod(argsList); - if (candidateProperties != null && !InferenceSession.isPertinentToApplicability(this, candidateProperties.getMethod())) { - return true; + if (candidateProperties != null) { + final PsiMethod method = candidateProperties.getMethod(); + if (isExact && !InferenceSession.isPertinentToApplicability(this, method)) { + return true; + } + + if (LambdaUtil.isPotentiallyCompatibleWithTypeParameter(this, argsList, method)) { + return true; + } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index f5b690863957..99e577b8506c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -33,6 +33,7 @@ import com.intellij.util.containers.HashSet; import gnu.trove.THashMap; import gnu.trove.THashSet; import gnu.trove.TIntArrayList; +import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -91,9 +92,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ // then noone can be more specific if (!atLeastOneMatch) return null; - checkLambdaApplicable(conflicts, myLanguageLevel); - if (conflicts.size() == 1) return conflicts.get(0); - checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel); if (conflicts.size() == 1) return conflicts.get(0); @@ -108,63 +106,6 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ return null; } - private void checkLambdaApplicable(@NotNull List conflicts, @NotNull LanguageLevel languageLevel) { - if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return; - for (int i = 0; i < getActualParametersLength(); i++) { - - PsiExpression expression; - if (myArgumentsList instanceof PsiExpressionList) { - expression = ((PsiExpressionList)myArgumentsList).getExpressions()[i]; - } - else { - final PsiType argType = getActualParameterTypes()[i]; - expression = argType instanceof PsiLambdaExpressionType ? ((PsiLambdaExpressionType)argType).getExpression() : null; - } - - final PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(expression); - if (lambdaExpression != null) { - checkLambdaApplicable(conflicts, i, lambdaExpression); - } - } - } - - private static PsiLambdaExpression findNestedLambdaExpression(PsiExpression expression) { - if (expression instanceof PsiLambdaExpression) { - return (PsiLambdaExpression)expression; - } - else if (expression instanceof PsiParenthesizedExpression) { - return findNestedLambdaExpression(((PsiParenthesizedExpression)expression).getExpression()); - } - else if (expression instanceof PsiConditionalExpression) { - PsiLambdaExpression lambdaExpression = findNestedLambdaExpression(((PsiConditionalExpression)expression).getThenExpression()); - if (lambdaExpression != null) { - return lambdaExpression; - } - return findNestedLambdaExpression(((PsiConditionalExpression)expression).getElseExpression()); - } - return null; - } - - private static void checkLambdaApplicable(@NotNull List conflicts, int i, @NotNull PsiLambdaExpression lambdaExpression) { - for (Iterator iterator = conflicts.iterator(); iterator.hasNext(); ) { - ProgressManager.checkCanceled(); - final CandidateInfo conflict = iterator.next(); - final PsiMethod method = (PsiMethod)conflict.getElement(); - final PsiParameter[] methodParameters = method.getParameterList().getParameters(); - if (methodParameters.length == 0) continue; - final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1]; - final PsiType paramType = param.getType(); - // http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1 - // A lambda expression or a method reference expression is potentially compatible with a type variable if the type variable is a type parameter of the candidate method. - final PsiClass paramClass = PsiUtil.resolveClassInType(paramType); - if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) continue; - if (!lambdaExpression.isAcceptable(((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType), - InferenceSession.isPertinentToApplicability(lambdaExpression, method))) { - iterator.remove(); - } - } - } - public void checkSpecifics(@NotNull List conflicts, @MethodCandidateInfo.ApplicabilityLevelConstant int applicabilityLevel, @NotNull LanguageLevel languageLevel) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java index a178b4d970d8..83db64423f6f 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityReturnValueResolution2.java @@ -20,7 +20,7 @@ public class Test { public static void main(String[] args) { Inner inn = new Inner<>(); inn.m8(p -> 1.0); - new Test().foo(p -> 1.0); + new Test().foo(p -> 1.0); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConflictResolution.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConflictResolution.java index 0cc3741e0f61..6fbdbd116855 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConflictResolution.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ConflictResolution.java @@ -1,7 +1,7 @@ class Demo { public void f1() { - f2(2, input -> input); + f2(2, input -> input); } public void f2() { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java index 10cd3fffeb86..cdddcba60c36 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility.java @@ -25,7 +25,7 @@ class ReturnTypeIncompatibility { } public static void main(String[] args) { - call(i-> {return i;}); + call(i-> {return i;}); } } @@ -57,7 +57,7 @@ class ReturnTypeCompatibility { } public static void main(String[] args) { - call(i-> {return i;}); + call(i-> {return i;}); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java index d62afb3fdfcd..55bf990960ef 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/ReturnTypeCompatibility1.java @@ -21,9 +21,9 @@ class Test { } void foo(Foo as, final Foo ac) { - boolean b1 = as.forAll(s -> ac.forAll(c -> false)); - String s1 = as.forAll(s -> ac.forAll(c -> "")); - boolean b2 = as.forAll(s -> ac.forAll(c -> "")); + boolean b1 = as.forAll(s -> ac.forAll(c -> false)); + String s1 = as.forAll(s -> ac.forAll(c -> "")); + boolean b2 = as.forAll(s -> ac.forAll(c -> "")); String s2 = as.forAll2(s -> ac.forAll2(c -> false)); boolean b3 = as.forAll((I)s -> ac.forAll((I)c -> "")); String s3 = as.forAll((II)s -> ac.forAll((II)c -> false)); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IDEA102800.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IDEA102800.java index 7c2cc7bdae5e..299c620daeb2 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IDEA102800.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/IDEA102800.java @@ -14,7 +14,7 @@ class Test { } void fooBar(IntStream1 instr){ - Supplier> si = () -> instr.map ((i) -> (( i % 2) == 0) ? i : -i).boxed(); + Supplier> si = () -> instr.map ((i) -> (( i % 2) == 0) ? i : -i).boxed(); System.out.println(si); Supplier> si1 = () -> instr.map (null).boxed(); System.out.println(si1); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/PertinentToApplicabilityOfExplicitlyTypedLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/PertinentToApplicabilityOfExplicitlyTypedLambda.java index 348108fc3443..adaea236cd62 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/PertinentToApplicabilityOfExplicitlyTypedLambda.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/PertinentToApplicabilityOfExplicitlyTypedLambda.java @@ -12,6 +12,6 @@ abstract class PertinentToApplicabilityOfExplicitlyTypedLambdaTest { abstract void foo(B b); { - foo(x -> y -> 42); + foo(x -> y -> 42); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityOfImplicitlyTypedLambda.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityOfImplicitlyTypedLambda.java index 1188a9584dca..443f6339121d 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityOfImplicitlyTypedLambda.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/overloadResolution/VoidValueCompatibilityOfImplicitlyTypedLambda.java @@ -14,10 +14,10 @@ abstract class Test { foo(x -> { return x += 1; }); - foo(x -> x += 1); + foo(x -> x += 1); foo(x -> 1); foo(x -> !x); - foo(x -> ++x); + foo(x -> ++x); foo(x -> o instanceof String ? 1 : 0); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/MethodApplicability.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/MethodApplicability.java index 81c52a8cb7e6..aa18671e3f48 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/MethodApplicability.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/params/MethodApplicability.java @@ -26,9 +26,9 @@ class Foo { System.out.println(s); }); - foo((String p, String k) -> { + foo((String p, String k) -> { System.out.println(p); - }); + }); } } @@ -62,7 +62,7 @@ class WithTypeParams { System.out.println(p); }); - foo((int k) -> {System.out.println(k);}); + foo((int k) -> {System.out.println(k);}); } } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java index 41559703426b..fad273396623 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.registry.Registry; import com.intellij.testFramework.IdeaTestUtil; import org.jetbrains.annotations.NonNls; @@ -100,7 +101,9 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase { } public void testJDK8042508() throws Exception { - doTest(false); + if (Registry.is("JDK8042508.bug.fixed", false)) { + doTest(false); + } } public void testIDEA125855() throws Exception { diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index bfbcb49e83ce..bd09bd415c8b 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -495,4 +495,7 @@ editor.xcode.like.scrollbar=false editor.xcode.like.scrollbar.description=Enables auto-hideable Xcode-like editor stripes editor.config.stop.at.project.root=true -editor.config.stop.at.project.root.description=Stops searching for .editorconfig at project root (requires project reopening) \ No newline at end of file +editor.config.stop.at.project.root.description=Stops searching for .editorconfig at project root (requires project reopening) + +JDK8042508.bug.fixed=false +JDK8042508.bug.fixed.description=Disable check for type variable until javac bug is fixed From f4c955145a4643f4c73fe5f742bd11337281acb6 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Wed, 26 Nov 2014 19:44:30 +0300 Subject: [PATCH 27/38] new colors for stripes (IDEA-131263) --- colorSchemes/src/colorSchemes/Darcula.xml | 34 ++++++++++------- .../HighlightDisplayLevel.java | 38 ++++++++++++------- .../daemon/impl/SeverityRegistrar.java | 2 +- .../daemon/impl/TrafficLightRenderer.java | 22 ++--------- .../InspectionProfileManagerImpl.java | 14 ++----- .../src/DefaultColorSchemesManager.xml | 34 ++++++++++++----- .../SpellCheckerSeveritiesProvider.java | 12 ++---- 7 files changed, 81 insertions(+), 75 deletions(-) diff --git a/colorSchemes/src/colorSchemes/Darcula.xml b/colorSchemes/src/colorSchemes/Darcula.xml index 6025ff6f84b8..d960bd12830b 100644 --- a/colorSchemes/src/colorSchemes/Darcula.xml +++ b/colorSchemes/src/colorSchemes/Darcula.xml @@ -557,7 +557,7 @@ @@ -731,7 +731,7 @@ + +