From 840bd4952f1e269bc5b34b7a441bdba9f7a07e97 Mon Sep 17 00:00:00 2001 From: Pavel Dolgov Date: Wed, 23 Mar 2016 15:15:38 +0300 Subject: [PATCH 01/16] Javafx: Quick fix for event handler method's signature: added TODO comment about handling wildcard types. (IDEA-151694) --- .../src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java index e05619e28208..55278757aa95 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java @@ -905,7 +905,7 @@ public class JavaFxPsiUtil { if (eventType instanceof PsiClassType) { return (PsiClassType)eventType; } - if (eventType instanceof PsiWildcardType) { + if (eventType instanceof PsiWildcardType) { // TODO Handle wildcards more accurately final PsiType boundType = ((PsiWildcardType)eventType).getBound(); if (boundType instanceof PsiClassType) { return (PsiClassType)boundType; From c1c00cfd958ba5348a593e2d0aaf8dd4065c4598 Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Wed, 23 Mar 2016 15:16:13 +0300 Subject: [PATCH 02/16] The possible fix of the thread leak in DebuggerReader --- .../com/jetbrains/python/debugger/pydev/RemoteDebugger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java index ff0a5175efe4..e62905181ff1 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java @@ -491,7 +491,7 @@ public class RemoteDebugger implements ProcessDebugger { private StringBuilder myTextBuilder = new StringBuilder(); private DebuggerReader(final InputStream stream) throws IOException { - super(stream, CharsetToolkit.UTF8_CHARSET, SleepingPolicy.BLOCKING); //TODO: correct encoding? + super(stream, CharsetToolkit.UTF8_CHARSET); //TODO: correct encoding? start(getClass().getName()); } From a5d13c5adf807ce9fbbbff005ad221fd96323bb2 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 23 Mar 2016 15:20:11 +0300 Subject: [PATCH 03/16] inspections settings: fixed severity icon and checkbox overlapping on hidpi monitors (see discussion in IDEA-127955) --- .../ui/inspectionsTree/InspectionsConfigTreeTable.java | 5 +++-- .../codeInspection/ui/table/ThreeStateCheckBoxRenderer.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java index e4c21a8e4e01..ab5134d5eca1 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/InspectionsConfigTreeTable.java @@ -43,6 +43,7 @@ import com.intellij.util.Alarm; import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; +import com.intellij.util.ui.JBUI; import com.intellij.util.ui.TextTransferable; import com.intellij.util.ui.table.IconTableCellRenderer; import org.jetbrains.annotations.NotNull; @@ -99,10 +100,10 @@ public class InspectionsConfigTreeTable extends TreeTable { return value; } }); - severitiesColumn.setMaxWidth(20); + severitiesColumn.setMaxWidth(JBUI.scale(20)); final TableColumn isEnabledColumn = getColumnModel().getColumn(IS_ENABLED_COLUMN); - isEnabledColumn.setMaxWidth(20 + getAdditionalPadding()); + isEnabledColumn.setMaxWidth(JBUI.scale(20 + getAdditionalPadding())); isEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer()); isEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer()); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java index d3f0f3c5a27f..a7ac867403f6 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/table/ThreeStateCheckBoxRenderer.java @@ -16,6 +16,7 @@ package com.intellij.profile.codeInspection.ui.table; import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeTable; +import com.intellij.ui.IdeBorderFactory; import com.intellij.util.SmartList; import com.intellij.util.ui.ThreeStateCheckBox; import org.jetbrains.annotations.Nullable; @@ -43,7 +44,7 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta setThirdStateEnabled(false); setHorizontalAlignment(CENTER); setVerticalAlignment(CENTER); - setBorder(BorderFactory.createEmptyBorder(0, 0, 0, InspectionsConfigTreeTable.getAdditionalPadding())); + setBorder(IdeBorderFactory.createEmptyBorder(0, 0, 0, InspectionsConfigTreeTable.getAdditionalPadding())); addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { From fea4f11ef7d51cf08122f16f45c973c97f210fae Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 23 Mar 2016 13:36:28 +0100 Subject: [PATCH 04/16] IDEA-CR-8978 deprecate old methods --- .../debugger/engine/JavaDebugProcess.java | 13 ++-- .../debugger-ui/src/LineBreakpointManager.kt | 4 +- .../com/intellij/xdebugger/XDebugProcess.java | 76 +++++++++++++------ .../xsltDebugger/impl/XsltDebugProcess.java | 10 +-- .../python/debugger/PyDebugProcess.java | 2 +- 5 files changed, 69 insertions(+), 36 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java index 76ee7cc71130..5c66fd6f2e1e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java @@ -55,6 +55,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.XBreakpointHandler; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.frame.XStackFrame; +import com.intellij.xdebugger.frame.XSuspendContext; import com.intellij.xdebugger.frame.XValueMarkerProvider; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.XDebuggerUtilImpl; @@ -240,22 +241,22 @@ public class JavaDebugProcess extends XDebugProcess { } @Override - public void startStepOver() { + public void startStepOver(@Nullable XSuspendContext context) { myJavaSession.stepOver(false); } @Override - public void startStepInto() { + public void startStepInto(@Nullable XSuspendContext context) { myJavaSession.stepInto(false, null); } @Override - public void startForceStepInto() { + public void startForceStepInto(@Nullable XSuspendContext context) { myJavaSession.stepInto(true, null); } @Override - public void startStepOut() { + public void startStepOut(@Nullable XSuspendContext context) { myJavaSession.stepOut(); } @@ -271,12 +272,12 @@ public class JavaDebugProcess extends XDebugProcess { } @Override - public void resume() { + public void resume(@Nullable XSuspendContext context) { myJavaSession.resume(); } @Override - public void runToPosition(@NotNull XSourcePosition position) { + public void runToPosition(@NotNull XSourcePosition position, @Nullable XSuspendContext context) { myJavaSession.runToCursor(position, false); } diff --git a/platform/script-debugger/debugger-ui/src/LineBreakpointManager.kt b/platform/script-debugger/debugger-ui/src/LineBreakpointManager.kt index 2e6466e7788e..2227e5f91384 100644 --- a/platform/script-debugger/debugger-ui/src/LineBreakpointManager.kt +++ b/platform/script-debugger/debugger-ui/src/LineBreakpointManager.kt @@ -197,7 +197,7 @@ abstract class LineBreakpointManager(internal val debugProcess: DebugProcessImpl protected open fun checkDuplicates(newTarget: BreakpointTarget, location: Location, breakpointManager: BreakpointManager): Breakpoint? = null - fun runToLocation(position: XSourcePosition) { + fun runToLocation(position: XSourcePosition, vm: Vm) { val addedBreakpoints = doRunToLocation(position) if (addedBreakpoints.isEmpty()) { return @@ -206,7 +206,7 @@ abstract class LineBreakpointManager(internal val debugProcess: DebugProcessImpl synchronized (lock) { runToLocationBreakpoints.addAll(addedBreakpoints) } - debugProcess.resume(debugProcess.activeOrMainVm!!) + debugProcess.resume(vm) } protected abstract fun doRunToLocation(position: XSourcePosition): List diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java index 0bd309f8b87c..1336186e3672 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebugProcess.java @@ -88,32 +88,51 @@ public abstract class XDebugProcess { public void startPausing() { } + @Deprecated /** - * Resume execution and call {@link XDebugSession#positionReached} - * when next line in current method/function is reached. - * Do not call this method directly. Use {@link XDebugSession#stepOver} instead + * @deprecated Use {@link #startStepOver(XSuspendContext)} instead */ public void startStepOver() { throw new AbstractMethodError(); } + /** + * Resume execution and call {@link XDebugSession#positionReached} + * when next line in current method/function is reached. + * Do not call this method directly. Use {@link XDebugSession#stepOver} instead + */ public void startStepOver(@Nullable XSuspendContext context) { + //noinspection deprecation startStepOver(); } + @Deprecated + /** + * @deprecated Use {@link #startForceStepInto(XSuspendContext)} instead + */ + public void startForceStepInto(){ + //noinspection deprecation + startStepInto(); + } + /** * Steps into suppressed call - * + *

* Resume execution and call {@link XDebugSession#positionReached} * when next line is reached. * Do not call this method directly. Use {@link XDebugSession#forceStepInto} instead */ - public void startForceStepInto(){ - startStepInto(); + public void startForceStepInto(@Nullable XSuspendContext context) { + //noinspection deprecation + startForceStepInto(); } - public void startForceStepInto(@Nullable XSuspendContext context) { - startForceStepInto(); + @Deprecated + /** + * @deprecated Use {@link #startStepInto(XSuspendContext)} instead + */ + public void startStepInto() { + throw new AbstractMethodError(); } /** @@ -121,12 +140,17 @@ public abstract class XDebugProcess { * when next line is reached. * Do not call this method directly. Use {@link XDebugSession#stepInto} instead */ - public void startStepInto() { - throw new AbstractMethodError(); + public void startStepInto(@Nullable XSuspendContext context) { + //noinspection deprecation + startStepInto(); } - public void startStepInto(@Nullable XSuspendContext context) { - startStepInto(); + @Deprecated + /** + * @deprecated Use {@link #startStepOut(XSuspendContext)} instead + */ + public void startStepOut() { + throw new AbstractMethodError(); } /** @@ -134,11 +158,8 @@ public abstract class XDebugProcess { * after returning from current method/function. * Do not call this method directly. Use {@link XDebugSession#stepOut} instead */ - public void startStepOut() { - throw new AbstractMethodError(); - } - public void startStepOut(@Nullable XSuspendContext context) { + //noinspection deprecation startStepOut(); } @@ -165,29 +186,40 @@ public abstract class XDebugProcess { return Promise.DONE; } + @Deprecated /** - * Resume execution. - * Do not call this method directly. Use {@link XDebugSession#resume} instead + * @deprecated Use {@link #resume(XSuspendContext)} instead */ public void resume() { throw new AbstractMethodError(); } + /** + * Resume execution. + * Do not call this method directly. Use {@link XDebugSession#resume} instead + */ public void resume(@Nullable XSuspendContext context) { + //noinspection deprecation resume(); } + @Deprecated + /** + * @deprecated Use {@link #runToPosition(XSuspendContext)} instead + */ + public void runToPosition(@NotNull XSourcePosition position) { + throw new AbstractMethodError(); + } + /** * Resume execution and call {@link XDebugSession#positionReached(com.intellij.xdebugger.frame.XSuspendContext)} * when position is reached. * Do not call this method directly. Use {@link XDebugSession#runToPosition} instead + * * @param position position in source code */ - public void runToPosition(@NotNull XSourcePosition position) { - throw new AbstractMethodError(); - } - public void runToPosition(@NotNull XSourcePosition position, @Nullable XSuspendContext context) { + //noinspection deprecation runToPosition(position); } diff --git a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java index d601c9b28e4c..71719a75a61f 100644 --- a/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java +++ b/plugins/xslt-debugger/src/org/intellij/plugins/xsltDebugger/impl/XsltDebugProcess.java @@ -121,17 +121,17 @@ public class XsltDebugProcess extends XDebugProcess implements Disposable { } @Override - public void startStepOver() { + public void startStepOver(@Nullable XSuspendContext context) { myDebuggerSession.stepOver(); } @Override - public void startStepInto() { + public void startStepInto(@Nullable XSuspendContext context) { myDebuggerSession.stepInto(); } @Override - public void startStepOut() { + public void startStepOut(@Nullable XSuspendContext context) { myDebuggerSession.stepOver(); } @@ -155,7 +155,7 @@ public class XsltDebugProcess extends XDebugProcess implements Disposable { } @Override - public void resume() { + public void resume(@Nullable XSuspendContext context) { myDebuggerSession.resume(); } @@ -164,7 +164,7 @@ public class XsltDebugProcess extends XDebugProcess implements Disposable { } @Override - public void runToPosition(@NotNull XSourcePosition position) { + public void runToPosition(@NotNull XSourcePosition position, @Nullable XSuspendContext context) { final PsiFile psiFile = PsiManager.getInstance(getSession().getProject()).findFile(position.getFile()); assert psiFile != null; if (myDebuggerSession.canRunTo(position)) { diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index c91c0194096e..98cc6d73f087 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -407,7 +407,7 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr } @Override - public void resume() { + public void resume(@Nullable XSuspendContext context) { passToAllThreads(ResumeOrStepCommand.Mode.RESUME); } From 3cc01ec931c399b7a6fe411e46c0a3b9ff094de0 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 22 Mar 2016 19:32:14 +0100 Subject: [PATCH 05/16] more contrast shadow --- platform/icons/src/windows/shadow/bottom.png | Bin 89 -> 92 bytes .../icons/src/windows/shadow/bottomLeft.png | Bin 150 -> 170 bytes .../icons/src/windows/shadow/bottomRight.png | Bin 148 -> 167 bytes platform/icons/src/windows/shadow/left.png | Bin 87 -> 88 bytes platform/icons/src/windows/shadow/right.png | Bin 87 -> 89 bytes platform/icons/src/windows/shadow/top.png | Bin 89 -> 88 bytes platform/icons/src/windows/shadow/topLeft.png | Bin 147 -> 165 bytes platform/icons/src/windows/shadow/topRight.png | Bin 148 -> 165 bytes 8 files changed, 0 insertions(+), 0 deletions(-) diff --git a/platform/icons/src/windows/shadow/bottom.png b/platform/icons/src/windows/shadow/bottom.png index 0a02167d45777bc1b510b839c213d62f7e247582..97df54dcd47ff1844ed04ef28a8fb5955b9f4d21 100644 GIT binary patch delta 61 zcma!ynV@2!?CIhdQgJIeAtB)fOHx~rfFQfl8pjr)4gm(iH9Y_S|4(ONu#sgsw|!GV QJOdDTy85}Sb4q9e0FW;f=>Px# delta 58 zcma!voS6OOO w;JGmka!0l2I)7XWA;c(#h2u(pUY5E61lkDjwc@3700000Ne4wvM6N<$f~So$X3(oQGc^irV@3KoiVP@;#jA~*_K*%V!h>JnzNVxy#UEpUUV{)A}|MLphvJ_;s8 bAKB3VyO9E!>)GZA00000NkvXXu0mjfX>c?J diff --git a/platform/icons/src/windows/shadow/bottomRight.png b/platform/icons/src/windows/shadow/bottomRight.png index 9e4af40ff6f748e024088d3ebd3e7161bc77387d..0054d80ffaae207e711eb7815d7281f8742b1c8b 100644 GIT binary patch delta 139 zcmV;60CfM90jB|wB!6y6L_t(|+Evay4nRN<#qseGB!W(&P^hSNDmQQdtrIwdgRg($ zZ8A3bHS^v~*39g|jT0LtbSRLR!V3phjA)R@!l`h_f*!RmY}%YLphbx^7ABqT6;^)R t^r1#)ONFT~6dGnONJ0oP{|3(Qy(4}I@QjzKSpWb407*qoLmUOV Nc)I$ztaD0e0swH^6%+sf delta 56 zcmazHpP*ta=jq}YQgJIeAtB)cdlIig7(BUr(0GF7T$!2Q4hA6b MboFyt=akR{08GXcQvd(} delta 58 zcma!uoSbP0l+XkK1XB@< diff --git a/platform/icons/src/windows/shadow/topLeft.png b/platform/icons/src/windows/shadow/topLeft.png index 123b8f788ebd50ca98774437abe5d2485d9c9ae6..13893e9c475379d36f4ba6abf789660c7fef1674 100644 GIT binary patch delta 137 zcmV;40CxYA0i^+uB!6s4L_t(|+GWnM34kyVh2a<_5hU6P78a?rwzF~r2T1D#&fwtj z7fv`d@HKh&jx*-}iVtIQ&N{FtQNih!l~0cb0i7Or!Wu1ljEK7JB^)qe!K&MhG-qts rk@P^2wTpxY&Ue7cK~dHw39lOlxCrn!_h(lC0000d&8}Ry2)Y+_f YUe4A6nU~LOCIA2c07*qoM6N<$f_}?2nE(I) diff --git a/platform/icons/src/windows/shadow/topRight.png b/platform/icons/src/windows/shadow/topRight.png index 8734648c9e4d8a35e67920948b5444a8a29116c5..35048e30ba1f06bbe5cb09ce602bed92aae61f01 100644 GIT binary patch delta 137 zcmV;40CxYB0i^+uB!6s4L_t(|+GWo%4nQyfh2a)KB4v{p3?}AoCO2>Zs}nebgV!&4 zq@l^T{dsMTF~)xUPL2#Ik|zuyyg>tp3Wee%UK`M(MU7I?8_e(+(J3n8l?^KvOj@eq rl>@sXuj^bKoQgJGH|XK_@9YI7TnO;%fsSf`T< ZdjRW(0-4iqoR9zj002ovPDHLkV1njpGNu3k From 840d2ef1205b6a86d6666b054ede1e025482b37d Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 23 Mar 2016 17:53:30 +0300 Subject: [PATCH 06/16] diff: cleanup passed editors are no longer nullable --- .../intellij/diff/actions/impl/SetEditorSettingsAction.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/actions/impl/SetEditorSettingsAction.java b/platform/diff-impl/src/com/intellij/diff/actions/impl/SetEditorSettingsAction.java index 92565f68c340..efd204add095 100644 --- a/platform/diff-impl/src/com/intellij/diff/actions/impl/SetEditorSettingsAction.java +++ b/platform/diff-impl/src/com/intellij/diff/actions/impl/SetEditorSettingsAction.java @@ -130,7 +130,7 @@ public class SetEditorSettingsAction extends ActionGroup implements DumbAware { @Override public void applyDefaults(@NotNull List editors) { for (Editor editor : editors) { - if (editor != null && editor.getUserData(EditorImpl.FORCED_SOFT_WRAPS) != null) myForcedSoftWrap = true; + if (editor.getUserData(EditorImpl.FORCED_SOFT_WRAPS) != null) myForcedSoftWrap = true; } super.applyDefaults(editors); } @@ -169,7 +169,6 @@ public class SetEditorSettingsAction extends ActionGroup implements DumbAware { public void setSelected(AnActionEvent e, boolean state) { setSelected(state); for (Editor editor : myEditors) { - if (editor == null) continue; apply(editor, state); } } @@ -182,7 +181,6 @@ public class SetEditorSettingsAction extends ActionGroup implements DumbAware { public void applyDefaults(@NotNull List editors) { for (Editor editor : editors) { - if (editor == null) continue; apply(editor, isSelected()); } } @@ -214,7 +212,6 @@ public class SetEditorSettingsAction extends ActionGroup implements DumbAware { private void apply(@NotNull HighlightingLevel layer) { for (Editor editor : myEditors) { - if (editor == null) continue; ((EditorImpl)editor).setHighlightingFilter(layer.getCondition()); } } From 95069ee9fde94cce34dd4c4b3ce36b148145e53c Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Wed, 23 Mar 2016 17:59:14 +0300 Subject: [PATCH 07/16] IDEA-149337 UI fonts are too big The logic of detecting the default system font size on Linux is improved. The default font size is used to derive the IDEA UI scale factor. Another side of improvement goes into our custom Linux JDK. GTK L&F will be able to detect "Xft.dpi" value in any Linux Desktop Environment, not necessarily built on GTK (e.g. KDE). "Xft.dpi" value is an X server resource which defines the fonts DPI. The value is set by a Linux DE automatically, or in response to users's settings. With the new custom JDK, IDEA will get properly scaled font on virtually all Linux's we support. So, the logic of deriving the UI scale will be unified with what IDEA does on Windows. With Oracle JDK, IDEA will behave the same way on GTK Linux DE's, but on other Linux's it will fallback to the old approach of detecting the UI scale based on the X server DPI (if set). --- .../src/com/intellij/ide/ui/UISettings.java | 22 ++++-- .../actions/TogglePresentationModeAction.java | 3 +- .../intellij/ide/ui/laf/LafManagerImpl.java | 4 +- .../ide/ui/laf/darcula/DarculaLaf.java | 2 +- .../util/resources/misc/registry.properties | 3 + .../util/src/com/intellij/util/ui/JBUI.java | 77 +++++++------------ .../util/src/com/intellij/util/ui/UIUtil.java | 59 ++++++++++++-- 7 files changed, 103 insertions(+), 67 deletions(-) diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java index b6ccede3ea81..ac657aefb963 100644 --- a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.java @@ -53,8 +53,15 @@ public class UISettings extends SimpleModificationTracker implements PersistentS /** Not tabbed pane. */ public static final int TABS_NONE = 0; + private String lafID; + public static UISettings getInstance() { - return ServiceManager.getService(UISettings.class); + UISettings instance = ServiceManager.getService(UISettings.class); + if (!instance.lafID.equals(UIManager.getLookAndFeel().getID())) { + // Re-init if LaF changed. + instance.init(); + } + return instance; } /** @@ -135,6 +142,10 @@ public class UISettings extends SimpleModificationTracker implements PersistentS private final EventDispatcher myDispatcher = EventDispatcher.create(UISettingsListener.class); public UISettings() { + init(); + } + + private void init() { tweakPlatformDefaults(); setSystemFontFaceAndSize(); @@ -142,6 +153,7 @@ public class UISettings extends SimpleModificationTracker implements PersistentS if (scrollToSource != null) { DEFAULT_AUTOSCROLL_TO_SOURCE = scrollToSource; } + lafID = UIManager.getLookAndFeel().getID(); } private void tweakPlatformDefaults() { @@ -181,11 +193,9 @@ public class UISettings extends SimpleModificationTracker implements PersistentS } private void setSystemFontFaceAndSize() { - if (FONT_FACE == null || FONT_SIZE <= 0) { - final Pair fontData = getSystemFontFaceAndSize(); - FONT_FACE = fontData.first; - FONT_SIZE = fontData.second; - } + final Pair fontData = getSystemFontFaceAndSize(); + FONT_FACE = fontData.first; + FONT_SIZE = fontData.second; } private static Pair getSystemFontFaceAndSize() { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java b/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java index 9d4134880911..628221c3950e 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java @@ -35,6 +35,7 @@ import com.intellij.openapi.wm.impl.DesktopLayout; import com.intellij.openapi.wm.impl.IdeFrameImpl; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -147,7 +148,7 @@ public class TogglePresentationModeAction extends AnAction implements DumbAware } } } - float scaleFactor = settings.PRESENTATION_MODE_FONT_SIZE / 12f; + float scaleFactor = settings.PRESENTATION_MODE_FONT_SIZE / UIUtil.DEF_SYSTEM_FONT_SIZE; ourSavedScaleFactor = JBUI.scale(1f); JBUI.setScaleFactor(scaleFactor); for (Object key : ourSavedValues.keySet()) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java index 63afba65f4bb..168f79f93a9f 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java @@ -729,7 +729,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo UISettings uiSettings = UISettings.getInstance(); if (uiSettings.OVERRIDE_NONIDEA_LAF_FONTS) { storeOriginalFontDefaults(uiDefaults); - JBUI.setScaleFactor(uiSettings.FONT_SIZE/12f); + JBUI.setScaleFactor(uiSettings.FONT_SIZE/UIUtil.DEF_SYSTEM_FONT_SIZE); initFontDefaults(uiDefaults, uiSettings.FONT_SIZE, new FontUIResource(uiSettings.FONT_FACE, Font.PLAIN, uiSettings.FONT_SIZE)); } else { @@ -745,7 +745,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo defaults.put(resource, lfDefaults.get(resource)); } } - JBUI.setScaleFactor(JBUI.Fonts.label().getSize()/12f); + JBUI.setScaleFactor(JBUI.Fonts.label().getSize()/UIUtil.DEF_SYSTEM_FONT_SIZE); } private void storeOriginalFontDefaults(UIDefaults defaults) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java index e398cbfb0f12..0ae2a1dc3caa 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java @@ -149,7 +149,7 @@ public class DarculaLaf extends BasicLookAndFeel { private static void applySystemFonts(UIDefaults defaults) { try { - String fqn = UIManager.getSystemLookAndFeelClassName(); + String fqn = UIUtil.getSystemLookAndFeelClassName(); Object systemLookAndFeel = Class.forName(fqn).newInstance(); final Method superMethod = BasicLookAndFeel.class.getDeclaredMethod("getDefaults"); superMethod.setAccessible(true); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index aa87893bdef2..f157470a699f 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -468,6 +468,9 @@ cvs.roots.refresh.uses.vfs=true cvs.roots.refresh.uses.vfs.description=Should CVS roots refresh after update use VFS vcs.add.remove.silent=true +ide.ui.scale.override=false +ide.ui.scale=1.0 + ide.new.notification.enabled=false ide.new.notification.visible.count=2 diff --git a/platform/util/src/com/intellij/util/ui/JBUI.java b/platform/util/src/com/intellij/util/ui/JBUI.java index c12f42bfdb10..6139cfdca0f2 100644 --- a/platform/util/src/com/intellij/util/ui/JBUI.java +++ b/platform/util/src/com/intellij/util/ui/JBUI.java @@ -36,61 +36,35 @@ import java.awt.*; public class JBUI { private static final Logger LOG = Logger.getInstance("#com.intellij.util.ui.JBUI"); - private static float SCALE_FACTOR = calculateScaleFactor(); + private static float scaleFactor = 1.0f; - private static float calculateScaleFactor() { + static { + calculateScaleFactor(); + } + + private static void calculateScaleFactor() { if (SystemInfo.isMac) { LOG.info("UI scale factor: 1.0"); - return 1.0f; + scaleFactor = 1.0f; + return; } if (SystemProperties.has("hidpi") && !SystemProperties.is("hidpi")) { LOG.info("UI scale factor: 1.0"); - return 1.0f; + scaleFactor = 1.0f; + return; } - float s = 1f; + UIUtil.initSystemFontData(); + Pair fdata = UIUtil.getSystemFontData(); - // On Linux: rely on DPI - if (SystemInfo.isLinux) { - final int dpi = getSystemDPI(); - if (dpi < 120) s = 1f; - else if (dpi < 144) s = 1.25f; - else if (dpi < 168) s = 1.5f; - else if (dpi < 192) s = 1.75f; - else s = 2f; - - LOG.info("UI scale factor: " + s); - return s; - } - - int size = -1; - - // On Windows: rely on default system font - if (SystemInfo.isWindows) { - UIUtil.initSystemFontData(); - Pair fdata = UIUtil.getSystemFontData(); - if (fdata != null) size = fdata.getSecond(); - } - if (size == -1) { + int size; + if (fdata != null) { + size = fdata.getSecond(); + } else { size = Fonts.label().getSize(); } - if (size <= 13) s = 1.0f; - else if (size <= 16) s = 1.25f; - else if (size <= 18) s = 1.5f; - else if (size < 24) s = 1.75f; - else s = 2.0f; - - LOG.info("UI scale factor: " + s); - return s; - } - - private static int getSystemDPI() { - try { - return Toolkit.getDefaultToolkit().getScreenResolution(); - } catch (HeadlessException e) { - return 96; - } + setScaleFactor(size/UIUtil.DEF_SYSTEM_FONT_SIZE); } public static void setScaleFactor(float scale) { @@ -108,19 +82,22 @@ public class JBUI { //Default UI font size for Unity and Gnome is 15. Scaling factor 1.25f works badly on Linux scale = 1f; } - LOG.info("UI scale factor changed: " + scale); + if (scaleFactor == scale) { + return; + } + LOG.info("UI scale factor: " + scale); - SCALE_FACTOR = scale; + scaleFactor = scale; IconLoader.setScale(scale); } public static int scale(int i) { - return Math.round(SCALE_FACTOR * i); + return Math.round(scaleFactor * i); } public static int scaleFontSize(int fontSize) { - if (SCALE_FACTOR == 1.25f) return (int)(fontSize * 1.34f); - if (SCALE_FACTOR == 1.75f) return (int)(fontSize * 1.67f); + if (scaleFactor == 1.25f) return (int)(fontSize * 1.34f); + if (scaleFactor == 1.75f) return (int)(fontSize * 1.67f); return scale(fontSize); } @@ -177,7 +154,7 @@ public class JBUI { } public static float scale(float f) { - return f * SCALE_FACTOR; + return f * scaleFactor; } public static JBInsets insets(Insets insets) { @@ -185,7 +162,7 @@ public class JBUI { } public static boolean isHiDPI() { - return SCALE_FACTOR > 1.0f; + return scaleFactor > 1.0f; } public static class Fonts { diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index ebf1f3c325b0..38571a174207 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -323,6 +323,8 @@ public class UIUtil { private static volatile Pair ourSystemFontData = null; + public static final float DEF_SYSTEM_FONT_SIZE = 12f; // TODO: consider 12 * 1.33 to compensate JDK's 72dpi font scale + @NonNls private static final String ROOT_PANE = "JRootPane.future"; private static final Ref ourRetina = Ref.create(SystemInfo.isMac ? null : false); @@ -2542,9 +2544,16 @@ public class UIUtil { } } + public static String getSystemLookAndFeelClassName() { + // Force GTK LaF on Linux to let it retrieve system font settings + // with proper font scale based on Xft.dpi + return SystemInfo.isLinux ? "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" : + UIManager.getSystemLookAndFeelClassName(); + } + public static void initDefaultLAF() { try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + UIManager.setLookAndFeel(getSystemLookAndFeelClassName()); initSystemFontData(); } catch (Exception ignore) {} @@ -2553,16 +2562,36 @@ public class UIUtil { public static void initSystemFontData() { if (ourSystemFontData != null) return; + // With JB Linux JDK the label font comes properly scaled based on Xft.dpi settings. Font font = getLabelFont(); - if (SystemInfo.isWindows) { + + Float forcedScale = null; + if (Registry.is("ide.ui.scale.override")) { + forcedScale = Float.valueOf((float)Registry.get("ide.ui.scale").asDouble()); + } + else if (SystemInfo.isLinux && !SystemInfo.isJetbrainsJvm) { + // With Oracle JDK: derive scale from X server DPI + float scale = getScreenScale(); + if (scale > 1f) { + forcedScale = Float.valueOf(scale); + } + // Or otherwise leave the detected font. It's undetermined if it's scaled or not. + // If it is (likely with GTK DE), then the UI scale will be derived from it, + // if it's not, then IDEA will start unscaled. This lets the users of GTK DEs + // not to bother about X server DPI settings. Users of other DEs (like KDE) + // will have to set X server DPI to meet their display. + } + else if (SystemInfo.isWindows) { //noinspection HardCodedStringLiteral Font winFont = (Font)Toolkit.getDefaultToolkit().getDesktopProperty("win.messagebox.font"); - if (winFont != null) font = winFont; + if (winFont != null) { + font = winFont; // comes scaled + } } - else if (SystemInfo.isLinux && JBUI.isHiDPI()) { - // We don't expect the default GUI font to be scaled on Linux and do it ourselves. - // TODO: this is valid until HIDPI support comes to J2D/Swing on Linux. - font = JBFont.create(font); + if (forcedScale != null) { + // With forced scale, we derive font from a hard-coded value as we cannot be sure + // the system font comes unscaled. + font = font.deriveFont(DEF_SYSTEM_FONT_SIZE * forcedScale.floatValue()); } ourSystemFontData = Pair.create(font.getName(), font.getSize()); } @@ -2572,6 +2601,22 @@ public class UIUtil { return ourSystemFontData; } + private static float getScreenScale() { + int dpi = 96; + try { + dpi = Toolkit.getDefaultToolkit().getScreenResolution(); + } catch (HeadlessException e) { + } + float scale = 1f; + if (dpi < 120) scale = 1f; + else if (dpi < 144) scale = 1.25f; + else if (dpi < 168) scale = 1.5f; + else if (dpi < 192) scale = 1.75f; + else scale = 2f; + + return scale; + } + public static void addKeyboardShortcut(final JComponent target, final AbstractButton button, final KeyStroke keyStroke) { target.registerKeyboardAction( new ActionListener() { From 5ce98f5faa9590546b861a7bf4732ed1ec5a1c65 Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Wed, 23 Mar 2016 18:29:16 +0300 Subject: [PATCH 08/16] Fix test TemplateSyntaxErrorExceptionBreakpoint --- python/helpers/pydev/pydevd_plugins/jinja2_debug.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/helpers/pydev/pydevd_plugins/jinja2_debug.py b/python/helpers/pydev/pydevd_plugins/jinja2_debug.py index d3d02ffe735e..b5002fab2127 100644 --- a/python/helpers/pydev/pydevd_plugins/jinja2_debug.py +++ b/python/helpers/pydev/pydevd_plugins/jinja2_debug.py @@ -360,11 +360,12 @@ def exception_break(plugin, pydb, pydb_frame, frame, args, arg): elif get_exception_name(exception) in ('TemplateSyntaxError', 'TemplateAssertionError'): #errors in compile time name = frame.f_code.co_name - if name in ('template', 'top-level template code') or name.startswith('block '): + if name in ('template', 'top-level template code', '') or name.startswith('block '): #Jinja2 translates exception info and creates fake frame on his own - pydb_frame.set_suspend(thread, CMD_ADD_EXCEPTION_BREAK, message=exception_type) + pydb_frame.set_suspend(thread, CMD_ADD_EXCEPTION_BREAK) add_exception_to_frame(frame, (exception, value, trace)) thread.additional_info.suspend_type = JINJA2_SUSPEND + thread.additional_info.pydev_message = exception_type flag = True return flag, frame return None \ No newline at end of file From 1db28b9ae99bdb36d55c97bac0b2b1af0469025b Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Wed, 23 Mar 2016 18:40:43 +0300 Subject: [PATCH 09/16] [vcs-log] turn current branch highlighting off when filtered by HEAD --- .../src/com/intellij/vcs/log/ui/CurrentBranchHighlighter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CurrentBranchHighlighter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CurrentBranchHighlighter.java index 7804a28ab4c7..22ae1508137d 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CurrentBranchHighlighter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/CurrentBranchHighlighter.java @@ -27,6 +27,7 @@ import java.awt.*; public class CurrentBranchHighlighter implements VcsLogHighlighter { private static final JBColor CURRENT_BRANCH_BG = new JBColor(new Color(228, 250, 255), new Color(63, 71, 73)); + private static final String HEAD = "HEAD"; @NotNull private final VcsLogDataManager myDataManager; @NotNull private final VcsLogUi myLogUi; @Nullable private String mySingleFilteredBranch; @@ -42,7 +43,7 @@ public class CurrentBranchHighlighter implements VcsLogHighlighter { if (isSelected || !myLogUi.isHighlighterEnabled(Factory.ID)) return VcsCommitStyle.DEFAULT; VcsLogProvider provider = myDataManager.getLogProvider(details.getRoot()); String currentBranch = provider.getCurrentBranch(details.getRoot()); - if (currentBranch != null && !(currentBranch.equals(mySingleFilteredBranch))) { + if (!HEAD.equals(mySingleFilteredBranch) && currentBranch != null && !(currentBranch.equals(mySingleFilteredBranch))) { Condition condition = myDataManager.getContainingBranchesGetter().getContainedInBranchCondition(currentBranch, details.getRoot()); if (condition.value(new CommitId(details.getId(), details.getRoot()))) { From 5d285805a9445c6d2a17f4552f4079a48a88ddab Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 23 Mar 2016 13:36:47 +0100 Subject: [PATCH 10/16] pattern configurations: don't find one-class pattern for method configuration (IDEA-152733) --- .../AbstractPatternBasedConfigurationProducer.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java b/java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java index 019e96608ce0..e5abab500559 100644 --- a/java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java +++ b/java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java @@ -87,6 +87,13 @@ public abstract class AbstractPatternBasedConfigurationProducer()); } if (Comparing.equal(classes, patterns)) { + if (patterns.size() == 1) { + final String pattern = patterns.iterator().next(); + if (!pattern.contains(",")) { + final PsiMethod method = PsiTreeUtil.getParentOfType(CommonDataKeys.PSI_ELEMENT.getData(dataContext), PsiMethod.class); + return method != null && isTestMethod(false, method); + } + } return true; } return false; From 9e8666f15974d06c2800590259b1dbe9fabb7456 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 23 Mar 2016 15:23:23 +0100 Subject: [PATCH 11/16] bind params to fields: accept field assignments if not exactly the parameter reference was assigned (IDEA-120320) --- .../impl/FieldFromParameterUtils.java | 24 ++++++++++++------- .../afterPositionAfter.java | 11 +++++++++ .../beforePositionAfter.java | 10 ++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/assignFieldFromParameter/afterPositionAfter.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/assignFieldFromParameter/beforePositionAfter.java diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java index 3160a2bb45c3..b2bc06e28f62 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/FieldFromParameterUtils.java @@ -145,19 +145,25 @@ public final class FieldFromParameterUtils { else if (expression instanceof PsiAssignmentExpression) { PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expression; PsiExpression lExpression = assignmentExpression.getLExpression(); - PsiExpression rExpression = assignmentExpression.getRExpression(); if (!(lExpression instanceof PsiReferenceExpression)) break; - if (!(rExpression instanceof PsiReferenceExpression)) break; - - PsiReferenceExpression lReference = (PsiReferenceExpression)lExpression; - PsiReferenceExpression rReference = (PsiReferenceExpression)rExpression; - - PsiElement lElement = lReference.resolve(); - PsiElement rElement = rReference.resolve(); + PsiElement lElement = ((PsiReferenceExpression)lExpression).resolve(); if (!(lElement instanceof PsiField) || ((PsiField)lElement).getContainingClass() != targetClass) break; - if (!(rElement instanceof PsiParameter)) break; + + final Set parameters = new HashSet<>(); + SyntaxTraverser.psiTraverser().withRoot(assignmentExpression.getRExpression()) + .filter(PsiReferenceExpression.class) + .forEach(expr -> { + final PsiElement resolve = expr.resolve(); + if (resolve instanceof PsiParameter && ((PsiParameter)resolve).getDeclarationScope() == myParameter.getDeclarationScope()) { + parameters.add((PsiParameter)resolve); + } + }); + + if (parameters.size() != 1) break; + + PsiElement rElement = parameters.iterator().next(); if (myParameter.getTextRange().getStartOffset() < rElement.getTextRange().getStartOffset()) { if (anchorRef != null) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/assignFieldFromParameter/afterPositionAfter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/assignFieldFromParameter/afterPositionAfter.java new file mode 100644 index 000000000000..d7d2684fc282 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/assignFieldFromParameter/afterPositionAfter.java @@ -0,0 +1,11 @@ +// "Assign Parameter to Field 'myId'" "true" + +class Person { + int a; + int myId; + void f(int a, int id) { + this.a = foo(a); + myId = id; + } + int foo(int a) {return a;} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/assignFieldFromParameter/beforePositionAfter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/assignFieldFromParameter/beforePositionAfter.java new file mode 100644 index 000000000000..4f7d9fe7b720 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/assignFieldFromParameter/beforePositionAfter.java @@ -0,0 +1,10 @@ +// "Assign Parameter to Field 'myId'" "true" + +class Person { + int a; + int myId; + void f(int a, int id) { + this.a = foo(a); + } + int foo(int a) {return a;} +} \ No newline at end of file From a3b5e864db1890274859825ace325c2955652b8b Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 23 Mar 2016 15:44:01 +0100 Subject: [PATCH 12/16] convert field to local: reject when field is used from javadoc (IDEA-153332) --- .../FieldCanBeLocalInspectionBase.java | 23 ++++++++++++++++--- .../convert2Local/beforeUsedInJavadoc.java | 17 ++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/convert2Local/beforeUsedInJavadoc.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java index ca81169adc36..9f20f4c29476 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/FieldCanBeLocalInspectionBase.java @@ -31,6 +31,8 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.WriteExternalException; import com.intellij.psi.*; import com.intellij.psi.controlFlow.*; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTagValue; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; @@ -135,6 +137,10 @@ public class FieldCanBeLocalInspectionBase extends BaseJavaBatchLocalInspectionT } } } + final PsiDocComment docComment = method.getDocComment(); + if (docComment != null) { + docComment.accept(this); + } //do not go inside method } @@ -145,15 +151,26 @@ public class FieldCanBeLocalInspectionBase extends BaseJavaBatchLocalInspectionT @Override public void visitReferenceExpression(PsiReferenceExpression expression) { - final PsiElement resolved = expression.resolve(); + excludeFieldCandidate(expression); + + super.visitReferenceExpression(expression); + } + + @Override + public void visitDocTagValue(PsiDocTagValue value) { + excludeFieldCandidate(value.getReference()); + super.visitDocTagValue(value); + } + + private void excludeFieldCandidate(PsiReference ref) { + if (ref == null) return; + final PsiElement resolved = ref.resolve(); if (resolved instanceof PsiField) { final PsiField field = (PsiField)resolved; if (aClass.equals(field.getContainingClass())) { candidates.remove(field); } } - - super.visitReferenceExpression(expression); } }); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/convert2Local/beforeUsedInJavadoc.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/convert2Local/beforeUsedInJavadoc.java new file mode 100644 index 000000000000..65e8b00ac9d9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/convert2Local/beforeUsedInJavadoc.java @@ -0,0 +1,17 @@ +// "Convert to local" "false" +class TestFieldConversion +{ + private static int someInt = 0; + + public TestFieldConversion() + { + int usingThatInt = someInt; + } + + /** + * Referencing that value here {@value #someInt} + */ + public void someMethod() { + + } +} From 0d30474e773709696a3d9f81df3c31c3ff9b5d41 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 23 Mar 2016 16:01:15 +0100 Subject: [PATCH 13/16] unguarded field access: support sync expressions (IDEA-153399) --- .../FieldAccessNotGuardedInspection.java | 15 +++++++++++++ .../guarded/syncOnFieldQualifier.java | 21 +++++++++++++++++++ ...FieldAccessedNotGuardedInspectionTest.java | 11 +++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/inspection/guarded/syncOnFieldQualifier.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java index 18c2af6681c9..cc68da71b1bd 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection.concurrencyAnnotations; +import com.intellij.codeInsight.PsiEquivalenceUtil; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool; import com.intellij.codeInspection.ProblemsHolder; @@ -81,6 +82,20 @@ public class FieldAccessNotGuardedInspection extends BaseJavaBatchLocalInspectio if (containingMethod != null && containingMethod.hasModifierProperty(PsiModifier.SYNCHRONIZED)) { return; } + + final PsiSynchronizedStatement synchronizedStatement = PsiTreeUtil.getParentOfType(expression, PsiSynchronizedStatement.class); + if (synchronizedStatement != null) { + final PsiExpression lockExpression = synchronizedStatement.getLockExpression(); + final PsiExpression qualifierExpression = expression.getQualifierExpression(); + if (lockExpression instanceof PsiThisExpression && qualifierExpression == null) { + return; + } + if (lockExpression instanceof PsiReferenceExpression && + qualifierExpression != null && + PsiEquivalenceUtil.areElementsEquivalent(lockExpression, qualifierExpression)) { + return; + } + } } if (findLockTryStatement(expression, guard) != null) { diff --git a/java/java-tests/testData/inspection/guarded/syncOnFieldQualifier.java b/java/java-tests/testData/inspection/guarded/syncOnFieldQualifier.java new file mode 100644 index 000000000000..3ca9b3c3f37b --- /dev/null +++ b/java/java-tests/testData/inspection/guarded/syncOnFieldQualifier.java @@ -0,0 +1,21 @@ +import javax.annotation.concurrent.GuardedBy; + +class Example +{ + private final Distribution distribution = new Distribution(); + + public void add(long value) + { + synchronized (distribution) { + distribution.total += value; + total += value; + } + + } + + protected static class Distribution + { + @GuardedBy("this") + private long total = 0; + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/FieldAccessedNotGuardedInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/FieldAccessedNotGuardedInspectionTest.java index d9fad819d34d..e2715abc5555 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/FieldAccessedNotGuardedInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/FieldAccessedNotGuardedInspectionTest.java @@ -24,11 +24,20 @@ import org.jetbrains.annotations.NotNull; public class FieldAccessedNotGuardedInspectionTest extends LightCodeInsightFixtureTestCase { public void testItself() throws Exception { myFixture.addClass("package net.jcip.annotations;\n" + getGuardedByAnnotationText()); - myFixture.testHighlighting(true, false, false, getTestName(true) + ".java"); + doTest(); } public void testJavax_itself() throws Exception { myFixture.addClass("package javax.annotation.concurrent;\n" + getGuardedByAnnotationText()); + doTest(); + } + + public void testSyncOnFieldQualifier() throws Exception { + myFixture.addClass("package javax.annotation.concurrent;\n" + getGuardedByAnnotationText()); + doTest(); + } + + private void doTest() { myFixture.testHighlighting(true, false, false, getTestName(true) + ".java"); } From d6cc35ac9304a3e6dcbf620bda5d3a191cfe974d Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 23 Mar 2016 16:39:36 +0100 Subject: [PATCH 14/16] copy file: suggest to bind file type if unknown (IDEA-153379) --- .../src/com/intellij/ide/actions/CreateFileAction.java | 4 +--- .../refactoring/copy/CopyFilesOrDirectoriesDialog.java | 9 ++++++++- .../intellij/openapi/fileTypes/ex/FileTypeChooser.java | 8 ++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CreateFileAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CreateFileAction.java index 6d26841c94f8..35902ab3a850 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CreateFileAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CreateFileAction.java @@ -34,7 +34,6 @@ import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.newvfs.impl.FakeVirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; @@ -235,8 +234,7 @@ public class CreateFileAction extends CreateElementActionBase implements DumbAwa DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() { @Override public void run() { - final FileType type = FileTypeChooser.getKnownFileTypeOrAssociate(new FakeVirtualFile(psiDirectory.getVirtualFile(), getFileName(inputString)), - project); + final FileType type = FileTypeChooser.getKnownFileTypeOrAssociate(psiDirectory.getVirtualFile(), getFileName(inputString), project); result[0] = type != null && MyValidator.super.canClose(getFileName(inputString)); } }); diff --git a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java index 76bb9f495b44..046371409be3 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/copy/CopyFilesOrDirectoriesDialog.java @@ -26,6 +26,7 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.ex.FileTypeChooser; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; @@ -51,6 +52,7 @@ import com.intellij.util.PathUtilRt; import com.intellij.util.ui.FormBuilder; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.DocumentEvent; @@ -91,7 +93,7 @@ public class CopyFilesOrDirectoriesDialog extends DialogWrapper { private PsiDirectory myTargetDirectory; private boolean myFileCopy = false; - public CopyFilesOrDirectoriesDialog(PsiElement[] elements, PsiDirectory defaultTargetDirectory, Project project, boolean doClone) { + public CopyFilesOrDirectoriesDialog(PsiElement[] elements, @Nullable PsiDirectory defaultTargetDirectory, Project project, boolean doClone) { super(project, true); myElements = elements; myProject = project; @@ -122,6 +124,7 @@ public class CopyFilesOrDirectoriesDialog extends DialogWrapper { myNewNameField.select(0, dotIdx); myNewNameField.putClientProperty(DialogWrapperPeer.HAVE_INITIAL_SELECTION, true); } + myTargetDirectory = file.getContainingDirectory(); myFileCopy = true; } else { @@ -265,6 +268,10 @@ public class CopyFilesOrDirectoriesDialog extends DialogWrapper { Messages.showErrorDialog(myNewNameField, "Name is not a valid file name"); return; } + + if (myFileCopy && FileTypeChooser.getKnownFileTypeOrAssociate(myTargetDirectory.getVirtualFile(), newName, myProject) == null) { + return; + } } saveOpenInEditorState(myOpenFilesInEditor.isSelected()); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java index 91d50d80b69a..ba49434fa5f8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java @@ -149,6 +149,14 @@ public class FileTypeChooser extends DialogWrapper { return type; } + /** + * Speculates if file with newName would have known file type + */ + @Nullable + public static FileType getKnownFileTypeOrAssociate(@NotNull VirtualFile parent, @NotNull String newName, @Nullable Project project) { + return getKnownFileTypeOrAssociate(new FakeVirtualFile(parent, newName), project); + } + @Nullable public static FileType getKnownFileTypeOrAssociate(@NotNull String fileName) { FileTypeManager fileTypeManager = FileTypeManager.getInstance(); From c83a2cf81f6dfb76a52a1c1a669c402ccc3e07f3 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Mon, 14 Mar 2016 20:02:54 +0300 Subject: [PATCH 15/16] PY-18543 Fixed: Package requirements.txt does not respect pip -rfilename.txt (with no spaces between -r and filename.txt) Update regex for recursive requirement to support case when there is no spaces between -r and filename --- .../jetbrains/python/packaging/PyRequirement.java | 12 ++++++------ .../requirement/recursive/requirements.a.txt | 1 + .../requirement/recursive/requirements.b.txt | 1 + .../testData/requirement/recursive/requirements.txt | 2 ++ .../com/jetbrains/python/PyRequirementTest.java | 12 +++++++++++- 5 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 python/testData/requirement/recursive/requirements.a.txt create mode 100644 python/testData/requirement/recursive/requirements.b.txt create mode 100644 python/testData/requirement/recursive/requirements.txt diff --git a/python/openapi/src/com/jetbrains/python/packaging/PyRequirement.java b/python/openapi/src/com/jetbrains/python/packaging/PyRequirement.java index 07493ac7a044..4337586363be 100644 --- a/python/openapi/src/com/jetbrains/python/packaging/PyRequirement.java +++ b/python/openapi/src/com/jetbrains/python/packaging/PyRequirement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,7 +40,7 @@ public class PyRequirement { private static final Pattern NAME = Pattern.compile("\\s*(\\w(\\w|[-.])*)\\s*(.*)"); private static final Pattern VERSION_SPEC = Pattern.compile("\\s*(<=?|>=?|==|!=)\\s*((\\w|[-.])+)"); private static final Pattern EDITABLE_EGG = Pattern.compile("\\s*(-e)?\\s*([^#]*)(#egg=(.*))?"); - private static final Pattern RECURSIVE_REQUIREMENT = Pattern.compile("\\s*-r\\s+(.*)"); + private static final Pattern RECURSIVE_REQUIREMENT = Pattern.compile("^-r\\s*(.*)"); private static final Pattern VCS_PATH = Pattern.compile(".*/([^/]+)/?"); public enum Relation { @@ -253,7 +253,7 @@ public class PyRequirement { * * @param line requirement to parse * @return requirement - * @throws java.lang.IllegalArgumentException if line can't be parsed + * @throws IllegalArgumentException if line can't be parsed */ @NotNull public static PyRequirement fromStringGuaranteed(@NotNull final String line) { @@ -304,7 +304,7 @@ public class PyRequirement { } @NotNull - public static List parse(@NotNull VirtualFile file, @NotNull Set visited) { + private static List parse(@NotNull VirtualFile file, @NotNull Set visited) { if (!visited.contains(file)) { visited.add(file); final Document document = FileDocumentManager.getInstance().getDocument(file); @@ -339,9 +339,9 @@ public class PyRequirement { } @NotNull - private static List parseRecursiveRequirement(@NotNull String line, @NotNull VirtualFile anchor, + private static List parseRecursiveRequirement(@NotNull String trimmedLine, @NotNull VirtualFile anchor, @NotNull Set visited) { - final Matcher matcher = RECURSIVE_REQUIREMENT.matcher(line); + final Matcher matcher = RECURSIVE_REQUIREMENT.matcher(trimmedLine); if (matcher.matches()) { final String fileName = FileUtil.toSystemIndependentName(matcher.group(1)); final VirtualFile dir = anchor.getParent(); diff --git a/python/testData/requirement/recursive/requirements.a.txt b/python/testData/requirement/recursive/requirements.a.txt new file mode 100644 index 000000000000..62f2aeb256b1 --- /dev/null +++ b/python/testData/requirement/recursive/requirements.a.txt @@ -0,0 +1 @@ +bitly_api \ No newline at end of file diff --git a/python/testData/requirement/recursive/requirements.b.txt b/python/testData/requirement/recursive/requirements.b.txt new file mode 100644 index 000000000000..296d654528b7 --- /dev/null +++ b/python/testData/requirement/recursive/requirements.b.txt @@ -0,0 +1 @@ +numpy \ No newline at end of file diff --git a/python/testData/requirement/recursive/requirements.txt b/python/testData/requirement/recursive/requirements.txt new file mode 100644 index 000000000000..5dd2b6032c34 --- /dev/null +++ b/python/testData/requirement/recursive/requirements.txt @@ -0,0 +1,2 @@ +-r requirements.a.txt +-rrequirements.b.txt \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyRequirementTest.java b/python/testSrc/com/jetbrains/python/PyRequirementTest.java index 75fb9a55e16f..eebb655e30b4 100644 --- a/python/testSrc/com/jetbrains/python/PyRequirementTest.java +++ b/python/testSrc/com/jetbrains/python/PyRequirementTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.jetbrains.python; +import com.intellij.openapi.vfs.VirtualFile; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.packaging.PyPackage; import com.jetbrains.python.packaging.PyRequirement; @@ -100,6 +101,15 @@ public class PyRequirementTest extends PyTestCase { PyRequirement.fromString("git+git://github.com/django/django.git@stable/1.5.x")); } + // PY-18543 + public void testRecursiveRequirement() { + final VirtualFile requirementsFile = getVirtualFileByName(getTestDataPath() + "/requirement/recursive/requirements.txt"); + assertNotNull(requirementsFile); + + assertEquals(list(new PyRequirement("bitly_api"), new PyRequirement("numpy")), + PyRequirement.parse(requirementsFile)); + } + private static List list(T... xs) { return Arrays.asList(xs); } From 45b735d71650ab8b87013f8eac958e71cc1a56ab Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Mon, 14 Mar 2016 15:01:25 +0300 Subject: [PATCH 16/16] PY-18684 Fixed: incorrect auto compleat for __rpow__ method Fix __rpow__ signature in PyNames --- python/psi-api/src/com/jetbrains/python/PyNames.java | 4 ++-- python/testData/completion/rPowSignature.after.py | 2 ++ python/testData/completion/rPowSignature.py | 2 ++ .../testSrc/com/jetbrains/python/PythonCompletionTest.java | 7 ++++++- 4 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 python/testData/completion/rPowSignature.after.py create mode 100644 python/testData/completion/rPowSignature.py diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java index d73539b2f8ef..95bb618b0cd0 100644 --- a/python/psi-api/src/com/jetbrains/python/PyNames.java +++ b/python/psi-api/src/com/jetbrains/python/PyNames.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -360,7 +360,7 @@ public class PyNames { .put("__rmod__", _self_other_descr) .put("__rmul__", _self_other_descr) .put("__ror__", _self_other_descr) - .put("__rpow__", new BuiltinDescription("(self, power, modulo=None)")) + .put("__rpow__", _self_other_descr) .put("__rrshift__", _self_other_descr) .put("__rshift__", _self_other_descr) .put("__rsub__", _self_other_descr) diff --git a/python/testData/completion/rPowSignature.after.py b/python/testData/completion/rPowSignature.after.py new file mode 100644 index 000000000000..986aea181170 --- /dev/null +++ b/python/testData/completion/rPowSignature.after.py @@ -0,0 +1,2 @@ +class Cl(object): + def __rpow__(self, other): \ No newline at end of file diff --git a/python/testData/completion/rPowSignature.py b/python/testData/completion/rPowSignature.py new file mode 100644 index 000000000000..128c85c9ee2f --- /dev/null +++ b/python/testData/completion/rPowSignature.py @@ -0,0 +1,2 @@ +class Cl(object): + def __rp \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index a1fddd101de9..7a86eea87a4a 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -981,6 +981,11 @@ public class PythonCompletionTest extends PyTestCase { doMultiFileTest(); } + // PY-18684 + public void testRPowSignature() { + doTest(); + } + @Override protected String getTestDataPath() { return super.getTestDataPath() + "/completion";