diff --git a/community-resources/src/idea_community_about.png b/community-resources/src/idea_community_about.png index d5e5a353e8ef..79fe896536ba 100644 Binary files a/community-resources/src/idea_community_about.png and b/community-resources/src/idea_community_about.png differ diff --git a/community-resources/src/idea_community_about@2x.png b/community-resources/src/idea_community_about@2x.png index 72bc8c68a9d5..d7ed6b89aeec 100644 Binary files a/community-resources/src/idea_community_about@2x.png and b/community-resources/src/idea_community_about@2x.png differ diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java index 6eedff4136ea..2696f226e412 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/QuickEvaluateActionHandler.java @@ -22,13 +22,13 @@ package com.intellij.debugger.actions; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.impl.DebuggerSession; -import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.ui.ValueHint; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint; import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler; import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import org.jetbrains.annotations.NotNull; import java.awt.*; @@ -53,6 +53,6 @@ public class QuickEvaluateActionHandler extends QuickEvaluateHandler { @Override public int getValueLookupDelay(final Project project) { - return DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY; + return XDebuggerSettingsManager.getInstance().getDataViewSettings().getValueLookupDelay(); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java index 56496b9aa1ca..bcd8257736c2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java @@ -27,7 +27,6 @@ import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.*; import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.settings.NodeRendererSettings; -import com.intellij.debugger.settings.ViewsGeneralSettings; import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.impl.FrameVariablesTree; import com.intellij.debugger.ui.impl.watch.*; @@ -47,6 +46,7 @@ import com.intellij.xdebugger.frame.XCompositeNode; import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.frame.XValueChildrenList; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import com.sun.jdi.*; import com.sun.jdi.event.Event; import com.sun.jdi.event.ExceptionEvent; @@ -271,7 +271,7 @@ public class JavaStackFrame extends XStackFrame { } try { - if (!ViewsGeneralSettings.getInstance().ENABLE_AUTO_EXPRESSIONS && !myAutoWatchMode) { + if (!XDebuggerSettingsManager.getInstance().getDataViewSettings().isAutoExpressions() && !myAutoWatchMode) { // optimization superBuildVariables(evaluationContext, children); } diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/Bytecodes.java b/java/debugger/impl/src/com/intellij/debugger/jdi/Bytecodes.java index 86fb655b0853..d6aa2372e720 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/Bytecodes.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/Bytecodes.java @@ -232,15 +232,16 @@ class Bytecodes { static { int i; byte[] b = new byte[220]; - String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" - + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA" - + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ"; - for (i = 0; i < b.length; ++i) { - b[i] = (byte) (s.charAt(i) - 'A'); - } - TYPE = b; + String s = + "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADDDDDEE" + + "EEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + + "AAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAAAAAAGGGGG" + + "GGHIFBFAAFFAARQJJKKJLMMGGGGGGGGGGGGHGAFFQFFGGG"; + for (i = 0; i < b.length; ++i) { + b[i] = (byte) (s.charAt(i) - 'A'); } + TYPE = b; + } static final int NOP = 0; // visitInsn @@ -446,4 +447,139 @@ class Bytecodes { static final int GOTO_W = 200; // - static final int JSR_W = 201; // - + // JVM runtime-specific and reserved opcodes: + // From JVM specification: + // In addition to the opcodes of the instructions specified later in this chapter, which are used in class files (§4), three opcodes are reserved for internal use by a Java Virtual Machine implementation. If the instruction set of the Java Virtual Machine is extended in the future, these reserved opcodes are guaranteed not to be used. + // Two of the reserved opcodes, numbers 254 (0xfe) and 255 (0xff), have the mnemonics impdep1 and impdep2, respectively. These instructions are intended to provide "back doors" or traps to implementation-specific functionality implemented in software and hardware, respectively. The third reserved opcode, number 202 (0xca), has the mnemonic breakpoint and is intended to be used by debuggers to implement breakpoints. + // Although these opcodes have been reserved, they may be used only inside a Java Virtual Machine implementation. They cannot appear in valid class files. Tools such as debuggers or JIT code generators (§2.13) that might directly interact with Java Virtual Machine code that has been already loaded and executed may encounter these opcodes. Such tools should attempt to behave gracefully if they encounter any of these reserved instructions. + + static final int BREAKPOINT = 202; + static final int LDC_QUICK = 203; + static final int LDC_W_QUICK = 204; + static final int LDC2_W_QUICK = 205; + static final int GETFIELD_QUICK = 206; + static final int PUTFIELD_QUICK = 207; + static final int GETFIELD2_QUICK = 208; + static final int PUTFIELD2_QUICK = 209; + static final int GETSTATIC_QUICK = 210; + static final int PUTSTATIC_QUICK = 211; + static final int GETSTATIC2_QUICK = 212; + static final int PUTSTATIC2_QUICK = 213; + static final int INVOKEVIRTUAL_QUICK = 214; + static final int INVOKENONVIRTUAL_QUICK = 215; + static final int INVOKESUPER_QUICK = 216; + static final int INVOKESTATIC_QUICK = 217; + static final int INVOKEINTERFACE_QUICK = 218; + static final int INVOKEVIRTUALOBJECT_QUICK = 219; + static final int NEW_QUICK = 221; + static final int ANEWARRAY_QUICK = 222; + static final int MULTIANEWARRAY_QUICK = 223; + static final int CHECKCAST_QUICK = 224; + static final int INSTANCEOF_QUICK = 225; + static final int INVOKEVIRTUAL_QUICK_W = 226; + static final int GETFIELD_QUICK_W = 227; + static final int PUTFIELD_QUICK_W = 228; + static final int IMPDEP1 = 254; + static final int IMPDEP2 = 255; + + public static void main(String[] args) { + int[] b = new int[229]; + //code to generate the above string + + // SBYTE_INSN instructions + b[NEWARRAY] = SBYTE_INSN; + b[BIPUSH] = SBYTE_INSN; + + // SHORT_INSN instructions + b[SIPUSH] = SHORT_INSN; + + // (IMPL)VAR_INSN instructions + b[RET] = VAR_INSN; + for (int i = ILOAD; i <= ALOAD; ++i) { + b[i] = VAR_INSN; + } + for (int i = ISTORE; i <= ASTORE; ++i) { + b[i] = VAR_INSN; + } + for (int i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3 + b[i] = IMPLVAR_INSN; + } + for (int i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3 + b[i] = IMPLVAR_INSN; + } + + // TYPE_INSN instructions + b[NEW] = TYPE_INSN; + b[ANEWARRAY] = TYPE_INSN; + b[CHECKCAST] = TYPE_INSN; + b[INSTANCEOF] = TYPE_INSN; + + // (Set)FIELDORMETH_INSN instructions + for (int i = GETSTATIC; i <= INVOKESTATIC; ++i) { + b[i] = FIELDORMETH_INSN; + } + b[INVOKEINTERFACE] = ITFMETH_INSN; + b[INVOKEDYNAMIC] = INDYMETH_INSN; + + // LABEL(W)_INSN instructions + for (int i = IFEQ; i <= JSR; ++i) { + b[i] = LABEL_INSN; + } + b[IFNULL] = LABEL_INSN; + b[IFNONNULL] = LABEL_INSN; + b[GOTO_W] = LABELW_INSN; // GOTO_W + b[JSR_W] = LABELW_INSN; // JSR_W + + b[BREAKPOINT] = LABEL_INSN; // todo: is this correct? + + // LDC(_W) instructions + b[LDC] = LDC_INSN; + b[LDC_W] = LDCW_INSN; // LDC_W + b[LDC2_W] = LDCW_INSN; // LDC2_W + + // special instructions + b[IINC] = IINC_INSN; + b[TABLESWITCH] = TABL_INSN; + b[LOOKUPSWITCH] = LOOK_INSN; + b[MULTIANEWARRAY] = MANA_INSN; + b[WIDE] = WIDE_INSN; // WIDE + + // runtime-specific + + b[LDC_QUICK] = LDC_INSN; // = 203; + b[LDC_W_QUICK] = LDCW_INSN; // = 204; + b[LDC2_W_QUICK] = LDCW_INSN; // = 205; + b[GETFIELD_QUICK] = FIELDORMETH_INSN; // = 206; + b[PUTFIELD_QUICK] = FIELDORMETH_INSN; // = 207; + + b[GETFIELD2_QUICK] = FIELDORMETH_INSN; // = 208; + b[PUTFIELD2_QUICK] = FIELDORMETH_INSN; // = 209; + b[GETSTATIC_QUICK] = FIELDORMETH_INSN; // = 210; + b[PUTSTATIC_QUICK] = FIELDORMETH_INSN; // = 211; + b[GETSTATIC2_QUICK] = FIELDORMETH_INSN; // = 212; + b[PUTSTATIC2_QUICK] = FIELDORMETH_INSN; // = 213; + b[INVOKEVIRTUAL_QUICK] = FIELDORMETH_INSN; // = 214; + b[INVOKENONVIRTUAL_QUICK] = FIELDORMETH_INSN; // = 215; + b[INVOKESUPER_QUICK] = FIELDORMETH_INSN; // = 216; + b[INVOKESTATIC_QUICK] = FIELDORMETH_INSN; // = 217; + b[INVOKEINTERFACE_QUICK] = ITFMETH_INSN; // = 218; + b[INVOKEVIRTUALOBJECT_QUICK] = FIELDORMETH_INSN; // = 219; + b[220] = Bytecodes.NOARG_INSN; // the ID is not used for any opcode + b[NEW_QUICK] = TYPE_INSN; // = 221; + b[ANEWARRAY_QUICK] = TYPE_INSN; // = 222; + b[MULTIANEWARRAY_QUICK] = MANA_INSN; // = 223; + b[CHECKCAST_QUICK] = TYPE_INSN; // = 224; + b[INSTANCEOF_QUICK] = TYPE_INSN; // = 225; + b[INVOKEVIRTUAL_QUICK_W] = FIELDORMETH_INSN; // = 226; + b[GETFIELD_QUICK_W] = FIELDORMETH_INSN; // = 227; + b[PUTFIELD_QUICK_W] = FIELDORMETH_INSN; // = 228; + + + for (int i = 0; i < b.length; ++i) { + System.err.print((char)('A' + b[i])); + } + System.err.println(); + + } + } diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/InstructionParser.java b/java/debugger/impl/src/com/intellij/debugger/jdi/InstructionParser.java index b8053a891d42..78bf10fe7e40 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/InstructionParser.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/InstructionParser.java @@ -38,7 +38,8 @@ public class InstructionParser { break; } int opcode = myCode[v] & 0xFF; - switch (Bytecodes.TYPE[opcode]) { + final byte opcodeType = opcode == Bytecodes.IMPDEP1 || opcode == Bytecodes.IMPDEP2? Bytecodes.NOARG_INSN : Bytecodes.TYPE[opcode]; + switch (opcodeType) { case Bytecodes.NOARG_INSN: v += 1; break; diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java index db01e13836ef..09c99729864b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java @@ -20,6 +20,7 @@ import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.ui.JavaDebuggerSupport; import com.intellij.debugger.ui.tree.render.ClassRenderer; import com.intellij.debugger.ui.tree.render.ToStringRenderer; +import com.intellij.openapi.options.OptionsBundle; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.registry.Registry; @@ -45,7 +46,6 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { private JCheckBox myCbAutoscroll; private JCheckBox myCbShowSyntheticFields; private StateRestoringCheckBox myCbShowValFieldsAsLocalVariables; - private JCheckBox myCbSort; private JCheckBox myCbHideNullArrayElements; private JCheckBox myCbShowStatic; private JCheckBox myCbShowDeclaredType; @@ -54,15 +54,13 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { private StateRestoringCheckBox myCbShowStaticFinalFields; private final ArrayRendererConfigurable myArrayRendererConfigurable; - private JCheckBox myCbEnableAutoExpressions; private JCheckBox myCbEnableAlternateViews; private JCheckBox myCbEnableToString; private JRadioButton myRbAllThatOverride; private JRadioButton myRbFromList; private ClassFilterEditor myToStringFilterEditor; - private JTextField myValueTooltipDelayField; - + private Project myProject; private RegistryCheckBox myAutoTooltip; @@ -71,16 +69,19 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { myArrayRendererConfigurable = new ArrayRendererConfigurable(NodeRendererSettings.getInstance().getArrayRenderer()); } + @Override public void disposeUIResources() { myArrayRendererConfigurable.disposeUIResources(); myToStringFilterEditor = null; myProject = null; } + @Override public String getDisplayName() { - return DebuggerBundle.message("base.renderer.configurable.display.name"); + return OptionsBundle.message("options.java.display.name"); } + @Override public JComponent createComponent() { if (myProject == null) { myProject = JavaDebuggerSupport.getContextProjectForEditorFieldsInDebuggerConfigurables(); @@ -90,13 +91,12 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { myCbAutoscroll = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.autoscroll")); myCbShowSyntheticFields = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.synthetic.fields")); myCbShowValFieldsAsLocalVariables = new StateRestoringCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.val.fields.as.locals")); - myCbSort = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.sort.alphabetically")); myCbHideNullArrayElements = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.hide.null.array.elements")); myCbShowStatic = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.static.fields")); myCbShowStaticFinalFields = new StateRestoringCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.static.final.fields")); myCbEnableAlternateViews = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.alternate.view")); - myCbEnableAutoExpressions = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.auto.expressions")); myCbShowStatic.addChangeListener(new ChangeListener(){ + @Override public void stateChanged(ChangeEvent e) { if(myCbShowStatic.isSelected()) { myCbShowStaticFinalFields.makeSelectable(); @@ -121,14 +121,15 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { myCbShowFQNames = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.fq.names")); myCbShowObjectId = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.show.object.id")); - myCbEnableToString = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.enable.tostring")); - myRbAllThatOverride = new JRadioButton(DebuggerBundle.message("label.base.renderer.configurable.all.overridding")); + myCbEnableToString = new JCheckBox(DebuggerBundle.message("label.base.renderer.configurable.enable.toString")); + myRbAllThatOverride = new JRadioButton(DebuggerBundle.message("label.base.renderer.configurable.all.overriding")); myRbFromList = new JRadioButton(DebuggerBundle.message("label.base.renderer.configurable.classes.from.list")); ButtonGroup group = new ButtonGroup(); group.add(myRbAllThatOverride); group.add(myRbFromList); myToStringFilterEditor = new ClassFilterEditor(myProject, null, "reference.viewBreakpoints.classFilters.newPattern"); myCbEnableToString.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { final boolean enabled = myCbEnableToString.isSelected(); myRbAllThatOverride.setEnabled(enabled); @@ -137,12 +138,12 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { } }); myRbFromList.addItemListener(new ItemListener() { + @Override public void itemStateChanged(ItemEvent e) { myToStringFilterEditor.setEnabled(myCbEnableToString.isSelected() && myRbFromList.isSelected()); } }); - panel.add(myCbSort, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); panel.add(myCbAutoscroll, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 0), 0, 0)); @@ -151,14 +152,6 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { DebuggerBundle.message("label.base.renderer.configurable.autoTooltip.description", Registry.stringValue("ide.forcedShowTooltip"))); panel.add(myAutoTooltip, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 0), 0, 0)); - - final JLabel tooltipLabel = new JLabel(DebuggerBundle.message("label.debugger.general.configurable.tooltips.delay")); - panel.add(tooltipLabel, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 0), 0, 0)); - myValueTooltipDelayField = new JTextField(10); - myValueTooltipDelayField.setMinimumSize(new Dimension(50, myValueTooltipDelayField.getPreferredSize().height)); - panel.add(myValueTooltipDelayField, new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 0), 0, 0)); - tooltipLabel.setLabelFor(myValueTooltipDelayField); - final JPanel showPanel = new JPanel(new GridBagLayout()); showPanel.setBorder(IdeBorderFactory.createTitledBorder("Show", true)); @@ -174,12 +167,12 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { final JPanel arraysPanel = new JPanel(new BorderLayout(0, UIUtil.DEFAULT_VGAP)); final JComponent arraysComponent = myArrayRendererConfigurable.createComponent(); + assert arraysComponent != null; arraysPanel.add(arraysComponent, BorderLayout.CENTER); arraysPanel.add(myCbHideNullArrayElements, BorderLayout.SOUTH); arraysPanel.setBorder(IdeBorderFactory.createTitledBorder("Arrays", true)); panel.add(arraysPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); - panel.add(myCbEnableAutoExpressions, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 10), 0, 0)); panel.add(myCbEnableAlternateViews, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 10), 0, 0)); // starting 4-th row panel.add(myCbEnableToString, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 0), 0, 0)); @@ -191,22 +184,16 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { return panel; } + @Override public void apply() { final ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance(); final NodeRendererSettings rendererSettings = NodeRendererSettings.getInstance(); - try { - DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY = Integer.parseInt(myValueTooltipDelayField.getText().trim()); - } - catch (NumberFormatException ignored) { - } generalSettings.AUTOSCROLL_TO_NEW_LOCALS = myCbAutoscroll.isSelected(); rendererSettings.setAlternateCollectionViewsEnabled(myCbEnableAlternateViews.isSelected()); generalSettings.HIDE_NULL_ARRAY_ELEMENTS = myCbHideNullArrayElements.isSelected(); - generalSettings.ENABLE_AUTO_EXPRESSIONS = myCbEnableAutoExpressions.isSelected(); final ClassRenderer classRenderer = rendererSettings.getClassRenderer(); - classRenderer.SORT_ASCENDING = myCbSort.isSelected(); classRenderer.SHOW_STATIC = myCbShowStatic.isSelected(); classRenderer.SHOW_STATIC_FINAL = myCbShowStaticFinalFields.isSelectedWhenSelectable(); classRenderer.SHOW_SYNTHETICS = myCbShowSyntheticFields.isSelected(); @@ -227,15 +214,14 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { rendererSettings.fireRenderersChanged(); } + @Override public void reset() { final ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance(); final NodeRendererSettings rendererSettings = NodeRendererSettings.getInstance(); - myValueTooltipDelayField.setText(Integer.toString(DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY)); myCbAutoscroll.setSelected(generalSettings.AUTOSCROLL_TO_NEW_LOCALS); myCbHideNullArrayElements.setSelected(generalSettings.HIDE_NULL_ARRAY_ELEMENTS); myCbEnableAlternateViews.setSelected(rendererSettings.areAlternateCollectionViewsEnabled()); - myCbEnableAutoExpressions.setSelected(generalSettings.ENABLE_AUTO_EXPRESSIONS); ClassRenderer classRenderer = rendererSettings.getClassRenderer(); @@ -244,7 +230,6 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { if (!classRenderer.SHOW_SYNTHETICS) { myCbShowValFieldsAsLocalVariables.makeUnselectable(false); } - myCbSort.setSelected(classRenderer.SORT_ASCENDING); myCbShowStatic.setSelected(classRenderer.SHOW_STATIC); myCbShowStaticFinalFields.setSelected(classRenderer.SHOW_STATIC_FINAL); if(!classRenderer.SHOW_STATIC) { @@ -268,24 +253,15 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { myArrayRendererConfigurable.reset(); } + @Override public boolean isModified() { - return areGeneralSettingsModified() || areDefaultRenderersModified() || areDebuggerSettingsModified(); - } - - private boolean areDebuggerSettingsModified() { - try { - return DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY != Integer.parseInt(myValueTooltipDelayField.getText().trim()); - } - catch (NumberFormatException ignored) { - } - return false; + return areGeneralSettingsModified() || areDefaultRenderersModified(); } private boolean areGeneralSettingsModified() { ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance(); return (generalSettings.AUTOSCROLL_TO_NEW_LOCALS != myCbAutoscroll.isSelected()) || - (generalSettings.ENABLE_AUTO_EXPRESSIONS != myCbEnableAutoExpressions.isSelected()) || (generalSettings.HIDE_NULL_ARRAY_ELEMENTS != myCbHideNullArrayElements.isSelected()) || myAutoTooltip.isChanged(); } @@ -297,7 +273,6 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { final ClassRenderer classRenderer = rendererSettings.getClassRenderer(); final boolean isClassRendererModified= - (classRenderer.SORT_ASCENDING != myCbSort.isSelected()) || (classRenderer.SHOW_STATIC != myCbShowStatic.isSelected()) || (classRenderer.SHOW_STATIC_FINAL != myCbShowStaticFinalFields.isSelectedWhenSelectable()) || (classRenderer.SHOW_SYNTHETICS != myCbShowSyntheticFields.isSelected()) || @@ -325,16 +300,20 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { return false; } + @SuppressWarnings("SpellCheckingInspection") + @Override @NotNull public String getHelpTopic() { return "reference.idesettings.debugger.dataviews"; } + @Override @NotNull public String getId() { return getHelpTopic(); } + @Override public Runnable enableSearch(String option) { return null; } diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSettings.java index a6aada62a61f..c682e3d5db87 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSettings.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSettings.java @@ -57,7 +57,6 @@ public class DebuggerSettings implements Cloneable, PersistentStateComponent { public boolean SHOW_OBJECTID = true; public boolean HIDE_NULL_ARRAY_ELEMENTS = true; public boolean AUTOSCROLL_TO_NEW_LOCALS = true; - public boolean ENABLE_AUTO_EXPRESSIONS = true; public ViewsGeneralSettings() { } @@ -41,22 +40,22 @@ public class ViewsGeneralSettings implements PersistentStateComponent { return ServiceManager.getService(ViewsGeneralSettings.class); } + @Override public void loadState(Element element) { try { DefaultJDOMExternalizer.readExternal(this, element); } - catch (InvalidDataException e) { - // ignore + catch (InvalidDataException ignored) { } } + @Override public Element getState() { Element element = new Element("ViewsGeneralSettings"); try { DefaultJDOMExternalizer.writeExternal(this, element); } - catch (WriteExternalException e) { - // ignore + catch (WriteExternalException ignored) { } return element; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index 630fa30339d2..0e5a9230fe72 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -42,12 +42,14 @@ import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider; import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler; import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; +import com.intellij.xdebugger.settings.XDebuggerSettings; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; /** * @author nik @@ -333,7 +335,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { //} } - public static class JavaDebuggerSettingsPanelProvider extends DebuggerSettingsPanelProvider { + final static class JavaDebuggerSettingsPanelProvider extends DebuggerSettingsPanelProvider { @Override public int getPriority() { return 1; @@ -344,11 +346,10 @@ public class JavaDebuggerSupport extends DebuggerSupport { return new DebuggerLaunchingConfigurable(); } + @NotNull @Override public Collection getConfigurables() { final ArrayList configurables = new ArrayList(); - configurables.add(new DebuggerDataViewsConfigurable(null)); - configurables.add(new DebuggerSteppingConfigurable()); configurables.add(new UserRenderersConfigurable(null)); configurables.add(new DebuggerHotswapConfigurable()); return configurables; @@ -358,6 +359,25 @@ public class JavaDebuggerSupport extends DebuggerSupport { public void apply() { NodeRendererSettings.getInstance().fireRenderersChanged(); } + + @NotNull + @Override + public Collection getConfigurable(@NotNull XDebuggerSettings.Category category) { + switch (category) { + case DATA_VIEWS: + return Collections.singletonList(new DebuggerDataViewsConfigurable(null)); + case STEPPING: + return Collections.singletonList(new DebuggerSteppingConfigurable()); + } + return Collections.emptyList(); + } + + @Override + public void applied(@NotNull XDebuggerSettings.Category category) { + if (category == XDebuggerSettings.Category.DATA_VIEWS) { + NodeRendererSettings.getInstance().fireRenderersChanged(); + } + } } public static Project getContextProjectForEditorFieldsInDebuggerConfigurables() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java index 09bf84e1a5bc..5d32e714ab89 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java @@ -53,6 +53,7 @@ import com.intellij.util.text.CharArrayUtil; import com.intellij.util.ui.tree.TreeModelAdapter; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.frame.XStackFrame; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import com.sun.jdi.*; import gnu.trove.TIntObjectHashMap; import gnu.trove.TObjectProcedure; @@ -157,7 +158,7 @@ public class FrameVariablesTree extends DebuggerTree { } try { - if (!ViewsGeneralSettings.getInstance().ENABLE_AUTO_EXPRESSIONS && !myAutoWatchMode) { + if (!XDebuggerSettingsManager.getInstance().getDataViewSettings().isAutoExpressions() && !myAutoWatchMode) { // optimization super.buildVariables(stackDescriptor, evaluationContext); } @@ -569,7 +570,7 @@ public class FrameVariablesTree extends DebuggerTree { myVars = vars; myPosition = position; myEvalContext = evalContext; - myCollectExpressions = ViewsGeneralSettings.getInstance().ENABLE_AUTO_EXPRESSIONS; + myCollectExpressions = XDebuggerSettingsManager.getInstance().getDataViewSettings().isAutoExpressions(); } @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java index fce05d1f23db..df91efed9579 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/TipManager.java @@ -15,7 +15,6 @@ */ package com.intellij.debugger.ui.impl; -import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.ide.FrameStateListener; import com.intellij.ide.FrameStateManager; import com.intellij.openapi.Disposable; @@ -32,6 +31,7 @@ import com.intellij.util.Alarm; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import javax.swing.*; import javax.swing.event.PopupMenuEvent; @@ -117,14 +117,17 @@ public class TipManager implements Disposable, PopupMenuListener { return menu; } + @Override public void popupMenuWillBecomeVisible(final PopupMenuEvent e) { myPopupShown = true; } + @Override public void popupMenuWillBecomeInvisible(final PopupMenuEvent e) { onPopupClosed(e); } + @Override public void popupMenuCanceled(final PopupMenuEvent e) { onPopupClosed(e); } @@ -174,12 +177,13 @@ public class TipManager implements Disposable, PopupMenuListener { myShowAlarm.cancelAllRequests(); myHideAlarm.cancelAllRequests(); myShowAlarm.addRequest(new Runnable() { + @Override public void run() { if (!myIsDisposed && !myPopupShown) { showTooltip(e, auto); } } - }, auto ? DebuggerSettings.getInstance().VALUE_LOOKUP_DELAY : 10); + }, auto ? XDebuggerSettingsManager.getInstance().getDataViewSettings().getValueLookupDelay() : 10); } private void showTooltip(InputEvent e, boolean auto) { @@ -245,6 +249,7 @@ public class TipManager implements Disposable, PopupMenuListener { myCurrentTooltip = null; } else { myHideAlarm.addRequest(new Runnable() { + @Override public void run() { if (myInsideComponent) { hideTooltip(true); @@ -273,10 +278,12 @@ public class TipManager implements Disposable, PopupMenuListener { myComponent = component; new UiNotifyConnector.Once(component, new Activatable() { + @Override public void showNotify() { installListeners(); } + @Override public void hideNotify() { } }); @@ -284,6 +291,7 @@ public class TipManager implements Disposable, PopupMenuListener { final HideTooltipAction hide = new HideTooltipAction(); hide.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)), myComponent); Disposer.register(this, new Disposable() { + @Override public void dispose() { hide.unregisterCustomShortcutSet(myComponent); } @@ -292,6 +300,7 @@ public class TipManager implements Disposable, PopupMenuListener { private class HideTooltipAction extends AnAction { + @Override public void actionPerformed(AnActionEvent e) { hideTooltip(true); } @@ -316,6 +325,7 @@ public class TipManager implements Disposable, PopupMenuListener { FrameStateManager.getInstance().addListener(myFrameStateListener); } + @Override public void dispose() { Disposer.dispose(this); @@ -333,6 +343,7 @@ public class TipManager implements Disposable, PopupMenuListener { private class MyAwtPreprocessor implements AWTEventListener { + @Override public void eventDispatched(AWTEvent event) { if (event.getID() == MouseEvent.MOUSE_MOVED) { preventFromHideIfInsideTooltip(event); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java index 52d557535917..d333eaaacd10 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java @@ -55,6 +55,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.SpeedSearchComparator; import com.intellij.ui.TreeSpeedSearch; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import com.sun.jdi.*; import com.sun.jdi.event.Event; import com.sun.jdi.event.ExceptionEvent; @@ -485,7 +486,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi try { buildVariables(stackDescriptor, evaluationContext); - if (classRenderer.SORT_ASCENDING) { + if (XDebuggerSettingsManager.getInstance().getDataViewSettings().isSortValues()) { Collections.sort(myChildren, NodeManagerImpl.getNodeComparator()); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java index bd14ef55b054..7fe89bb42299 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java @@ -38,6 +38,7 @@ import com.intellij.psi.PsiElementFactory; import com.intellij.psi.PsiExpression; import com.intellij.util.IncorrectOperationException; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import com.sun.jdi.*; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -58,7 +59,6 @@ public class ClassRenderer extends NodeRendererImpl{ public static final @NonNls String UNIQUE_ID = "ClassRenderer"; - public boolean SORT_ASCENDING = false; public boolean SHOW_SYNTHETICS = true; public boolean SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES = true; public boolean SHOW_STATIC = false; @@ -83,22 +83,27 @@ public class ClassRenderer extends NodeRendererImpl{ return typeName; } + @Override public String getUniqueId() { return UNIQUE_ID; } + @Override public boolean isEnabled() { return myProperties.isEnabled(); } + @Override public void setEnabled(boolean enabled) { myProperties.setEnabled(enabled); } + @Override public ClassRenderer clone() { return (ClassRenderer) super.clone(); } + @Override public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) throws EvaluateException { return calcLabel(descriptor); } @@ -151,6 +156,7 @@ public class ClassRenderer extends NodeRendererImpl{ } } + @Override public void buildChildren(final Value value, final ChildrenBuilder builder, final EvaluationContext evaluationContext) { DebuggerManagerThreadImpl.assertIsManagerThread(); final ValueDescriptorImpl parentDescriptor = (ValueDescriptorImpl)builder.getParentDescriptor(); @@ -171,7 +177,7 @@ public class ClassRenderer extends NodeRendererImpl{ children.add(nodeManager.createNode(nodeDescriptorFactory.getFieldDescriptor(parentDescriptor, objRef, field), evaluationContext)); } - if(SORT_ASCENDING) { + if (XDebuggerSettingsManager.getInstance().getDataViewSettings().isSortValues()) { Collections.sort(children, NodeManagerImpl.getNodeComparator()); } } @@ -211,16 +217,19 @@ public class ClassRenderer extends NodeRendererImpl{ return true; } + @Override public void readExternal(Element element) throws InvalidDataException { super.readExternal(element); DefaultJDOMExternalizer.readExternal(this, element); } + @Override public void writeExternal(Element element) throws WriteExternalException { super.writeExternal(element); DefaultJDOMExternalizer.writeExternal(this, element); } + @Override public PsiExpression getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) throws EvaluateException { FieldDescriptor fieldDescriptor = (FieldDescriptor)node.getDescriptor(); @@ -251,19 +260,23 @@ public class ClassRenderer extends NodeRendererImpl{ return false; } + @Override public boolean isExpandable(Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) { DebuggerManagerThreadImpl.assertIsManagerThread(); return valueExpandable(value); } + @Override public boolean isApplicable(Type type) { return type instanceof ReferenceType && !(type instanceof ArrayType); } + @Override public @NonNls String getName() { return "Object"; } + @Override public void setName(String text) { LOG.assertTrue(false); } diff --git a/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java b/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java index e3570c2c0fe5..ded07d482ed3 100644 --- a/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java +++ b/java/idea-ui/src/com/intellij/ide/actions/ShowStructureSettingsAction.java @@ -27,6 +27,7 @@ import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.Gray; +import com.intellij.ui.JBColor; import com.intellij.ui.border.CustomLineBorder; import org.jetbrains.annotations.Nullable; @@ -55,7 +56,7 @@ public class ShowStructureSettingsAction extends AnAction implements DumbAware { protected JComponent createSouthPanel() { JComponent panel = super.createSouthPanel(); assert panel != null; - CustomLineBorder line = new CustomLineBorder(Gray._153, 1, 0, 0, 0); + CustomLineBorder line = new CustomLineBorder(new JBColor(Gray._153, Gray._80), 1, 0, 0, 0); panel.setBorder(new CompoundBorder(line, new EmptyBorder(10, 5, 5, 5))); return panel; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ErrorPaneConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ErrorPaneConfigurable.java index 1ca83e0705d7..77ccbe6cbdff 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ErrorPaneConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ErrorPaneConfigurable.java @@ -45,9 +45,11 @@ public class ErrorPaneConfigurable extends JPanel implements Configurable, Dispo private final Alarm myAlarm; private final ArrayList myErrors = new ArrayList(); private final JTextPane myContent = new JTextPane(); + private Runnable myOnErrorsChanged; - public ErrorPaneConfigurable(final Project project, StructureConfigurableContext context) { + public ErrorPaneConfigurable(final Project project, StructureConfigurableContext context, Runnable onErrorsChanged) { super(new BorderLayout()); + myOnErrorsChanged = onErrorsChanged; myContent.setEditorKit(UIUtil.getHTMLEditorKit()); myContent.setEditable(false); myContent.setBackground(UIUtil.getListBackground()); @@ -148,6 +150,9 @@ public class ErrorPaneConfigurable extends JPanel implements Configurable, Dispo } html += ""; myContent.setText(html); + if (myOnErrorsChanged != null) { + myOnErrorsChanged.run(); + } } }, 100); } @@ -205,4 +210,8 @@ public class ErrorPaneConfigurable extends JPanel implements Configurable, Dispo myErrors.remove(error); refresh(); } + + public int getErrorsCount() { + return myErrors.size(); + } } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java index a5ae27a7a158..bf083f92c66c 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ProjectStructureConfigurable.java @@ -302,7 +302,12 @@ public class ProjectStructureConfigurable extends BaseConfigurable implements Se } private void addErrorPane() { - addConfigurable(new ErrorPaneConfigurable(myProject, myContext), true); + addConfigurable(new ErrorPaneConfigurable(myProject, myContext, new Runnable() { + @Override + public void run() { + mySidePanel.getList().repaint(); + } + }), true); } private void addGlobalLibrariesConfig() { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java index 14d696f3415b..290f35e561b5 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/SidePanel.java @@ -16,10 +16,13 @@ package com.intellij.openapi.roots.ui.configuration; import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.ui.GraphicsConfig; import com.intellij.openapi.ui.popup.ListItemDescriptor; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.*; import com.intellij.ui.components.JBList; +import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.ui.navigation.History; import com.intellij.ui.navigation.Place; import com.intellij.ui.popup.list.GroupedItemsListRenderer; @@ -29,6 +32,7 @@ import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; @@ -94,6 +98,8 @@ public class SidePanel extends JPanel { }; myList.setCellRenderer(new GroupedItemsListRenderer(descriptor) { + JPanel myExtraPanel; + CountLabel myCountLabel; { mySeparatorComponent.setCaptionCentered(false); } @@ -136,8 +142,38 @@ public class SidePanel extends JPanel { }; } + @Override + protected void layout() { + if (Registry.is("ide.new.project.settings")) { + myRendererComponent.add(mySeparatorComponent, BorderLayout.NORTH); + myExtraPanel.add(myComponent, BorderLayout.CENTER); + myExtraPanel.add(myCountLabel, BorderLayout.EAST); + myRendererComponent.add(myExtraPanel, BorderLayout.CENTER); + } else { + super.layout(); + } + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + myCountLabel.setText(""); + final Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if ("Problems".equals(descriptor.getTextFor(value))) { + final ErrorPaneConfigurable errorPane = (ErrorPaneConfigurable)((Place)value).getPath("category"); + if (errorPane != null && errorPane.getErrorsCount() > 0) { + myCountLabel.setSelected(isSelected); + myCountLabel.setText(String.valueOf(errorPane.getErrorsCount())); + } + } + return component; + } + @Override protected JComponent createItemComponent() { + myExtraPanel = new NonOpaquePanel(new BorderLayout()); + myCountLabel = new CountLabel(); + + if (Registry.is("ide.new.project.settings")) { myTextLabel = new EngravedLabel(); myTextLabel.setFont(myTextLabel.getFont().deriveFont(Font.BOLD)); @@ -169,6 +205,10 @@ public class SidePanel extends JPanel { }); } + public JList getList() { + return myList; + } + public void addPlace(Place place, @NotNull Presentation presentation) { myModel.addElement(place); myPlaces.add(place); @@ -188,4 +228,51 @@ public class SidePanel extends JPanel { public void select(final Place place) { myList.setSelectedValue(place, true); } + + private static class CountLabel extends JLabel { + private boolean mySelected; + + public CountLabel() { + super(); + setBorder(new Border() { + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + } + + @Override + public Insets getBorderInsets(Component c) { + return StringUtil.isEmpty(getText()) ? new Insets(0,0,0,0) : new Insets(2, 6, 2, 6 + 6); + } + + @Override + public boolean isBorderOpaque() { + return false; + } + }); + setFont(UIUtil.getListFont().deriveFont(Font.BOLD)); + } + + public boolean isSelected() { + return mySelected; + } + + public void setSelected(boolean selected) { + mySelected = selected; + } + + @Override + protected void paintComponent(Graphics g) { + g.setColor(isSelected() ? UIUtil.getListSelectionBackground() : UIUtil.getSidePanelColor()); + g.fillRect(0, 0, getWidth(), getHeight()); + if (StringUtil.isEmpty(getText())) return; + final JBColor deepBlue = new JBColor(new Color(0x97A4B2), new Color(92, 98, 113)); + g.setColor(isSelected() ? Gray._255.withAlpha(UIUtil.isUnderDarcula() ? 100 : 220) : deepBlue); + final GraphicsConfig config = GraphicsUtil.setupAAPainting(g); + g.fillRoundRect(0, 3, getWidth() - 6 -1, getHeight()-6 , (getHeight() - 6), (getHeight() - 6)); + config.restore(); + setForeground(isSelected() ? deepBlue.darker() : UIUtil.getListForeground(true)); + + super.paintComponent(g); + } + } } diff --git a/java/java-analysis-impl/java-analysis-impl.iml b/java/java-analysis-impl/java-analysis-impl.iml index 28987be6d459..95c129baadfb 100644 --- a/java/java-analysis-impl/java-analysis-impl.iml +++ b/java/java-analysis-impl/java-analysis-impl.iml @@ -18,7 +18,6 @@ - diff --git a/java/java-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java similarity index 100% rename from java/java-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java rename to java/java-analysis-impl/src/com/intellij/codeInsight/InferredAnnotationsManagerImpl.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java index 0ccad5cadf48..9fc35a649504 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddTypeCastFix.java @@ -31,6 +31,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import org.jetbrains.annotations.NotNull; @@ -91,6 +92,7 @@ public class AddTypeCastFix extends LocalQuickFixAndIntentionActionOnPsiElement String text = "(" + type.getCanonicalText(false) + ")value"; PsiElementFactory factory = JavaPsiFacade.getInstance(original.getProject()).getElementFactory(); PsiTypeCastExpression typeCast = (PsiTypeCastExpression)factory.createExpressionFromText(text, original); + typeCast = (PsiTypeCastExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(typeCast); typeCast = (PsiTypeCastExpression)CodeStyleManager.getInstance(project).reformat(typeCast); if (expression instanceof PsiConditionalExpression) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java index 96066c34eefe..c1f127d3a1df 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java @@ -32,10 +32,7 @@ import com.intellij.psi.controlFlow.ControlFlow; import com.intellij.psi.controlFlow.ControlFlowUtil; import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.psi.infos.MethodCandidateInfo; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiTypesUtil; -import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.*; import com.intellij.util.ArrayUtilRt; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtilRt; @@ -91,16 +88,12 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection final PsiMethod[] methods = aClass.getMethods(); if (methods.length == 1 && aClass.getFields().length == 0) { final PsiCodeBlock body = methods[0].getBody(); - if (body != null) { - final ForbiddenRefsChecker checker = new ForbiddenRefsChecker(methods[0], aClass); - body.accept(checker); - if (!checker.hasForbiddenRefs()) { - final PsiElement lBrace = aClass.getLBrace(); - LOG.assertTrue(lBrace != null); - final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); - holder.registerProblem(aClass.getParent(), "Anonymous #ref #loc can be replaced with lambda", - ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithLambdaFix()); - } + if (body != null && !hasForbiddenRefsInsideBody(methods[0], aClass)) { + final PsiElement lBrace = aClass.getLBrace(); + LOG.assertTrue(lBrace != null); + final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); + holder.registerProblem(aClass.getParent(), "Anonymous #ref #loc can be replaced with lambda", + ProblemHighlightType.LIKE_UNUSED_SYMBOL, rangeInElement, new ReplaceWithLambdaFix()); } } } @@ -110,6 +103,14 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection }; } + public static boolean hasForbiddenRefsInsideBody(PsiMethod method, PsiAnonymousClass aClass) { + final ForbiddenRefsChecker checker = new ForbiddenRefsChecker(method, aClass); + final PsiCodeBlock body = method.getBody(); + LOG.assertTrue(body != null); + body.accept(checker); + return checker.hasForbiddenRefs(); + } + private static PsiType getInferredType(PsiAnonymousClass aClass) { final PsiExpression expression = (PsiExpression)aClass.getParent(); final PsiType psiType = PsiTypesUtil.getExpectedTypeByParent(expression); @@ -369,14 +370,14 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection private final PsiMethod myMethod; private final PsiAnonymousClass myAnonymClass; - private final boolean myRawType; + private final boolean myEqualInference; public ForbiddenRefsChecker(PsiMethod method, PsiAnonymousClass aClass) { myMethod = method; myAnonymClass = aClass; final PsiType inferredType = getInferredType(aClass); - myRawType = inferredType instanceof PsiClassType && ((PsiClassType)inferredType).isRaw(); + myEqualInference = !aClass.getBaseClassType().equals(inferredType); } @Override @@ -467,7 +468,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection } } - if (myRawType) { + if (myEqualInference) { final PsiElement resolved = expression.resolve(); if (resolved instanceof PsiParameter && ((PsiParameter)resolved).getDeclarationScope() == myMethod) { final int parameterIndex = myMethod.getParameterList().getParameterIndex((PsiParameter)resolved); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java index d6a884c8917c..c3363ec7eb12 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -69,7 +69,7 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI final PsiClassType baseClassType = aClass.getBaseClassType(); if (LambdaUtil.isFunctionalType(baseClassType)) { final PsiMethod[] methods = aClass.getMethods(); - if (methods.length == 1 && aClass.getFields().length == 0) { + if (methods.length == 1 && aClass.getFields().length == 0 && !AnonymousCanBeLambdaInspection.hasForbiddenRefsInsideBody(methods[0], aClass)) { final PsiCodeBlock body = methods[0].getBody(); final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java index 1e887030dcb4..416226e9ac8f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -245,11 +245,14 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp PsiParameter[] candidateParams = method.getParameterList().getParameters(); if (candidateParams.length == 1) { if (TypeConversionUtil.areTypesConvertible(candidateParams[0].getType(), parameters[0].getType())) { - for (PsiMethod superMethod : psiMethod.findDeepestSuperMethods()) { - PsiMethod validSuperMethod = ensureNonAmbiguousMethod(parameters, superMethod); - if (validSuperMethod != null) return validSuperMethod; + final PsiMethod[] deepestSuperMethods = psiMethod.findDeepestSuperMethods(); + if (deepestSuperMethods.length > 0) { + for (PsiMethod superMethod : deepestSuperMethods) { + PsiMethod validSuperMethod = ensureNonAmbiguousMethod(parameters, superMethod); + if (validSuperMethod != null) return validSuperMethod; + } + return null; } - return null; } } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java index 38eaf83dbe2a..f29dd7f6cf0c 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisConverter.java @@ -263,11 +263,12 @@ public class BytecodeAnalysisConverter implements ApplicationComponent { private int mkPsiClassKey(PsiClass psiClass, int dimensions) throws IOException { - PsiClassOwner psiFile = (PsiClassOwner) psiClass.getContainingFile(); - if (psiFile == null) { - LOG.debug("getContainingFile was null for " + psiClass.getQualifiedName()); + PsiFile containingFile = psiClass.getContainingFile(); + if (!(containingFile instanceof PsiClassOwner)) { + LOG.debug("containingFile was not resolved for " + psiClass.getQualifiedName()); return -1; } + PsiClassOwner psiFile = (PsiClassOwner)containingFile; String packageName = psiFile.getPackageName(); String qname = psiClass.getQualifiedName(); if (qname == null) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java index a6aa2ac784e3..6a4b32783c95 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIndex.java @@ -15,9 +15,9 @@ */ package com.intellij.codeInspection.bytecodeAnalysis; +import com.intellij.ide.highlighter.JavaClassFileType; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileWithId; import com.intellij.util.SystemProperties; @@ -82,7 +82,7 @@ public class BytecodeAnalysisIndex extends FileBasedIndexExtensioncreateFunction(null)), getTargetSubstitutor(expression), CreateFromUsageUtils.guessExpectedTypes(expression, true), @@ -213,7 +214,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix { public static void doCreate(PsiClass targetClass, PsiMethod method, List> arguments, PsiSubstitutor substitutor, ExpectedTypeInfo[] expectedTypes, @Nullable PsiElement context) { - doCreate(targetClass, method, shouldBeAbstractImpl(targetClass), arguments, substitutor, expectedTypes, context); + doCreate(targetClass, method, shouldBeAbstractImpl(null, targetClass), arguments, substitutor, expectedTypes, context); } public static void doCreate(PsiClass targetClass, @@ -340,12 +341,12 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix { return false; } - protected boolean shouldBeAbstract(PsiClass targetClass) { - return shouldBeAbstractImpl(targetClass); + protected boolean shouldBeAbstract(PsiReferenceExpression expression, PsiClass targetClass) { + return shouldBeAbstractImpl(expression, targetClass); } - private static boolean shouldBeAbstractImpl(PsiClass targetClass) { - return targetClass.isInterface(); + private static boolean shouldBeAbstractImpl(PsiReferenceExpression expression, PsiClass targetClass) { + return targetClass.isInterface() && (expression == null || !shouldCreateStaticMember(expression, targetClass)); } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java index 4236da3187fc..fe4208deada7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateDelegateHandler.java @@ -251,11 +251,22 @@ public class GenerateDelegateHandler implements LanguageCodeInsightActionHandler final Set existingSignatures = new HashSet(aClass.getVisibleSignatures()); final Set selection = new HashSet(); Map superSubstitutors = new HashMap(); + + final PsiClass containingClass = targetMember.getContainingClass(); JavaPsiFacade facade = JavaPsiFacade.getInstance(target.getProject()); for (PsiMethod method : allMethods) { final PsiClass superClass = method.getContainingClass(); if (CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) continue; if (method.isConstructor()) continue; + + //do not suggest to override final method + if (method.hasModifierProperty(PsiModifier.FINAL)) { + PsiMethod overridden = containingClass.findMethodBySignature(method, true); + if (overridden != null && overridden.getContainingClass() != containingClass) { + continue; + } + } + PsiSubstitutor superSubstitutor = superSubstitutors.get(superClass); if (superSubstitutor == null) { superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, targetClass, substitutor); diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java index ec771e43c073..1c1957bcf472 100644 --- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java @@ -29,15 +29,23 @@ public class JavaMethodParameterUnwrapper extends JavaUnwrapper { super(""); } + private static PsiElement adjustElementToTheLeft(PsiElement element) { + if (element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == JavaTokenType.RPARENTH) { + return element.getPrevSibling(); + } + return element; + } + @Override public String getDescription(PsiElement e) { - String text = e.getText(); + String text = adjustElementToTheLeft(e).getText(); if (text.length() > 20) text = text.substring(0, 17) + "..."; return CodeInsightBundle.message("unwrap.with.placeholder", text); } @Override public boolean isApplicableTo(PsiElement e) { + e = adjustElementToTheLeft(e); final PsiElement parent = e.getParent(); if (e instanceof PsiExpression){ if (parent instanceof PsiExpressionList) { @@ -62,6 +70,7 @@ public class JavaMethodParameterUnwrapper extends JavaUnwrapper { @Override public PsiElement collectAffectedElements(PsiElement e, List toExtract) { + e = adjustElementToTheLeft(e); super.collectAffectedElements(e, toExtract); return isTopLevelCall(e) ? e.getParent() : e.getParent().getParent(); } @@ -73,6 +82,7 @@ public class JavaMethodParameterUnwrapper extends JavaUnwrapper { @Override protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + element = adjustElementToTheLeft(element); PsiElement methodCall = isTopLevelCall(element) ? element.getParent() : element.getParent().getParent(); final PsiElement extractedElement = isTopLevelCall(element) ? getArg(element) : element; context.extractElement(extractedElement, methodCall); diff --git a/java/java-impl/src/com/intellij/ide/util/PackageUtil.java b/java/java-impl/src/com/intellij/ide/util/PackageUtil.java index be9405ee4754..0530f34e653a 100644 --- a/java/java-impl/src/com/intellij/ide/util/PackageUtil.java +++ b/java/java-impl/src/com/intellij/ide/util/PackageUtil.java @@ -24,14 +24,12 @@ import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.projectRoots.impl.ProjectRootUtil; -import com.intellij.openapi.roots.ModulePackageIndex; -import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.ProjectFileIndex; -import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.ui.configuration.CommonContentEntriesEditor; import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -52,13 +50,29 @@ public class PackageUtil { @Nullable public static PsiDirectory findPossiblePackageDirectoryInModule(Module module, String packageName) { + return findPossiblePackageDirectoryInModule(module, packageName, true); + } + @Nullable + public static PsiDirectory findPossiblePackageDirectoryInModule(Module module, String packageName, boolean preferNonGeneratedRoots) { + final Project project = module.getProject(); PsiDirectory psiDirectory = null; - if (!"".equals(packageName)) { - PsiPackage rootPackage = findLongestExistingPackage(module.getProject(), packageName); + if (!StringUtil.isEmptyOrSpaces(packageName)) { + PsiPackage rootPackage = findLongestExistingPackage(project, packageName); if (rootPackage != null) { final PsiDirectory[] psiDirectories = getPackageDirectoriesInModule(rootPackage, module); if (psiDirectories.length > 0) { psiDirectory = psiDirectories[0]; + + // If we prefer to find a non-generated PsiDirectory for the given package name, search through all + // the directories for the first dir not marked as generated and use that one instead + if (preferNonGeneratedRoots && psiDirectories.length > 1) { + for (PsiDirectory dir : psiDirectories) { + if (!GeneratedSourcesFilter.isGeneratedSourceByAnyFilter(dir.getVirtualFile(), project)) { + psiDirectory = dir; + break; + } + } + } } } } @@ -66,7 +80,7 @@ public class PackageUtil { if (checkSourceRootsConfigured(module)) { final List sourceRoots = ModuleRootManager.getInstance(module).getSourceRoots(JavaModuleSourceRootTypes.SOURCES); for (VirtualFile sourceRoot : sourceRoots) { - final PsiDirectory directory = PsiManager.getInstance(module.getProject()).findDirectory(sourceRoot); + final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(sourceRoot); if (directory != null) { psiDirectory = directory; break; diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java index c1bc3bf60038..ce19d6bacaa5 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/AutocreatingSingleSourceRootMoveDestination.java @@ -102,6 +102,6 @@ public class AutocreatingSingleSourceRootMoveDestination extends AutocreatingMov if (myTargetDirectory == null) { myTargetDirectory = RefactoringUtil.createPackageDirectoryInSourceRoot(myPackage, mySourceRoot); } - return RefactoringUtil.createPackageDirectoryInSourceRoot(myPackage, mySourceRoot); + return myTargetDirectory; } } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java index 9f5ecb109fd5..5e008afb4797 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java @@ -45,7 +45,6 @@ import com.intellij.psi.util.*; import com.intellij.util.Function; import com.intellij.util.ObjectUtils; import com.intellij.util.text.CharArrayUtil; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -701,7 +700,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem else if (element instanceof PsiComment) { return settings.isCollapseEndOfLineComments(); } - else if (isLiteralExpression(element) + else if (ParameterNameFoldingManager.isLiteralExpression(element) && element.getParent() instanceof PsiExpressionList && (element.getParent().getParent() instanceof PsiCallExpression || element.getParent().getParent() instanceof PsiAnonymousClass)) { @@ -760,55 +759,8 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem if (quick || !JavaCodeFoldingSettings.getInstance().isInlineParameterNamesForLiteralCallArguments()) { return; } - PsiExpressionList callArgumentsList = expression.getArgumentList(); - if (callArgumentsList == null) { - return; - } - - PsiExpression[] callArguments = callArgumentsList.getExpressions(); - if (callArguments.length > 1) { - PsiParameter[] parameters = null; - boolean isResolved = false; - - for (int i = 0; i < callArguments.length; i++) { - PsiExpression callArgument = callArguments[i]; - - if (callArgument.getType() != null && isLiteralExpression(callArgument)) { - if (!isResolved) { - PsiMethod method = expression.resolveMethod(); - isResolved = true; - if (method == null) { - return; - } - parameters = method.getParameterList().getParameters(); - if (parameters.length != callArguments.length) { - return; - } - } - - PsiParameter methodParam = parameters[i]; - if (TypeConversionUtil.isAssignable(methodParam.getType(), callArgument.getType())) { - TextRange range = callArgument.getTextRange(); - String placeholderText = methodParam.getName() + ": " + callArgument.getText(); - foldElements.add(new NamedFoldingDescriptor(callArgument, range.getStartOffset(), range.getEndOffset(), null, placeholderText)); - } - } - } - } - } - - @Contract("null -> false") - private static boolean isLiteralExpression(@Nullable PsiElement callArgument) { - if (callArgument instanceof PsiLiteralExpression) - return true; - - if (callArgument instanceof PsiPrefixExpression) { - PsiPrefixExpression expr = (PsiPrefixExpression)callArgument; - IElementType tokenType = expr.getOperationTokenType(); - return JavaTokenType.MINUS.equals(tokenType) && expr.getOperand() instanceof PsiLiteralExpression; - } - - return false; + ParameterNameFoldingManager manager = new ParameterNameFoldingManager(expression); + foldElements.addAll(manager.buildDescriptors()); } private boolean addClosureFolding(final PsiClass aClass, final Document document, final List foldElements, diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java new file mode 100644 index 000000000000..f643e9ee1110 --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/ParameterNameFoldingManager.java @@ -0,0 +1,154 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.folding.impl; + +import com.intellij.lang.folding.FoldingDescriptor; +import com.intellij.lang.folding.NamedFoldingDescriptor; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.TypeConversionUtil; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class ParameterNameFoldingManager { + private static final int MIN_NAME_LENGTH_THRESHOLD = 3; + private static final int MIN_ARGS_TO_FOLD = 2; + + private static final String[] RANGE_START_WORDS = { + "begin", "start", "from", "first" + }; + private static final String[] RANGE_END_WORDS = { + "end", "to", "last" + }; + + private final PsiCallExpression myCallExpression; + + private PsiExpression[] myCallArguments; + private PsiParameter[] myParameters; + + public ParameterNameFoldingManager(@NotNull PsiCallExpression callExpression) { + myCallExpression = callExpression; + } + + public static boolean isLiteralExpression(@Nullable PsiElement callArgument) { + if (callArgument instanceof PsiLiteralExpression) + return true; + + if (callArgument instanceof PsiPrefixExpression) { + PsiPrefixExpression expr = (PsiPrefixExpression)callArgument; + IElementType tokenType = expr.getOperationTokenType(); + return JavaTokenType.MINUS.equals(tokenType) && expr.getOperand() instanceof PsiLiteralExpression; + } + + return false; + } + + @Nullable + public PsiExpression[] getArguments(@NotNull PsiCallExpression call) { + PsiExpressionList callArgumentsList = call.getArgumentList(); + return callArgumentsList != null ? callArgumentsList.getExpressions() : null; + } + + @NotNull + public List buildDescriptors() { + myCallArguments = getArguments(myCallExpression); + + if (myCallArguments != null && myCallArguments.length >= MIN_ARGS_TO_FOLD && hasLiteralExpression(myCallArguments)) { + PsiMethod method = myCallExpression.resolveMethod(); + + if (method != null) { + myParameters = method.getParameterList().getParameters(); + if (myParameters.length == myCallArguments.length) { + return buildDescriptorsForLiteralArguments(); + } + } + } + + return ContainerUtil.emptyList(); + } + + @NotNull + private List buildDescriptorsForLiteralArguments() { + List descriptors = ContainerUtil.newArrayList(); + + int i = 0; + while (i < myCallArguments.length) { + if (i + 1 < myCallArguments.length && isCommonlyNamedParameterPair(i, i + 1)) { + i += 2; + continue; + } + + if (shouldInlineParameterName(i)) { + descriptors.add(createFoldingDescriptor(myCallArguments[i], myParameters[i])); + } + i++; + } + + return descriptors; + } + + @NotNull + private static NamedFoldingDescriptor createFoldingDescriptor(@NotNull PsiExpression callArgument, @NotNull PsiParameter methodParam) { + TextRange range = callArgument.getTextRange(); + String placeholderText = methodParam.getName() + ": " + callArgument.getText(); + return new NamedFoldingDescriptor(callArgument, range.getStartOffset(), range.getEndOffset(), null, placeholderText); + } + + private boolean isCommonlyNamedParameterPair(int first, int second) { + assert first < myParameters.length && second < myParameters.length; + + String firstParamName = myParameters[first].getName(); + String secondParamName = myParameters[second].getName(); + if (firstParamName == null || secondParamName == null) return false; + + if (containsAnyWord(firstParamName, RANGE_START_WORDS) && containsAnyWord(secondParamName, RANGE_END_WORDS)) { + return true; + } + + return false; + } + + private static boolean containsAnyWord(@NotNull String str, @NotNull String[] words) { + for (String word : words) { + if (StringUtil.containsIgnoreCase(str, word)) return true; + } + return false; + } + + private boolean shouldInlineParameterName(int paramIndex) { + PsiExpression argument = myCallArguments[paramIndex]; + if (isLiteralExpression(argument) && argument.getType() != null) { + PsiParameter parameter = myParameters[paramIndex]; + String paramName = parameter.getName(); + if (paramName != null && paramName.length() >= MIN_NAME_LENGTH_THRESHOLD) { + return TypeConversionUtil.isAssignable(parameter.getType(), argument.getType()); + } + } + return false; + } + + private static boolean hasLiteralExpression(@NotNull PsiExpression[] arguments) { + for (PsiExpression argument : arguments) { + if (isLiteralExpression(argument)) return true; + } + return false; + } +} diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index eefe8cf393ac..f80457c676b8 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -218,6 +218,7 @@ public class JavaDocInfoGenerator { LOG.debug(text); } + text = StringUtil.replaceIgnoreCase(text, "

", "

"); return StringUtil.replace(text, "/>", ">"); } diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java index 54e493126c1c..36d024726bbf 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java @@ -46,6 +46,8 @@ public class DeclarationParser { JavaTokenType.IDENTIFIER, JavaTokenType.COMMA, JavaTokenType.THROWS_KEYWORD); private static final TokenSet PARAM_LIST_STOPPERS = TokenSet.create( JavaTokenType.RPARENTH, JavaTokenType.LBRACE, JavaTokenType.ARROW); + private static final TokenSet TYPE_START = TokenSet.orSet( + ElementType.PRIMITIVE_TYPE_BIT_SET, TokenSet.create(JavaTokenType.IDENTIFIER, JavaTokenType.AT)); private static final String WHITESPACES = "\n\r \t"; private static final String LINE_ENDS = "\n\r"; @@ -278,56 +280,64 @@ public class DeclarationParser { return modList; } - PsiBuilder.Marker type; - if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(builder.getTokenType())) { - type = parseTypeNotNull(builder); - } - else if (builder.getTokenType() == JavaTokenType.IDENTIFIER /*|| builder.getTokenType() == JavaTokenType.AT*/) { - PsiBuilder.Marker idPos = builder.mark(); - type = parseTypeNotNull(builder); - if (builder.getTokenType() == JavaTokenType.LPARENTH) { // constructor - if (context == Context.CODE_BLOCK) { - declaration.rollbackTo(); - return null; - } - idPos.rollbackTo(); - if (typeParams == null) { - emptyElement(builder, JavaElementType.TYPE_PARAMETER_LIST); - } - builder.advanceLexer(); - if (builder.getTokenType() != JavaTokenType.LPARENTH) { - declaration.rollbackTo(); - return null; - } - return parseMethodFromLeftParenth(builder, declaration, false, true); - } - idPos.drop(); - } - else if (builder.getTokenType() == JavaTokenType.LBRACE) { + if (builder.getTokenType() == JavaTokenType.LBRACE) { if (context == Context.CODE_BLOCK) { error(builder, JavaErrorMessages.message("expected.identifier.or.type"), typeParams); declaration.drop(); return modList; } - final PsiBuilder.Marker codeBlock = myParser.getStatementParser().parseCodeBlock(builder); + PsiBuilder.Marker codeBlock = myParser.getStatementParser().parseCodeBlock(builder); assert codeBlock != null : builder.getOriginalText(); if (typeParams != null) { - final PsiBuilder.Marker error = typeParams.precede(); + PsiBuilder.Marker error = typeParams.precede(); error.errorBefore(JavaErrorMessages.message("unexpected.token"), codeBlock); } + done(declaration, JavaElementType.CLASS_INITIALIZER); return declaration; } - else { - final PsiBuilder.Marker error; - if (typeParams != null) { - error = typeParams.precede(); + + PsiBuilder.Marker type = null; + + if (TYPE_START.contains(builder.getTokenType())) { + PsiBuilder.Marker pos = builder.mark(); + + type = myParser.getReferenceParser().parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD); + + if (type == null) { + pos.rollbackTo(); + } + else if (builder.getTokenType() == JavaTokenType.LPARENTH) { // constructor + if (context == Context.CODE_BLOCK) { + declaration.rollbackTo(); + return null; + } + + pos.rollbackTo(); + + if (typeParams == null) { + emptyElement(builder, JavaElementType.TYPE_PARAMETER_LIST); + } + parseAnnotations(builder); + builder.advanceLexer(); + + if (builder.getTokenType() == JavaTokenType.LPARENTH) { + return parseMethodFromLeftParenth(builder, declaration, false, true); + } + else { + declaration.rollbackTo(); + return null; + } } else { - error = builder.mark(); + pos.drop(); } + } + + if (type == null) { + PsiBuilder.Marker error = typeParams != null ? typeParams.precede() : builder.mark(); error.error(JavaErrorMessages.message("expected.identifier.or.type")); declaration.drop(); return modList; @@ -363,13 +373,6 @@ public class DeclarationParser { return parseFieldOrLocalVariable(builder, declaration, declarationStart, context); } - @NotNull - private PsiBuilder.Marker parseTypeNotNull(final PsiBuilder builder) { - final PsiBuilder.Marker type = myParser.getReferenceParser().parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD); - assert type != null : builder.getOriginalText(); - return type; - } - @NotNull public Pair parseModifierList(final PsiBuilder builder) { return parseModifierList(builder, ElementType.MODIFIER_BIT_SET); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaImportStatementElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaImportStatementElementType.java index 7c9af30f1d9b..93e359e6778a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaImportStatementElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaImportStatementElementType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 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. @@ -24,7 +24,7 @@ import com.intellij.psi.impl.java.stubs.impl.PsiImportStatementStubImpl; import com.intellij.psi.impl.source.PsiImportStatementImpl; import com.intellij.psi.impl.source.PsiImportStaticStatementImpl; import com.intellij.psi.impl.source.tree.JavaElementType; -import com.intellij.psi.impl.source.tree.SourceUtil; +import com.intellij.psi.impl.source.tree.JavaSourceUtil; import com.intellij.psi.impl.source.tree.java.ImportStaticStatementElement; import com.intellij.psi.stubs.IndexSink; import com.intellij.psi.stubs.StubElement; @@ -68,7 +68,7 @@ public abstract class JavaImportStatementElementType extends JavaStubElementType for (LighterASTNode child : tree.getChildren(node)) { IElementType type = child.getTokenType(); if (type == JavaElementType.JAVA_CODE_REFERENCE || type == JavaElementType.IMPORT_STATIC_REFERENCE) { - refText = SourceUtil.getReferenceText(tree, child); + refText = JavaSourceUtil.getReferenceText(tree, child); } else if (type == JavaTokenType.ASTERISK) { isOnDemand = true; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java index ff8c80db3729..3413fda3a3fe 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaLightStubBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 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. @@ -44,7 +44,7 @@ public class JavaLightStubBuilder extends LightStubBuilder { if (pkg != null) { LighterASTNode ref = LightTreeUtil.firstChildOfType(tree, pkg, JavaElementType.JAVA_CODE_REFERENCE); if (ref != null) { - refText = SourceUtil.getReferenceText(tree, ref); + refText = JavaSourceUtil.getReferenceText(tree, ref); } } return new PsiJavaFileStubImpl((PsiJavaFile)file, StringRef.fromString(refText), false); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java index 20ee0c571400..807b42d60383 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -751,7 +751,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme private String getNormalizedText() { String whiteSpaceAndComments = myCachedNormalizedText; if (whiteSpaceAndComments == null) { - myCachedNormalizedText = whiteSpaceAndComments = SourceUtil.getReferenceText(this); + myCachedNormalizedText = whiteSpaceAndComments = JavaSourceUtil.getReferenceText(this); } return whiteSpaceAndComments; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index cd11b21475ef..6098199c591c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -379,7 +379,7 @@ public class InferenceSession { PsiType returnType = method.getReturnType(); if (!PsiType.VOID.equals(returnType) && returnType != null) { PsiType targetType = getTargetType(context); - if (targetType != null) { + if (targetType != null && !PsiType.VOID.equals(targetType)) { registerReturnTypeConstraints(PsiUtil.isRawSubstitutor(method, mySiteSubstitutor) ? returnType : mySiteSubstitutor.substitute(returnType), targetType); } } @@ -1021,13 +1021,13 @@ public class InferenceSession { */ public static boolean isMoreSpecific(PsiMethod m1, PsiMethod m2, - PsiSubstitutor siteSubstitutor2, PsiExpression[] args, PsiElement context, boolean varargs) { - final PsiTypeParameter[] typeParameters = m2.getTypeParameters(); - - final InferenceSession session = new InferenceSession(typeParameters, siteSubstitutor2, m2.getManager(), context); + final InferenceSession session = new InferenceSession(PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY, m2.getManager(), context); + for (PsiTypeParameter param : PsiUtil.typeParametersIterable(m2)) { + session.initBounds(param); + } final PsiParameter[] parameters1 = m1.getParameterList().getParameters(); final PsiParameter[] parameters2 = m2.getParameterList().getParameters(); @@ -1037,8 +1037,8 @@ public class InferenceSession { final int paramsLength = !varargs ? parameters1.length : parameters1.length - 1; for (int i = 0; i < paramsLength; i++) { - PsiType sType = getParameterType(parameters1, i, siteSubstitutor2, false); - PsiType tType = getParameterType(parameters2, i, siteSubstitutor2, varargs); + PsiType sType = getParameterType(parameters1, i, PsiSubstitutor.EMPTY, false); + PsiType tType = getParameterType(parameters2, i, PsiSubstitutor.EMPTY, varargs); if (session.isProperType(sType) && session.isProperType(tType)) { if (!TypeConversionUtil.isAssignable(tType, sType)) { return false; @@ -1055,8 +1055,8 @@ public class InferenceSession { } if (varargs) { - PsiType sType = getParameterType(parameters1, paramsLength, siteSubstitutor2, true); - PsiType tType = getParameterType(parameters2, paramsLength, siteSubstitutor2, true); + PsiType sType = getParameterType(parameters1, paramsLength, PsiSubstitutor.EMPTY, true); + PsiType tType = getParameterType(parameters2, paramsLength, PsiSubstitutor.EMPTY, true); session.addConstraint(new StrictSubtypingConstraint(tType, sType)); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java index 4fbbad26964d..8d42dbeb4f90 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java @@ -84,8 +84,8 @@ public interface JavaElementType { IElementType PARAMETER_LIST = JavaStubElementTypes.PARAMETER_LIST; IElementType EXTENDS_BOUND_LIST = JavaStubElementTypes.EXTENDS_BOUND_LIST; IElementType THROWS_LIST = JavaStubElementTypes.THROWS_LIST; - IElementType LITERAL_EXPRESSION = new JavaCompositeElementType("LITERAL_EXPRESSION", PsiLiteralExpressionImpl.class); + IElementType LITERAL_EXPRESSION = new JavaCompositeElementType("LITERAL_EXPRESSION", PsiLiteralExpressionImpl.class); IElementType IMPORT_STATIC_REFERENCE = new JavaCompositeElementType("IMPORT_STATIC_REFERENCE", PsiImportStaticReferenceElementImpl.class); IElementType TYPE = new JavaCompositeElementType("TYPE", PsiTypeElementImpl.class); IElementType DIAMOND_TYPE = new JavaCompositeElementType("DIAMOND_TYPE", PsiDiamondTypeElementImpl.class); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java index 8cf5b5bfbdd2..e2af7b08df0d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSourceUtil.java @@ -15,13 +15,28 @@ */ package com.intellij.psi.impl.source.tree; +import com.intellij.lang.ASTFactory; import com.intellij.lang.ASTNode; +import com.intellij.lang.LighterAST; +import com.intellij.lang.LighterASTNode; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.source.DummyHolder; import com.intellij.psi.impl.source.SourceJavaCodeReference; +import com.intellij.psi.impl.source.SourceTreeToPsiMap; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.CharTable; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; public class JavaSourceUtil { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.JavaSourceUtil"); + + private static final TokenSet REF_FILTER = TokenSet.orSet( + ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET, TokenSet.create(JavaElementType.ANNOTATION)); + private JavaSourceUtil() { } public static void fullyQualifyReference(@NotNull CompositeElement reference, @NotNull PsiClass targetClass) { @@ -61,4 +76,70 @@ public class JavaSourceUtil { } } } + + @NotNull + public static String getReferenceText(@NotNull PsiJavaCodeReferenceElement ref) { + final StringBuilder buffer = new StringBuilder(); + + ((TreeElement)ref.getNode()).acceptTree(new RecursiveTreeElementWalkingVisitor() { + @Override + public void visitLeaf(LeafElement leaf) { + if (!REF_FILTER.contains(leaf.getElementType())) { + String leafText = leaf.getText(); + if (buffer.length() > 0 && !leafText.isEmpty() && Character.isJavaIdentifierPart(leafText.charAt(0))) { + char lastInBuffer = buffer.charAt(buffer.length() - 1); + if (lastInBuffer == '?' || Character.isJavaIdentifierPart(lastInBuffer)) { + buffer.append(" "); + } + } + + buffer.append(leafText); + } + } + + @Override + public void visitComposite(CompositeElement composite) { + if (!REF_FILTER.contains(composite.getElementType())) { + super.visitComposite(composite); + } + } + }); + + return buffer.toString(); + } + + @NotNull + public static String getReferenceText(@NotNull LighterAST tree, @NotNull LighterASTNode node) { + return LightTreeUtil.toFilteredString(tree, node, REF_FILTER); + } + + public static TreeElement addParenthToReplacedChild(@NotNull IElementType parenthType, + @NotNull TreeElement newChild, + @NotNull PsiManager manager) { + CompositeElement parenthExpr = ASTFactory.composite(parenthType); + + TreeElement dummyExpr = (TreeElement)newChild.clone(); + final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(newChild); + new DummyHolder(manager, parenthExpr, null, charTableByTree); + parenthExpr.putUserData(CharTable.CHAR_TABLE_KEY, charTableByTree); + parenthExpr.rawAddChildren(ASTFactory.leaf(JavaTokenType.LPARENTH, "(")); + parenthExpr.rawAddChildren(dummyExpr); + parenthExpr.rawAddChildren(ASTFactory.leaf(JavaTokenType.RPARENTH, ")")); + + try { + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); + PsiElement formatted = codeStyleManager.reformat(SourceTreeToPsiMap.treeToPsiNotNull(parenthExpr)); + parenthExpr = (CompositeElement)SourceTreeToPsiMap.psiToTreeNotNull(formatted); + } + catch (IncorrectOperationException e) { + LOG.error(e); // should not happen + } + + newChild.putUserData(CharTable.CHAR_TABLE_KEY, SharedImplUtil.findCharTableByTree(newChild)); + dummyExpr.getTreeParent().replaceChild(dummyExpr, newChild); + + // TODO remove explicit caches drop since this should be ok if we will use ChangeUtil for the modification + TreeUtil.clearCaches(TreeUtil.getFileElement(parenthExpr)); + return parenthExpr; + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java index 93e9f60c890e..554580828c0b 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/SourceUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 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. @@ -15,94 +15,29 @@ */ package com.intellij.psi.impl.source.tree; -import com.intellij.lang.ASTFactory; import com.intellij.lang.LighterAST; import com.intellij.lang.LighterASTNode; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.JavaTokenType; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiJavaCodeReferenceElement; import com.intellij.psi.PsiManager; -import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.source.DummyHolder; -import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.TokenSet; -import com.intellij.util.CharTable; -import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +/** @deprecated use {@link JavaSourceUtil} (to be removed in IDEA 15) */ +@SuppressWarnings("UnusedDeclaration") public class SourceUtil { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.SourceUtil"); - - private static final TokenSet REF_FILTER = TokenSet.orSet( - ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET, TokenSet.create(JavaElementType.ANNOTATION)); - private SourceUtil() { } @NotNull public static String getReferenceText(@NotNull PsiJavaCodeReferenceElement ref) { - final StringBuilder buffer = new StringBuilder(); - - ((TreeElement)ref.getNode()).acceptTree(new RecursiveTreeElementWalkingVisitor() { - @Override - public void visitLeaf(LeafElement leaf) { - if (!REF_FILTER.contains(leaf.getElementType())) { - String leafText = leaf.getText(); - if (buffer.length() > 0 && !leafText.isEmpty() && Character.isJavaIdentifierPart(leafText.charAt(0))) { - char lastInBuffer = buffer.charAt(buffer.length() - 1); - if (lastInBuffer == '?' || Character.isJavaIdentifierPart(lastInBuffer)) { - buffer.append(" "); - } - } - - buffer.append(leafText); - } - } - - @Override - public void visitComposite(CompositeElement composite) { - if (!REF_FILTER.contains(composite.getElementType())) { - super.visitComposite(composite); - } - } - }); - - return buffer.toString(); + return JavaSourceUtil.getReferenceText(ref); } @NotNull public static String getReferenceText(@NotNull LighterAST tree, @NotNull LighterASTNode node) { - return LightTreeUtil.toFilteredString(tree, node, REF_FILTER); + return JavaSourceUtil.getReferenceText(tree, node); } - public static TreeElement addParenthToReplacedChild(@NotNull IElementType parenthType, - @NotNull TreeElement newChild, - @NotNull PsiManager manager) { - CompositeElement parenthExpr = ASTFactory.composite(parenthType); - - TreeElement dummyExpr = (TreeElement)newChild.clone(); - final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(newChild); - new DummyHolder(manager, parenthExpr, null, charTableByTree); - parenthExpr.putUserData(CharTable.CHAR_TABLE_KEY, charTableByTree); - parenthExpr.rawAddChildren(ASTFactory.leaf(JavaTokenType.LPARENTH, "(")); - parenthExpr.rawAddChildren(dummyExpr); - parenthExpr.rawAddChildren(ASTFactory.leaf(JavaTokenType.RPARENTH, ")")); - - try { - CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); - PsiElement formatted = codeStyleManager.reformat(SourceTreeToPsiMap.treeToPsiNotNull(parenthExpr)); - parenthExpr = (CompositeElement)SourceTreeToPsiMap.psiToTreeNotNull(formatted); - } - catch (IncorrectOperationException e) { - LOG.error(e); // should not happen - } - - newChild.putUserData(CharTable.CHAR_TABLE_KEY, SharedImplUtil.findCharTableByTree(newChild)); - dummyExpr.getTreeParent().replaceChild(dummyExpr, newChild); - - // TODO remove explicit caches drop since this should be ok if we will use ChangeUtil for the modification - TreeUtil.clearCaches(TreeUtil.getFileElement(parenthExpr)); - return parenthExpr; + public static TreeElement addParenthToReplacedChild(@NotNull IElementType parenthType, @NotNull TreeElement newChild, @NotNull PsiManager manager) { + return JavaSourceUtil.addParenthToReplacedChild(parenthType, newChild, manager); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java index 1d8693efc55c..e0b122e95592 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ExpressionPsiElement.java @@ -13,10 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/* - * @author max - */ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; @@ -24,13 +20,11 @@ import com.intellij.psi.impl.source.tree.*; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; +/** + * @author max + */ public class ExpressionPsiElement extends CompositePsiElement { - private final int myHC = CompositePsiElement.ourHC++; - - @Override - public final int hashCode() { - return myHC; - } + @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") private final int myHC = CompositePsiElement.ourHC++; public ExpressionPsiElement(final IElementType type) { super(type); @@ -42,9 +36,14 @@ public class ExpressionPsiElement extends CompositePsiElement { ElementType.EXPRESSION_BIT_SET.contains(newElement.getElementType())) { boolean needParenth = ReplaceExpressionUtil.isNeedParenthesis(child, newElement); if (needParenth) { - newElement = SourceUtil.addParenthToReplacedChild(JavaElementType.PARENTH_EXPRESSION, newElement, getManager()); + newElement = JavaSourceUtil.addParenthToReplacedChild(JavaElementType.PARENTH_EXPRESSION, newElement, getManager()); } } super.replaceChildInternal(child, newElement); } + + @Override + public final int hashCode() { + return myHC; + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodElement.java index 31fb4bca8833..1edd7cbaec76 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 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. @@ -41,14 +41,15 @@ public class MethodElement extends CompositeElement implements Constants { @Override public int getTextOffset() { - return findChildByRole(ChildRole.NAME).getStartOffset(); + ASTNode name = findChildByType(IDENTIFIER); + return name != null ? name.getStartOffset() : this.getStartOffset(); } @Override public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) { - if (first == last && first.getElementType() == JavaElementType.CODE_BLOCK){ - ASTNode semicolon = findChildByRole(ChildRole.CLOSING_SEMICOLON); - if (semicolon != null){ + if (first == last && first.getElementType() == JavaElementType.CODE_BLOCK) { + ASTNode semicolon = TreeUtil.findChildBackward(this, SEMICOLON); + if (semicolon != null) { deleteChildInternal(semicolon); } } @@ -64,7 +65,7 @@ public class MethodElement extends CompositeElement implements Constants { @Override public void deleteChildInternal(@NotNull ASTNode child) { - if (child.getElementType() == CODE_BLOCK){ + if (child.getElementType() == CODE_BLOCK) { final ASTNode prevWS = TreeUtil.prevLeaf(child); if (prevWS != null && prevWS.getElementType() == TokenType.WHITE_SPACE) { removeChild(prevWS); @@ -80,9 +81,9 @@ public class MethodElement extends CompositeElement implements Constants { } @Override - public ASTNode findChildByRole(int role){ + public ASTNode findChildByRole(int role) { LOG.assertTrue(ChildRole.isUnique(role)); - switch(role){ + switch (role) { default: return null; @@ -161,5 +162,4 @@ public class MethodElement extends CompositeElement implements Constants { protected boolean isVisibilitySupported() { return true; } - } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java index 5a42715590ef..29d072970560 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiPackageStatementImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 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. @@ -38,7 +38,7 @@ public class PsiPackageStatementImpl extends CompositePsiElement implements PsiP @Override public String getPackageName() { PsiJavaCodeReferenceElement ref = getPackageReference(); - return ref == null ? null : SourceUtil.getReferenceText(ref); + return ref == null ? null : JavaSourceUtil.getReferenceText(ref); } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java index 02ffaa6f3c20..8dd43933c660 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -761,7 +761,7 @@ public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase imple private String getCachedNormalizedText() { String whiteSpaceAndComments = myCachedNormalizedText; if (whiteSpaceAndComments == null) { - myCachedNormalizedText = whiteSpaceAndComments = SourceUtil.getReferenceText(this); + myCachedNormalizedText = whiteSpaceAndComments = JavaSourceUtil.getReferenceText(this); } return whiteSpaceAndComments; } 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 f136c843aa87..59083c625f82 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 @@ -550,10 +550,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel); - boolean applicable12 = isApplicableTo(types2AtSite, method1, languageLevel, varargsPosition, methodSubstitutor1, method2, siteSubstitutor1); + boolean applicable12 = isApplicableTo(types2AtSite, method1, languageLevel, varargsPosition, methodSubstitutor1, method2); final PsiSubstitutor methodSubstitutor2 = calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, types1AtSite, languageLevel); - boolean applicable21 = isApplicableTo(types1AtSite, method2, languageLevel, varargsPosition, methodSubstitutor2, method1, siteSubstitutor2); + boolean applicable21 = isApplicableTo(types1AtSite, method2, languageLevel, varargsPosition, methodSubstitutor2, method1); if (!myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_8)) { final boolean typeArgsApplicable12 = GenericsUtil.isTypeArgumentsApplicable(typeParameters1, methodSubstitutor1, myArgumentsList, !applicable21); @@ -604,9 +604,9 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ if (toCompareFunctional) { final boolean applicable12ignoreFunctionalType = isApplicableTo(types2AtSite, method1, languageLevel, varargsPosition, - calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel), null, null); + calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel), null); final boolean applicable21ignoreFunctionalType = isApplicableTo(types1AtSite, method2, languageLevel, varargsPosition, - calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, types1AtSite, languageLevel), null, null); + calculateMethodSubstitutor(typeParameters2, method2, siteSubstitutor2, types2, types1AtSite, languageLevel), null); if (applicable12ignoreFunctionalType || applicable21ignoreFunctionalType) { Specifics specifics = null; @@ -694,12 +694,11 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ @NotNull LanguageLevel languageLevel, boolean varargsPosition, @NotNull PsiSubstitutor methodSubstitutor1, - PsiMethod method2, - PsiSubstitutor siteSubstitutor1) { + PsiMethod method2) { if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && method2 != null && method1.getTypeParameters().length > 0 && myArgumentsList instanceof PsiExpressionList) { final PsiElement parent = myArgumentsList.getParent(); if (parent instanceof PsiCallExpression && ((PsiCallExpression)parent).getTypeArguments().length == 0) { - return InferenceSession.isMoreSpecific(method2, method1, siteSubstitutor1, ((PsiExpressionList)myArgumentsList).getExpressions(), myArgumentsList, varargsPosition); + return InferenceSession.isMoreSpecific(method2, method1, ((PsiExpressionList)myArgumentsList).getExpressions(), myArgumentsList, varargsPosition); } } final int applicabilityLevel = PsiUtil.getApplicabilityLevel(method1, methodSubstitutor1, types2AtSite, languageLevel, false, varargsPosition); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java index 28035c8c1698..01f7486ea89a 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/annotations/typeAnnotations.java @@ -114,6 +114,7 @@ class Outer { void @TA misplaced() { } @TA Outer() { } + @TA Outer(T t) { } class MyClass<@TA @TPA T> { } interface MyInterface<@TA @TPA E> { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/IDEA127584.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/IDEA127584.java new file mode 100644 index 000000000000..f1222505a708 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/IDEA127584.java @@ -0,0 +1,22 @@ +class Test { + public static Future foo(Future future, Function function) { + return future.map(function); + } + + // These interfaces inspired by FoundationDB Java client class files + interface PartialFunction { + VP apply(TP t) throws java.lang.Exception; + } + + interface Function extends PartialFunction { + VF apply(TF t); + } + + interface PartialFuture { + PartialFuture map(PartialFunction partialFunction); + } + + interface Future extends PartialFuture { + Future map(Function function); + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA127596.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA127596.java new file mode 100644 index 000000000000..20636674141b --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA127596.java @@ -0,0 +1,9 @@ +class Executor { + void bar(Executor e) { + Runnable r = () -> foo(e); + } + + private T foo(final Executor e) { + return null; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterShortenFQNs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterShortenFQNs.java new file mode 100644 index 000000000000..9fea89ffa684 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/afterShortenFQNs.java @@ -0,0 +1,10 @@ +import java.util.List; + +// "Cast parameter to 'java.util.List'" "true" +class Test { + void m(Object o) { + foo((List) o); + } + + private void foo(final java.util.List o) {} +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeShortenFQNs.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeShortenFQNs.java new file mode 100644 index 000000000000..e53d8b1e6c31 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/addTypeCast/beforeShortenFQNs.java @@ -0,0 +1,8 @@ +// "Cast parameter to 'java.util.List'" "true" +class Test { + void m(Object o) { + foo(o); + } + + private void foo(final java.util.List o) {} +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeObjectInferredButIntExpected.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeObjectInferredButIntExpected.java new file mode 100644 index 000000000000..3a82478ec678 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/anonymous2lambda/beforeObjectInferredButIntExpected.java @@ -0,0 +1,16 @@ +// "Replace with lambda" "false" +import java.util.function.Function; + +class Test { + void ab() { + comparing(new Function() { + public String apply(Integer pObj) { + return Integer.toString(pObj); + } + }); + + } + + static void comparing(Function keyExtractor){} + +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterStaticInInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterStaticInInterface.java new file mode 100644 index 000000000000..66a2b59a9a10 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/afterStaticInInterface.java @@ -0,0 +1,10 @@ +// "Create Method 'f'" "true" +interface X { + public static void m() { + f(); + } + + static void f() { + + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeStaticInInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeStaticInInterface.java new file mode 100644 index 000000000000..81afbe358fbe --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage/beforeStaticInInterface.java @@ -0,0 +1,6 @@ +// "Create Method 'f'" "true" +interface X { + public static void m() { + f(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguityWithoutSuperMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguityWithoutSuperMethods.java new file mode 100644 index 000000000000..54310c8da75f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/afterAmbiguityWithoutSuperMethods.java @@ -0,0 +1,11 @@ +// "Replace lambda with method reference" "true" +import java.io.PrintStream; +import java.util.function.BiConsumer; + +class Test { + { + BiConsumer printer = PrintStream::println; + } + + +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguityWithoutSuperMethods.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguityWithoutSuperMethods.java new file mode 100644 index 000000000000..7c68e5ec9fbc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAmbiguityWithoutSuperMethods.java @@ -0,0 +1,11 @@ +// "Replace lambda with method reference" "true" +import java.io.PrintStream; +import java.util.function.BiConsumer; + +class Test { + { + BiConsumer printer = (printStream, x) -> printStream.println(x); + } + + +} diff --git a/java/java-tests/testData/codeInsight/javadocIG/pInsidePre.html b/java/java-tests/testData/codeInsight/javadocIG/pInsidePre.html new file mode 100644 index 000000000000..fbfd2983208a --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/pInsidePre.html @@ -0,0 +1,6 @@ + Test
public String field = null
+
+         foo
+         

+ bar +
\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadocIG/pInsidePre.java b/java/java-tests/testData/codeInsight/javadocIG/pInsidePre.java new file mode 100644 index 000000000000..0627e4b99510 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadocIG/pInsidePre.java @@ -0,0 +1,10 @@ +class Test { + /** + *
+   *     foo
+   *     

+ * bar + *

+ */ + public String field = null; +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/Errors.java b/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/Errors.java index 200c37e7fa32..4e90d08eb3ea 100644 --- a/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/Errors.java +++ b/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/Errors.java @@ -1,2 +1,8 @@ @Ann(0) class D { + + @EJB + Runnable myMissingEjbRef; + + public @SafeVarargs + static void m(); } \ No newline at end of file diff --git a/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/Errors.txt b/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/Errors.txt index 9f1efdb6d2e4..678025fdf06a 100644 --- a/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/Errors.txt +++ b/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/Errors.txt @@ -69,5 +69,96 @@ PsiJavaFile:Errors.java PsiWhiteSpace(' ') PsiJavaToken:LBRACE('{') + PsiWhiteSpace('\n\n ') + PsiModifierList: + + PsiErrorElement:Identifier or type expected + PsiTypeParameterList + PsiJavaToken:LT('<') + PsiTypeParameter:error + PsiIdentifier:error('error') + PsiElement(EXTENDS_BOUND_LIST) + + PsiJavaToken:GT('>') + PsiModifierList:@EJB + PsiAnnotation + PsiJavaToken:AT('@') + PsiJavaCodeReferenceElement:EJB + PsiIdentifier:EJB('EJB') + PsiReferenceParameterList + + PsiAnnotationParameterList + + PsiErrorElement:Identifier or type expected + PsiTypeParameterList + PsiJavaToken:LT('<') + PsiErrorElement:Type parameter expected + + PsiErrorElement:'>' expected. + + PsiErrorElement:Unexpected token + PsiJavaToken:DIV('/') + PsiModifierList: + + PsiTypeElement:error + PsiJavaCodeReferenceElement:error + PsiIdentifier:error('error') + PsiReferenceParameterList + + PsiErrorElement:Identifier expected + + PsiErrorElement:Unexpected token + PsiJavaToken:GT('>') + PsiWhiteSpace('\n ') + PsiField:myMissingEjbRef + PsiModifierList: + + PsiTypeElement:Runnable + PsiJavaCodeReferenceElement:Runnable + PsiIdentifier:Runnable('Runnable') + PsiReferenceParameterList + + PsiWhiteSpace(' ') + PsiIdentifier:myMissingEjbRef('myMissingEjbRef') + PsiJavaToken:SEMICOLON(';') + PsiWhiteSpace('\n\n ') + PsiModifierList:public + PsiKeyword:public('public') + PsiWhiteSpace(' ') + PsiErrorElement:Identifier or type expected + PsiTypeParameterList + PsiJavaToken:LT('<') + PsiTypeParameter:T + PsiIdentifier:T('T') + PsiElement(EXTENDS_BOUND_LIST) + + PsiJavaToken:GT('>') + PsiWhiteSpace(' ') + PsiMethod:m + PsiModifierList:@SafeVarargs + static + PsiAnnotation + PsiJavaToken:AT('@') + PsiJavaCodeReferenceElement:SafeVarargs + PsiIdentifier:SafeVarargs('SafeVarargs') + PsiReferenceParameterList + + PsiAnnotationParameterList + + PsiWhiteSpace('\n ') + PsiKeyword:static('static') + PsiTypeParameterList + + PsiWhiteSpace(' ') + PsiTypeElement:void + PsiKeyword:void('void') + PsiWhiteSpace(' ') + PsiIdentifier:m('m') + PsiParameterList:() + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiJavaToken:SEMICOLON(';') PsiWhiteSpace('\n') PsiJavaToken:RBRACE('}') \ No newline at end of file diff --git a/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/TypeAnnotations.java b/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/TypeAnnotations.java index 208e34387c56..de61404de20d 100644 --- a/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/TypeAnnotations.java +++ b/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/TypeAnnotations.java @@ -47,9 +47,10 @@ class SpecSamples { try (@A Reader r = new @B FileReader("/dev/zero"); @A Writer w = new @B FileWriter("/dev/null")) { } } - //interface TestClass { - // @Nullable List test(); - //} + interface TestClass { + @Nullable List test(); + @Positive int test(T t); + } // // 2. An annotation on a wildcard type argument appears before the wildcard ... @@ -76,7 +77,7 @@ class SpecSamples { // @Immutable SpecSamples() { } - // @Immutable SpecSamples(T t) { } + @Immutable SpecSamples(T t) { } // // todo [r.sh] 5. It is permitted to explicitly declare the method receiver as the first formal parameter ... diff --git a/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/TypeAnnotations.txt b/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/TypeAnnotations.txt index d1a8022925f3..0cc33a82fa2c 100644 --- a/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/TypeAnnotations.txt +++ b/java/java-tests/testData/psi/parser-full/annotationParsing/annotation/TypeAnnotations.txt @@ -1045,11 +1045,103 @@ PsiJavaFile:TypeAnnotations.java PsiWhiteSpace('\n ') PsiJavaToken:RBRACE('}') PsiWhiteSpace('\n\n ') - PsiComment(END_OF_LINE_COMMENT)('//interface TestClass {') - PsiWhiteSpace('\n ') - PsiComment(END_OF_LINE_COMMENT)('// @Nullable List test();') - PsiWhiteSpace('\n ') - PsiComment(END_OF_LINE_COMMENT)('//}') + PsiClass:TestClass + PsiModifierList: + + PsiKeyword:interface('interface') + PsiWhiteSpace(' ') + PsiIdentifier:TestClass('TestClass') + PsiTypeParameterList + + PsiReferenceList + + PsiReferenceList + + PsiWhiteSpace(' ') + PsiJavaToken:LBRACE('{') + PsiWhiteSpace('\n ') + PsiMethod:test + PsiModifierList: + + PsiTypeParameterList + PsiJavaToken:LT('<') + PsiTypeParameter:T + PsiIdentifier:T('T') + PsiElement(EXTENDS_BOUND_LIST) + + PsiJavaToken:GT('>') + PsiWhiteSpace(' ') + PsiTypeElement:@Nullable List + PsiAnnotation + PsiJavaToken:AT('@') + PsiJavaCodeReferenceElement:Nullable + PsiIdentifier:Nullable('Nullable') + PsiReferenceParameterList + + PsiAnnotationParameterList + + PsiWhiteSpace(' ') + PsiJavaCodeReferenceElement:List + PsiIdentifier:List('List') + PsiReferenceParameterList + PsiJavaToken:LT('<') + PsiTypeElement:T + PsiJavaCodeReferenceElement:T + PsiIdentifier:T('T') + PsiReferenceParameterList + + PsiJavaToken:GT('>') + PsiWhiteSpace(' ') + PsiIdentifier:test('test') + PsiParameterList:() + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiJavaToken:SEMICOLON(';') + PsiWhiteSpace('\n ') + PsiMethod:test + PsiModifierList: + + PsiTypeParameterList + PsiJavaToken:LT('<') + PsiTypeParameter:T + PsiIdentifier:T('T') + PsiElement(EXTENDS_BOUND_LIST) + + PsiJavaToken:GT('>') + PsiWhiteSpace(' ') + PsiTypeElement:@Positive int + PsiAnnotation + PsiJavaToken:AT('@') + PsiJavaCodeReferenceElement:Positive + PsiIdentifier:Positive('Positive') + PsiReferenceParameterList + + PsiAnnotationParameterList + + PsiWhiteSpace(' ') + PsiKeyword:int('int') + PsiWhiteSpace(' ') + PsiIdentifier:test('test') + PsiParameterList:(T t) + PsiJavaToken:LPARENTH('(') + PsiParameter:t + PsiModifierList: + + PsiTypeElement:T + PsiJavaCodeReferenceElement:T + PsiIdentifier:T('T') + PsiReferenceParameterList + + PsiWhiteSpace(' ') + PsiIdentifier:t('t') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiJavaToken:SEMICOLON(';') + PsiWhiteSpace('\n ') + PsiJavaToken:RBRACE('}') PsiWhiteSpace('\n\n ') PsiComment(END_OF_LINE_COMMENT)('//') PsiWhiteSpace('\n ') @@ -1492,7 +1584,47 @@ PsiJavaFile:TypeAnnotations.java PsiWhiteSpace(' ') PsiJavaToken:RBRACE('}') PsiWhiteSpace('\n ') - PsiComment(END_OF_LINE_COMMENT)('// @Immutable SpecSamples(T t) { }') + PsiMethod:SpecSamples + PsiModifierList: + + PsiTypeParameterList + PsiJavaToken:LT('<') + PsiTypeParameter:T + PsiIdentifier:T('T') + PsiElement(EXTENDS_BOUND_LIST) + + PsiJavaToken:GT('>') + PsiWhiteSpace(' ') + PsiAnnotation + PsiJavaToken:AT('@') + PsiJavaCodeReferenceElement:Immutable + PsiIdentifier:Immutable('Immutable') + PsiReferenceParameterList + + PsiAnnotationParameterList + + PsiWhiteSpace(' ') + PsiIdentifier:SpecSamples('SpecSamples') + PsiParameterList:(T t) + PsiJavaToken:LPARENTH('(') + PsiParameter:t + PsiModifierList: + + PsiTypeElement:T + PsiJavaCodeReferenceElement:T + PsiIdentifier:T('T') + PsiReferenceParameterList + + PsiWhiteSpace(' ') + PsiIdentifier:t('t') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiWhiteSpace(' ') + PsiCodeBlock + PsiJavaToken:LBRACE('{') + PsiWhiteSpace(' ') + PsiJavaToken:RBRACE('}') PsiWhiteSpace('\n\n ') PsiComment(END_OF_LINE_COMMENT)('//') PsiWhiteSpace('\n ') 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 7a73bfed6cbd..9bb7d4801944 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 @@ -111,6 +111,10 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIDEA127584() throws Exception { + doTest(); + } + private void doTest() { doTest(true); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 6bd7654b72af..ea9ada93ca77 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 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. @@ -31,214 +31,64 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { @Override protected LocalInspectionTool[] configureLocalInspectionTools() { return new LocalInspectionTool[]{ - new UnusedSymbolLocalInspection(), + new UnusedSymbolLocalInspection() }; } - public void testIDEA93586() throws Exception { - doTest(); - } + public void testIDEA93586() { doTest(); } + public void testIDEA113573() { doTest(); } + public void testIDEA112922() { doTest(); } + public void testIDEA113504() { doTest(); } + public void testAfterAbstractPipeline2() { doTest(); } + public void testIDEA116252() { doTest(); } + public void testIDEA106670() { doTest(); } + public void testIDEA116548() { doTest(); } + public void testOverloadResolutionSAM() { doTest(); } + public void testIntersectionTypesDuringInference() { doTest(); } + public void testIncludeConstraintsWhenParentMethodIsDuringCalculation() { doTest(); } + public void testUseCalculatedSubstitutor() { doTest(); } + public void testArgumentOfAnonymousClass() { doTest(); } + public void testEllipsis() { doTest(); } + public void testOuterMethodPropagation() { doTest(); } + public void testRecursiveCalls() { doTest(); } + public void testGroundTargetTypeForImplicitLambdas() { doTest(); } + public void testAdditionalConstraintsReduceOrder() { doTest(); } + public void testAdditionalConstraintSubstitution() { doTest(); } + public void testFunctionalInterfacesCalculation() { doTest(); } + public void testMissedSiteSubstitutorDuringDeepAdditionalConstraintsGathering() { doTest(); } + public void testIDEA120992() { doTest(); } + public void testTargetTypeConflictResolverShouldNotTryToEvaluateCurrentArgumentType() { doTest(); } + public void testIDEA119535() { doTest(); } + public void testIDEA119003() { doTest(); } + public void testIDEA117124() { doTest(); } + public void testWildcardParameterization() { doTest(); } + public void testDiamondInLambdaReturn() { doTest(); } + public void testIDEA118965() { doTest(); } + public void testIDEA121315() { doTest(); } + public void testIDEA118965comment() { doTest(); } + public void testIDEA122074() { doTest(); } + public void testIDEA122084() { doTest(); } + public void testAdditionalConstraintDependsOnNonMentionedVars() { doTest(); } + public void testIDEA122616() { doTest(); } + public void testIDEA122700() { doTest(); } + public void testIDEA122406() { doTest(); } + public void testNestedCallsInsideLambdaReturnExpression() { doTest(); } + public void testIDEA123731() { doTest(); } + public void testIDEA123869() { doTest(); } + public void testIDEA123848() { doTest(); } + public void testOnlyLambdaAtTypeParameterPlace() { doTest(); } + public void testLiftedIntersectionType() { doTest(); } + public void testInferenceFromReturnStatements() { doTest(); } + public void testDownUpThroughLambdaReturnStatements() { doTest(); } + public void testIDEA124547() { doTest(); } + public void testIDEA118362() { doTest(); } + public void testIDEA126056() { doTest(); } + public void testIDEA125254() { doTest(); } + public void testIDEA124961() { doTest(); } + public void testIDEA126109() { doTest(); } + public void testIDEA126809() { doTest(); } - public void testIDEA113573() throws Exception { - doTest(); - } - - public void testIDEA112922() throws Exception { - doTest(); - } - - public void testIDEA113504() throws Exception { - doTest(); - } - - public void testAfterAbstractPipeline2() throws Exception { - doTest(); - } - - public void testIDEA116252() throws Exception { - doTest(); - } - - public void testIDEA106670() throws Exception { - doTest(); - } - - public void testIDEA116548() throws Exception { - doTest(); - } - - public void testOverloadResolutionSAM() throws Exception { - doTest(); - } - - public void testIntersectionTypesDuringInference() throws Exception { - doTest(); - } - - public void testIncludeConstraintsWhenParentMethodIsDuringCalculation() throws Exception { - doTest(); - } - - public void testUseCalculatedSubstitutor() throws Exception { - doTest(); - } - - public void testArgumentOfAnonymousClass() throws Exception { - doTest(); - } - - public void testEllipsis() throws Exception { - doTest(); - } - - public void testOuterMethodPropagation() throws Exception { - doTest(); - } - - public void testRecursiveCalls() throws Exception { - doTest(); - } - - public void testGroundTargetTypeForImplicitLambdas() throws Exception { - doTest(); - } - - public void testAdditionalConstraintsReduceOrder() throws Exception { - doTest(); - } - - public void testAdditionalConstraintSubstitution() throws Exception { - doTest(); - } - public void testFunctionalInterfacesCalculation() throws Exception { - doTest(); - } - - public void testMissedSiteSubstitutorDuringDeepAdditionalConstraintsGathering() throws Exception { - doTest(); - } - - public void testIDEA120992() throws Exception { - doTest(); - } - - public void testTargetTypeConflictResolverShouldNotTryToEvaluateCurrentArgumentType() throws Exception { - doTest(); - } - - public void testIDEA119535() throws Exception { - doTest(); - } - - public void testIDEA119003() throws Exception { - doTest(); - } - - public void testIDEA117124() throws Exception { - doTest(); - } - - public void testWildcardParameterization() throws Exception { - doTest(); - } - - public void testDiamondInLambdaReturn() throws Exception { - doTest(); - } - - public void testIDEA118965() throws Exception { - doTest(); - } - - public void testIDEA121315() throws Exception { - doTest(); - } - - public void testIDEA118965comment() throws Exception { - doTest(); - } - - public void testIDEA122074() throws Exception { - doTest(); - } - - public void testIDEA122084() throws Exception { - doTest(); - } - - public void testAdditionalConstraintDependsOnNonMentionedVars() throws Exception { - doTest(); - } - - public void testIDEA122616() throws Exception { - doTest(); - } - - public void testIDEA122700() throws Exception { - doTest(); - } - - public void testIDEA122406() throws Exception { - doTest(); - } - - public void testNestedCallsInsideLambdaReturnExpression() throws Exception { - doTest(); - } - - public void testIDEA123731() throws Exception { - doTest(); - } - - public void testIDEA123869() throws Exception { - doTest(); - } - - public void testIDEA123848() throws Exception { - doTest(); - } - - public void testOnlyLambdaAtTypeParameterPlace() throws Exception { - doTest(); - } - - public void testLiftedIntersectionType() throws Exception { - doTest(); - } - - public void testInferenceFromReturnStatements() throws Exception { - doTest(); - } - - public void testDownUpThroughLambdaReturnStatements() throws Exception { - doTest(); - } - - public void testIDEA124547() throws Exception { - doTest(); - } - - public void testIDEA118362() throws Exception { - doTest(); - } - - public void testIDEA126056() throws Exception { - doTest(); - } - - public void testIDEA125254() throws Exception { - doTest(); - } - - public void testIDEA124961() throws Exception { - doTest(); - } - - public void testIDEA126109() throws Exception { - doTest(); - } - - public void testIDEA126809() throws Exception { + public void testIDEA127596() throws Exception { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RenameWrongReferenceTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RenameWrongReferenceTest.java index ae2c847128b3..7b19bbd5cd27 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RenameWrongReferenceTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/RenameWrongReferenceTest.java @@ -1,3 +1,18 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.codeInsight.daemon.quickFix; public class RenameWrongReferenceTest extends LightQuickFixAvailabilityTestCase { @@ -9,4 +24,3 @@ public class RenameWrongReferenceTest extends LightQuickFixAvailabilityTestCase return "/codeInsight/daemonCodeAnalyzer/quickFix/renameWrongReference"; } } - diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index 2047f13b795d..7b877f7d0c22 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -608,7 +608,7 @@ class Test { configure(testNow, shouldIgnoreRoots(), fourteen, pi, title, c, file); } - pubic void configure(boolean testNow, boolean shouldIgnoreRoots, int times, float pi, String title, char terminate, File file) { + pubic void configure(boolean testNow, boolean shouldIgnoreRoots, int times, float pii, String title, char terminate, File file) { System.out.println(); System.out.println(); } @@ -672,7 +672,7 @@ public class VarArgTest { assert regions[1].placeholderText == "test: 13" } - public void "test inline if argument length is one (EA-57555)"() { + public void "test do not inline if parameter length is one or two"() { def text = """ public class CharSymbol { @@ -681,7 +681,7 @@ public class CharSymbol { count(1, false); } - public void count(int test, boolean fast) { + public void count(int t, boolean fa) { int temp = test; boolean isFast = fast; } @@ -689,13 +689,47 @@ public class CharSymbol { """ configure text def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset } - assert regions.size() == 4 + assert regions.size() == 2 + } - checkRangeOffsetByPositionInText(regions[1], text, "1") - assert regions[1].placeholderText == "test: 1" + public void "test do not inline paired ranged names"() { + def text = """ +public class CharSymbol { - checkRangeOffsetByPositionInText(regions[2], text, "false") - assert regions[2].placeholderText == "fast: false" + public void main() { + String s = "AAA"; + int last = 3; + + substring1(1, last); + substring2(1, last); + substring3(1, last); + substring4(1, last); + } + + public void substring1(int beginIndex, int endIndex) { + int start = beginIndex; + int end = endIndex; + } + + public void substring2(int startIndex, int endIndex) { + int start = beginIndex; + int end = endIndex; + } + + public void substring3(int from, int to) { + int start = beginIndex; + int end = endIndex; + } + + public void substring4(int first, int last) { + int start = beginIndex; + int end = endIndex; + } +} +""" + configure text + def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset } + assert regions.size() == 5 } public void "test inline names if literal expression can be assigned to method parameter"() { @@ -764,7 +798,7 @@ public class Test { } abstract class Checker { - Checker(boolean applyToFirst, boolean applyToSecond) {} + Checker(boolean isActive, boolean requestFocus) {} abstract void test(); } } @@ -773,8 +807,8 @@ public class Test { def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset } assert regions.length == 6 - assert regions[1].placeholderText == "applyToFirst: true" - assert regions[2].placeholderText == "applyToSecond: false" + assert regions[1].placeholderText == "isActive: true" + assert regions[2].placeholderText == "requestFocus: false" checkRangeOffsetByPositionInText(regions[1], text, "true") checkRangeOffsetByPositionInText(regions[2], text, "false") diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java index 454bb7f97a58..a4de0bcdcab8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java @@ -88,6 +88,10 @@ public class JavaDocInfoGeneratorTest extends CodeInsightTestCase { doTestField(); } + public void testPInsidePre() throws Exception { + doTestField(); + } + public void testEnumConstantOrdinal() throws Exception { PsiClass psiClass = getTestClass(); PsiField field = psiClass.getFields() [0]; diff --git a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java index 318126d84e62..e583daed6ed1 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/roots/impl/DirectoryIndexTest.java @@ -188,7 +188,7 @@ public class DirectoryIndexTest extends IdeaTestCase { } public void testDirInfos() throws IOException { - checkNotInProject(myRootVFile); + assertNotInProject(myRootVFile); // beware: files in directory index checkInfo(myFileLibSrc, null, false, true, "", null, myModule); @@ -206,21 +206,21 @@ public class DirectoryIndexTest extends IdeaTestCase { checkInfo(myLibSrcDir, myModule, false, true, "", null, myModule2, myModule3); checkInfo(myLibClsDir, myModule, true, false, "", null, myModule2, myModule3); - assertEquals(myLibSrcDir, checkInProject(myLibSrcDir).getSourceRoot()); + assertEquals(myLibSrcDir, assertInProject(myLibSrcDir).getSourceRoot()); checkInfo(myModule2Dir, myModule2, false, false, null, null); checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3); - checkNotInProject(myCvsDir); - checkExcluded(myExcludeDir, myModule2); - checkExcluded(myExcludedLibClsDir, myModule); - checkExcluded(myExcludedLibSrcDir, myModule); + assertNotInProject(myCvsDir); + assertExcluded(myExcludeDir, myModule2); + assertExcluded(myExcludedLibClsDir, myModule); + assertExcluded(myExcludedLibSrcDir, myModule); - assertEquals(myModule1Dir, checkInProject(myLibClsDir).getContentRoot()); + assertEquals(myModule1Dir, assertInProject(myLibClsDir).getContentRoot()); checkInfo(myModule3Dir, myModule3, false, false, null, null); VirtualFile cvs = myPack1Dir.createChildDirectory(this, "CVS"); - checkNotInProject(cvs); + assertNotInProject(cvs); assertNull(ProjectRootManager.getInstance(myProject).getFileIndex().getPackageNameByDirectory(cvs)); } @@ -332,7 +332,7 @@ public class DirectoryIndexTest extends IdeaTestCase { VirtualFile newDir = myModule1Dir.createChildDirectory(this, "newDir"); myIndex.checkConsistency(); - checkInProject(newDir); + assertInProject(newDir); final FileTypeManagerEx fileTypeManager = (FileTypeManagerEx)FileTypeManager.getInstance(); final String list = fileTypeManager.getIgnoredFilesList(); @@ -345,7 +345,7 @@ public class DirectoryIndexTest extends IdeaTestCase { } }); myIndex.checkConsistency(); - checkNotInProject(newDir); + assertNotInProject(newDir); } finally { ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -354,7 +354,7 @@ public class DirectoryIndexTest extends IdeaTestCase { fileTypeManager.setIgnoredFilesList(list); } }); - checkInProject(newDir); + assertInProject(newDir); } } @@ -397,7 +397,7 @@ public class DirectoryIndexTest extends IdeaTestCase { ModuleManager moduleManager = ModuleManager.getInstance(myProject); Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId()); PsiTestUtil.addContentRoot(module, module4); - checkNotInProject(ignored); + assertNotInProject(ignored); checkInfo(module4, module, false, false, null, null); } }.execute().throwException(); @@ -445,20 +445,20 @@ public class DirectoryIndexTest extends IdeaTestCase { VirtualFile output1 = myModule1Dir.createChildDirectory(this, "output1"); VirtualFile output2 = myModule1Dir.createChildDirectory(this, "output2"); - checkInProject(output1); - checkInProject(output2); + assertInProject(output1); + assertInProject(output2); getCompilerProjectExtension().setCompilerOutputUrl(output1.getUrl()); fireRootsChanged(); - checkExcluded(output1, myModule); - checkInProject(output2); + assertExcluded(output1, myModule); + assertInProject(output2); getCompilerProjectExtension().setCompilerOutputUrl(output2.getUrl()); fireRootsChanged(); - checkInProject(output1); - checkExcluded(output2, myModule); + assertInProject(output1); + assertExcluded(output2, myModule); } private void fireRootsChanged() { @@ -482,7 +482,7 @@ public class DirectoryIndexTest extends IdeaTestCase { public void testModuleSourceAsLibraryClasses() throws Exception { ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Arrays.asList(mySrcDir1.getUrl()), Collections.emptyList()); checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule); - assertInstanceOf(assertOneElement(checkInProject(mySrcDir1).getOrderEntries()), ModuleSourceOrderEntry.class); + assertInstanceOf(assertOneElement(assertInProject(mySrcDir1).getOrderEntries()), ModuleSourceOrderEntry.class); } public void testModulesWithSameSourceContentRoot() { @@ -512,7 +512,7 @@ public class DirectoryIndexTest extends IdeaTestCase { public void testSameSourceAndOutput() { PsiTestUtil.setCompilerOutputPath(myModule, mySrcDir1.getUrl(), false); - checkExcluded(mySrcDir1, myModule); + assertExcluded(mySrcDir1, myModule); } public void testExcludedDirShouldBeExcludedRightAfterItsCreation() throws Exception { @@ -521,10 +521,10 @@ public class DirectoryIndexTest extends IdeaTestCase { VirtualFile module2Output = myModule1Dir.createChildDirectory(this, "module2Output"); VirtualFile module2TestOutput = myModule2Dir.createChildDirectory(this, "module2TestOutput"); - checkInProject(excluded); - checkInProject(projectOutput); - checkInProject(module2Output); - checkInProject(module2TestOutput); + assertInProject(excluded); + assertInProject(projectOutput); + assertInProject(module2Output); + assertInProject(module2TestOutput); getCompilerProjectExtension().setCompilerOutputUrl(projectOutput.getUrl()); @@ -533,15 +533,10 @@ public class DirectoryIndexTest extends IdeaTestCase { PsiTestUtil.setCompilerOutputPath(myModule2, module2TestOutput.getUrl(), true); PsiTestUtil.setExcludeCompileOutput(myModule2, true); - checkExcluded(excluded, myModule); - checkExcluded(projectOutput, myModule); - checkExcluded(module2Output, myModule); - checkExcluded(module2TestOutput, myModule2); - - assertFalse(myIndex.isProjectExcludeRoot(excluded)); - assertFalse(myIndex.isProjectExcludeRoot(projectOutput)); - assertFalse(myIndex.isProjectExcludeRoot(module2Output)); - assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput)); + assertExcluded(excluded, myModule); + assertExcluded(projectOutput, myModule); + assertExcluded(module2Output, myModule); + assertExcluded(module2TestOutput, myModule2); excluded.delete(this); projectOutput.delete(this); @@ -554,45 +549,25 @@ public class DirectoryIndexTest extends IdeaTestCase { public void fileCreated(@NotNull VirtualFileEvent e) { VirtualFile file = e.getFile(); String fileName = e.getFileName(); - checkExcluded(file, fileName.contains("module2TestOutput") ? myModule2 : myModule); + assertExcluded(file, fileName.contains("module2TestOutput") ? myModule2 : myModule); created.add(file); - - if (fileName.equals("projectOutput")) { - assertFalse(myIndex.isProjectExcludeRoot(file)); - } - if (fileName.equals("module2Output")) { - assertFalse(myIndex.isProjectExcludeRoot(file)); - } - if (fileName.equals("module2TestOutput")) { - assertFalse(myIndex.isProjectExcludeRoot(file)); - } } }; VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable()); excluded = myModule1Dir.createChildDirectory(this, excluded.getName()); - assertFalse(myIndex.isProjectExcludeRoot(excluded)); - - projectOutput = myModule1Dir.createChildDirectory(this, projectOutput.getName()); - assertFalse(myIndex.isProjectExcludeRoot(projectOutput)); - - module2Output = myModule1Dir.createChildDirectory(this, module2Output.getName()); - assertFalse(myIndex.isProjectExcludeRoot(module2Output)); - - module2TestOutput = myModule2Dir.createChildDirectory(this, module2TestOutput.getName()); - assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput)); + assertExcluded(excluded, myModule); - checkExcluded(excluded, myModule); - checkExcluded(projectOutput, myModule); - checkExcluded(module2Output, myModule); - checkExcluded(module2TestOutput, myModule2); + projectOutput = myModule1Dir.createChildDirectory(this, projectOutput.getName()); + assertExcluded(projectOutput, myModule); + + module2Output = myModule1Dir.createChildDirectory(this, module2Output.getName()); + assertExcluded(module2Output, myModule); + + module2TestOutput = myModule2Dir.createChildDirectory(this, module2TestOutput.getName()); + assertExcluded(module2TestOutput, myModule2); assertEquals(created.toString(), 4, created.size()); - - assertFalse(myIndex.isProjectExcludeRoot(excluded)); - assertFalse(myIndex.isProjectExcludeRoot(projectOutput)); - assertFalse(myIndex.isProjectExcludeRoot(module2Output)); - assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput)); } public void testExcludesShouldBeRecognizedRightOnRefresh() throws Exception { @@ -616,9 +591,9 @@ public class DirectoryIndexTest extends IdeaTestCase { assertEquals("dir", e.getFileName()); VirtualFile file = e.getFile(); - checkInProject(file); - checkExcluded(file.findFileByRelativePath("excluded"), myModule); - checkExcluded(file.findFileByRelativePath("excluded/foo"), myModule); + assertInProject(file); + assertExcluded(file.findFileByRelativePath("excluded"), myModule); + assertExcluded(file.findFileByRelativePath("excluded/foo"), myModule); } }; @@ -647,8 +622,8 @@ public class DirectoryIndexTest extends IdeaTestCase { }); - checkExcluded(LocalFileSystem.getInstance().findFileByIoFile(f.getParentFile().getParentFile()), myModule); - checkInProject(LocalFileSystem.getInstance().findFileByIoFile(f)); + assertExcluded(LocalFileSystem.getInstance().findFileByIoFile(f.getParentFile().getParentFile()), myModule); + assertInProject(LocalFileSystem.getInstance().findFileByIoFile(f)); } public void testLibraryDirInContent() throws Exception { @@ -670,7 +645,7 @@ public class DirectoryIndexTest extends IdeaTestCase { checkInfo(myLibSrcDir, myModule, true, true, "", null, myModule, myModule3); checkInfo(myResDir, myModule, true, false, "", JavaResourceRootType.RESOURCE, myModule); - assertInstanceOf(assertOneElement(checkInProject(myResDir).getOrderEntries()), ModuleSourceOrderEntry.class); + assertInstanceOf(assertOneElement(assertInProject(myResDir).getOrderEntries()), ModuleSourceOrderEntry.class); checkInfo(myExcludedLibSrcDir, null, true, false, "lib.src.exc", null, myModule3, myModule); checkInfo(myExcludedLibClsDir, null, true, false, "lib.cls.exc", null, myModule3); @@ -690,9 +665,8 @@ public class DirectoryIndexTest extends IdeaTestCase { assertTrue(fileIndex.isIgnored(myOutputDir)); assertTrue(fileIndex.isIgnored(myModule1OutputDir)); assertFalse(fileIndex.isIgnored(myOutputDir.getParent())); - assertTrue(myIndex.isProjectExcludeRoot(myOutputDir)); - checkExcluded(myOutputDir, null); - assertFalse(myIndex.isProjectExcludeRoot(myModule1OutputDir)); + assertExcludedFromProject(myOutputDir); + assertExcludedFromProject(myModule1OutputDir); String moduleOutputUrl = myModule1OutputDir.getUrl(); myOutputDir.delete(this); @@ -701,10 +675,8 @@ public class DirectoryIndexTest extends IdeaTestCase { myOutputDir = myRootVFile.createChildDirectory(this, "out"); myModule1OutputDir = myOutputDir.createChildDirectory(this, "module1"); - assertTrue(myIndex.isProjectExcludeRoot(myOutputDir)); - checkExcluded(myOutputDir, null); - assertTrue(myIndex.isProjectExcludeRoot(myModule1OutputDir)); - checkExcluded(myModule1OutputDir, null); + assertExcludedFromProject(myOutputDir); + assertExcludedFromProject(myModule1OutputDir); assertTrue(fileIndex.isIgnored(myModule1OutputDir)); PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, true); @@ -714,21 +686,20 @@ public class DirectoryIndexTest extends IdeaTestCase { PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, true); // now no module inherits project output dir, but it still should be project-excluded - assertTrue(myIndex.isProjectExcludeRoot(myOutputDir)); - checkExcluded(myOutputDir, null); + assertExcludedFromProject(myOutputDir); // project output inside module content shouldn't be projectExcludeRoot VirtualFile projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent"); getCompilerProjectExtension().setCompilerOutputUrl(projectOutputUnderContent.getUrl()); fireRootsChanged(); - assertFalse(myIndex.isProjectExcludeRoot(myOutputDir)); - assertFalse(myIndex.isProjectExcludeRoot(projectOutputUnderContent)); - + assertNotExcluded(myOutputDir); + assertExcluded(projectOutputUnderContent, myModule); + projectOutputUnderContent.delete(this); projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent"); - assertFalse(myIndex.isProjectExcludeRoot(myOutputDir)); - assertFalse(myIndex.isProjectExcludeRoot(projectOutputUnderContent)); + assertNotExcluded(myOutputDir); + assertExcluded(projectOutputUnderContent, myModule); } public void testFileContentAndSourceRoots() throws IOException { @@ -738,7 +709,7 @@ public class DirectoryIndexTest extends IdeaTestCase { VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt"); VirtualFile fileTestSourceRoot = myRootVFile.createChildData(this, "fileTestSourceRoot.txt"); - checkNotInProject(fileRoot); + assertNotInProject(fileRoot); assertFalse(fileIndex.isInContent(fileRoot)); assertIteratedContent(fileIndex, null, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot)); @@ -771,7 +742,7 @@ public class DirectoryIndexTest extends IdeaTestCase { // removing file content root PsiTestUtil.removeContentEntry(myModule, contentEntry); - checkNotInProject(fileRoot); + assertNotInProject(fileRoot); assertFalse(fileIndex.isInContent(fileRoot)); assertFalse(fileIndex.isInSource(fileRoot)); assertIteratedContent(fileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Arrays.asList(fileRoot)); @@ -821,7 +792,7 @@ public class DirectoryIndexTest extends IdeaTestCase { PsiTestUtil.addExcludedRoot(myModule, fileExcludeRoot); assertFalse(fileIndex.isInContent(fileExcludeRoot)); assertFalse(fileIndex.isInSource(fileExcludeRoot)); - checkExcluded(fileExcludeRoot, myModule); + assertExcluded(fileExcludeRoot, myModule); assertIteratedContent(fileIndex, null, Arrays.asList(fileExcludeRoot)); // removing file exclude root @@ -842,7 +813,7 @@ public class DirectoryIndexTest extends IdeaTestCase { PsiTestUtil.addExcludedRoot(myModule, fileRoot); assertFalse(fileIndex.isInContent(fileRoot)); - checkExcluded(fileRoot, myModule); + assertExcluded(fileRoot, myModule); assertIteratedContent(fileIndex, null, Arrays.asList(fileRoot)); // removing file exclude root @@ -869,7 +840,7 @@ public class DirectoryIndexTest extends IdeaTestCase { VirtualFile temp = myRootVFile.createChildDirectory(this, "temp"); VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt"); - checkNotInProject(fileSourceRoot); + assertNotInProject(fileSourceRoot); PsiTestUtil.addContentRoot(myModule, fileSourceRoot); PsiTestUtil.addSourceRoot(myModule, fileSourceRoot); @@ -879,7 +850,7 @@ public class DirectoryIndexTest extends IdeaTestCase { // delete and recreate fileSourceRoot.delete(this); - checkNotInProject(fileSourceRoot); + assertNotInProject(fileSourceRoot); assertFalse(fileIndex.isInContent(fileSourceRoot)); assertFalse(fileIndex.isInSource(fileSourceRoot)); fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt"); @@ -889,11 +860,11 @@ public class DirectoryIndexTest extends IdeaTestCase { // delete and move from another dir fileSourceRoot.delete(this); - checkNotInProject(fileSourceRoot); + assertNotInProject(fileSourceRoot); assertFalse(fileIndex.isInContent(fileSourceRoot)); assertFalse(fileIndex.isInSource(fileSourceRoot)); fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt"); - checkNotInProject(fileSourceRoot); + assertNotInProject(fileSourceRoot); fileSourceRoot.move(this, myRootVFile); checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule); assertTrue(fileIndex.isInContent(fileSourceRoot)); @@ -901,11 +872,11 @@ public class DirectoryIndexTest extends IdeaTestCase { // delete and copy from another dir fileSourceRoot.delete(this); - checkNotInProject(fileSourceRoot); + assertNotInProject(fileSourceRoot); assertFalse(fileIndex.isInContent(fileSourceRoot)); assertFalse(fileIndex.isInSource(fileSourceRoot)); fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt"); - checkNotInProject(fileSourceRoot); + assertNotInProject(fileSourceRoot); fileSourceRoot = fileSourceRoot.copy(this, myRootVFile, "fileSourceRoot.txt"); checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule); assertTrue(fileIndex.isInContent(fileSourceRoot)); @@ -913,25 +884,25 @@ public class DirectoryIndexTest extends IdeaTestCase { // delete and rename from another file fileSourceRoot.delete(this); - checkNotInProject(fileSourceRoot); + assertNotInProject(fileSourceRoot); assertFalse(fileIndex.isInContent(fileSourceRoot)); assertFalse(fileIndex.isInSource(fileSourceRoot)); fileSourceRoot = myRootVFile.createChildData(this, "temp_file.txt"); - checkNotInProject(fileSourceRoot); + assertNotInProject(fileSourceRoot); fileSourceRoot.rename(this, "fileSourceRoot.txt"); checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule); assertTrue(fileIndex.isInContent(fileSourceRoot)); assertTrue(fileIndex.isInSource(fileSourceRoot)); } - private void checkInfo(VirtualFile dir, + private void checkInfo(VirtualFile file, @Nullable Module module, boolean isInLibrary, boolean isInLibrarySource, @Nullable String packageName, @Nullable final JpsModuleSourceRootType moduleSourceRootType, Module... modulesOfOrderEntries) { - DirectoryInfo info = checkInProject(dir); + DirectoryInfo info = assertInProject(file); assertEquals(module, info.getModule()); if (moduleSourceRootType != null) { assertTrue("isInModuleSource", info.isInModuleSource()); @@ -944,8 +915,8 @@ public class DirectoryIndexTest extends IdeaTestCase { assertEquals(isInLibrarySource, info.isInLibrarySource()); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); - if (dir.isDirectory()) { - assertEquals(packageName, fileIndex.getPackageNameByDirectory(dir)); + if (file.isDirectory()) { + assertEquals(packageName, fileIndex.getPackageNameByDirectory(file)); } assertEquals(Arrays.toString(info.getOrderEntries()), modulesOfOrderEntries.length, info.getOrderEntries().length); @@ -955,25 +926,33 @@ public class DirectoryIndexTest extends IdeaTestCase { } } - private void checkNotInProject(VirtualFile dir) { - DirectoryInfo info = myIndex.getInfoForFile(dir); + private void assertNotInProject(VirtualFile file) { + DirectoryInfo info = myIndex.getInfoForFile(file); assertFalse(info.toString(), info.isInProject()); assertFalse(info.toString(), info.isExcluded()); } - private void checkExcluded(VirtualFile dir, Module module) { - DirectoryInfo info = myIndex.getInfoForFile(dir); + private void assertExcluded(VirtualFile file, Module module) { + DirectoryInfo info = myIndex.getInfoForFile(file); assertTrue(info.toString(), info.isExcluded()); assertEquals(module, info.getModule()); } - private DirectoryInfo checkInProject(VirtualFile output2) { - DirectoryInfo info = myIndex.getInfoForFile(output2); - assertTrue(output2.toString(), info.isInProject()); + private DirectoryInfo assertInProject(VirtualFile file) { + DirectoryInfo info = myIndex.getInfoForFile(file); + assertTrue(file.toString(), info.isInProject()); info.assertConsistency(); return info; } + private void assertNotExcluded(VirtualFile file) { + assertFalse(myIndex.getInfoForFile(file).isExcluded()); + } + + private void assertExcludedFromProject(VirtualFile file) { + assertExcluded(file, null); + } + private void checkPackage(String packageName, boolean includeLibrarySources, VirtualFile... expectedDirs) { VirtualFile[] actualDirs = myIndex.getDirectoriesByPackageName(packageName, includeLibrarySources).toArray(VirtualFile.EMPTY_ARRAY); assertNotNull(actualDirs); diff --git a/java/remote-servers/impl/remote-servers-java-impl.iml b/java/remote-servers/impl/remote-servers-java-impl.iml index b0228d7f4075..6999e2deac71 100644 --- a/java/remote-servers/impl/remote-servers-java-impl.iml +++ b/java/remote-servers/impl/remote-servers-java-impl.iml @@ -13,6 +13,8 @@ + + diff --git a/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml b/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml index cec87d9643f2..24a0776ccd29 100644 --- a/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml +++ b/java/remote-servers/impl/src/META-INF/RemoteServersJava.xml @@ -1,7 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudAccountSelectionPanel.form b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudAccountSelectionPanel.form new file mode 100644 index 000000000000..87eff737a482 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudAccountSelectionPanel.form @@ -0,0 +1,43 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudAccountSelectionPanel.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudAccountSelectionPanel.java new file mode 100644 index 000000000000..aecaebd960b9 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudAccountSelectionPanel.java @@ -0,0 +1,189 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + +import com.intellij.ide.DataManager; +import com.intellij.ide.actions.ShowSettingsUtilImpl; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.ex.SingleConfigurableEditor; +import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Ref; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.configuration.RemoteServersManager; +import com.intellij.remoteServer.impl.configuration.RemoteServerConfigurable; +import com.intellij.util.Consumer; +import com.intellij.util.text.UniqueNameGenerator; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; + + +public class CloudAccountSelectionPanel { + + private JButton myNewButton; + private ComboBox myAccountComboBox; + private JPanel myMainPanel; + + private final List> myCloudTypes; + + private Runnable myServerSelectionListener; + + public CloudAccountSelectionPanel(List> cloudTypes) { + myCloudTypes = cloudTypes; + + for (ServerType cloudType : cloudTypes) { + for (RemoteServer account : RemoteServersManager.getInstance().getServers(cloudType)) { + myAccountComboBox.addItem(new AccountItem(account)); + } + } + + myNewButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + onNewButton(); + } + }); + + myAccountComboBox.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (myServerSelectionListener != null) { + myServerSelectionListener.run(); + } + } + }); + } + + public void setAccountSelectionListener(Runnable listener) { + myServerSelectionListener = listener; + } + + private void onNewButton() { + DefaultActionGroup group = new DefaultActionGroup(); + for (final ServerType cloudType : myCloudTypes) { + group.add(new AnAction(cloudType.getPresentableName(), cloudType.getPresentableName(), cloudType.getIcon()) { + + @Override + public void actionPerformed(AnActionEvent e) { + createAccount(cloudType); + } + }); + } + JBPopupFactory.getInstance().createActionGroupPopup("New Account", group, DataManager.getInstance().getDataContext(myMainPanel), + JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false) + .showUnderneathOf(myNewButton); + } + + private void createAccount(ServerType cloudType) { + RemoteServer newAccount = RemoteServersManager.getInstance().createServer(cloudType, generateServerName(cloudType)); + + final Ref> errorConsumerRef = new Ref>(); + + RemoteServerConfigurable configurable = new RemoteServerConfigurable(newAccount, null, true) { + + @Override + protected void setConnectionStatusText(boolean error, String text) { + super.setConnectionStatusText(error, error ? "" : text); + errorConsumerRef.get().consume(error ? text : null); + } + }; + + final SingleConfigurableEditor configurableEditor + = new SingleConfigurableEditor(myMainPanel, configurable, ShowSettingsUtilImpl.createDimensionKey(configurable), false) { + + { + errorConsumerRef.set(new Consumer() { + + @Override + public void consume(String s) { + setErrorText(s); + } + }); + } + }; + + if (!configurableEditor.showAndGet()) { + return; + } + + newAccount.setName(configurable.getDisplayName()); + + RemoteServersManager.getInstance().addServer(newAccount); + AccountItem newAccountItem = new AccountItem(newAccount); + myAccountComboBox.addItem(newAccountItem); + myAccountComboBox.setSelectedItem(newAccountItem); + } + + public JComponent getMainPanel() { + return myMainPanel; + } + + @Nullable + public RemoteServer getSelectedAccount() { + AccountItem selectedItem = (AccountItem)myAccountComboBox.getSelectedItem(); + return selectedItem == null ? null : selectedItem.getAccount(); + } + + private static String generateServerName(ServerType cloudType) { + return UniqueNameGenerator.generateUniqueName(cloudType.getPresentableName(), new Condition() { + + @Override + public boolean value(String s) { + for (RemoteServer server : RemoteServersManager.getInstance().getServers()) { + if (server.getName().equals(s)) { + return false; + } + } + return true; + } + }); + } + + public void validate() throws ConfigurationException { + if (getSelectedAccount() == null) { + throw new ConfigurationException("Account required"); + } + } + + private static class AccountItem { + + private final RemoteServer myAccount; + + public AccountItem(RemoteServer account) { + myAccount = account; + } + + public RemoteServer getAccount() { + return myAccount; + } + + @Override + public String toString() { + return myAccount.getName(); + } + } +} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java new file mode 100644 index 000000000000..14bd043a7f23 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfigurable.java @@ -0,0 +1,166 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.runtime.Deployment; +import com.intellij.remoteServer.runtime.ServerConnection; +import com.intellij.remoteServer.runtime.ServerConnector; +import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance; +import com.intellij.remoteServer.util.*; +import com.intellij.util.concurrency.Semaphore; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicReference; + + +public abstract class CloudApplicationConfigurable< + SC extends CloudConfigurationBase, + DC extends CloudDeploymentNameConfiguration, + SR extends CloudMultiSourceServerRuntimeInstance, + AC extends CloudApplicationConfiguration> { + + private final Project myProject; + private final Disposable myParentDisposable; + + private DelayedRunner myRunner; + + private RemoteServer myAccount; + + public CloudApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) { + myProject = project; + myParentDisposable = parentDisposable; + } + + public void setAccount(RemoteServer account) { + myAccount = account; + clearCloudData(); + } + + protected RemoteServer getAccount() { + return (RemoteServer)myAccount; + } + + public JComponent getComponent() { + JComponent result = getMainPanel(); + if (myRunner == null) { + myRunner = new DelayedRunner(result) { + + private RemoteServer myPreviousAccount; + + @Override + protected boolean wasChanged() { + boolean result = myPreviousAccount != myAccount; + if (result) { + myPreviousAccount = myAccount; + } + return result; + } + + @Override + protected void run() { + loadCloudData(); + } + }; + Disposer.register(myParentDisposable, myRunner); + } + return result; + } + + protected void clearCloudData() { + getExistingComboBox().removeAllItems(); + } + + protected void loadCloudData() { + new ConnectionTask>("Loading existing applications list") { + + @Override + protected void run(final ServerConnection connection, + final Semaphore semaphore, + final AtomicReference> result) { + connection.connectIfNeeded(new ServerConnector.ConnectionCallback() { + + @Override + public void connected(@NotNull ServerRuntimeInstance serverRuntimeInstance) { + connection.computeDeployments(new Runnable() { + + @Override + public void run() { + result.set(connection.getDeployments()); + semaphore.up(); + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + if (!Disposer.isDisposed(myParentDisposable)) { + setupExistingApplications(result.get()); + } + } + }); + } + }); + } + + @Override + public void errorOccurred(@NotNull String errorMessage) { + runtimeErrorOccurred(errorMessage); + semaphore.up(); + } + }); + } + + @Override + protected Collection run(SR serverRuntimeInstance) throws ServerRuntimeException { + return null; + } + }.performAsync(); + } + + private void setupExistingApplications(Collection deployments) { + JComboBox existingComboBox = getExistingComboBox(); + existingComboBox.removeAllItems(); + for (Deployment deployment : deployments) { + existingComboBox.addItem(deployment.getName()); + } + } + + protected Project getProject() { + return myProject; + } + + protected abstract JComboBox getExistingComboBox(); + + protected abstract JComponent getMainPanel(); + + public abstract AC createConfiguration(); + + public abstract void validate() throws ConfigurationException; + + protected abstract class ConnectionTask extends CloudConnectionTask { + + public ConnectionTask(String title) { + super(myProject, title, CloudApplicationConfigurable.this.getAccount()); + } + } +} + diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java new file mode 100644 index 000000000000..9af0f1ad472b --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudApplicationConfiguration.java @@ -0,0 +1,36 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + + +public abstract class CloudApplicationConfiguration { + + private boolean myExisting; + private final String myExistingAppName; + + protected CloudApplicationConfiguration(boolean existing, String existingAppName) { + myExisting = existing; + myExistingAppName = existingAppName; + } + + public boolean isExisting() { + return myExisting; + } + + public String getExistingAppName() { + return myExistingAppName; + } +} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java new file mode 100644 index 000000000000..4aa8d60bcea4 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilder.java @@ -0,0 +1,114 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + +import com.intellij.icons.AllIcons; +import com.intellij.ide.util.projectWizard.JavaModuleBuilder; +import com.intellij.ide.util.projectWizard.ModuleBuilderListener; +import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.module.JavaModuleType; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.remoteServer.configuration.RemoteServer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + + +public class CloudModuleBuilder extends JavaModuleBuilder { + + private RemoteServer myAccount; + private CloudApplicationConfiguration myApplicationConfiguration; + + public CloudModuleBuilder() { + addListener(new ModuleBuilderListener() { + + @Override + public void moduleCreated(@NotNull Module module) { + configureModule(module); + } + }); + } + + public String getBuilderId() { + return getClass().getName(); + } + + @Override + public Icon getBigIcon() { + return AllIcons.General.Balloon; + } + + @Override + public Icon getNodeIcon() { + return AllIcons.General.Balloon; + } + + @Override + public String getDescription() { + return "Java module of PAAS cloud application"; + } + + @Override + public String getPresentableName() { + return "Clouds"; + } + + @Override + public String getGroupName() { + return "Clouds"; + } + + @Override + public String getParentGroup() { + return JavaModuleType.JAVA_GROUP; + } + + @Override + public int getWeight() { + return 30; + } + + @Override + public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) { + return ModuleWizardStep.EMPTY_ARRAY; + } + + @Nullable + @Override + public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) { + return new CloudModuleWizardStep(this, context.getProject(), parentDisposable); + } + + public void setAccount(RemoteServer account) { + myAccount = account; + } + + public RemoteServer getAccount() { + return myAccount; + } + + public void setApplicationConfiguration(CloudApplicationConfiguration applicationConfiguration) { + myApplicationConfiguration = applicationConfiguration; + } + + private void configureModule(final Module module) { + CloudModuleBuilderContribution.getInstanceByType(myAccount.getType()).configureModule(module, myAccount, myApplicationConfiguration); + } +} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java new file mode 100644 index 000000000000..6643c89cc1c4 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContribution.java @@ -0,0 +1,48 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import org.jetbrains.annotations.Nullable; + + +public abstract class CloudModuleBuilderContribution { + + public static final ExtensionPointName EP_NAME + = ExtensionPointName.create("com.intellij.remoteServer.moduleBuilderContribution"); + + public abstract ServerType getCloudType(); + + public abstract CloudApplicationConfigurable createApplicationConfigurable(@Nullable Project project, Disposable parentDisposable); + + public abstract void configureModule(Module module, + RemoteServer account, + CloudApplicationConfiguration configuration); + + public static CloudModuleBuilderContribution getInstanceByType(ServerType cloudType) { + for (CloudModuleBuilderContribution contribution : EP_NAME.getExtensions()) { + if (contribution.getCloudType() == cloudType) { + return contribution; + } + } + return null; + } +} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java new file mode 100644 index 000000000000..6a927d97bb93 --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleBuilderContributionBase.java @@ -0,0 +1,142 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module; + +import com.intellij.execution.RunManagerEx; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModulePointer; +import com.intellij.openapi.module.ModulePointerManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType; +import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration; +import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl; +import com.intellij.remoteServer.util.*; +import com.intellij.remoteServer.util.ssh.SshKeyChecker; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + + +public abstract class CloudModuleBuilderContributionBase< + SC extends CloudConfigurationBase, + DC extends CloudDeploymentNameConfiguration, + AC extends CloudApplicationConfiguration, + SR extends CloudMultiSourceServerRuntimeInstance> + extends CloudModuleBuilderContribution { + + @Override + public void configureModule(Module module, + RemoteServer account, + CloudApplicationConfiguration applicationConfiguration) { + RemoteServer castedAccount = (RemoteServer)account; + final AC castedApplicationConfiguration = (AC)applicationConfiguration; + + DC deploymentConfiguration = createDeploymentConfiguration(); + + if (applicationConfiguration.isExisting()) { + deploymentConfiguration.setDefaultDeploymentName(false); + deploymentConfiguration.setDeploymentName(applicationConfiguration.getExistingAppName()); + } + + final DeployToServerRunConfiguration runConfiguration = createRunConfiguration(module, castedAccount, deploymentConfiguration); + + final String cloudName = account.getType().getPresentableName(); + final Project project = module.getProject(); + new CloudConnectionTask(project, CloudBundle.getText("cloud.support", cloudName), castedAccount) { + + CloudNotifier myNotifier = new CloudNotifier(cloudName); + + boolean myFirstAttempt = true; + + @Override + protected Object run(SR serverRuntime) throws ServerRuntimeException { + doConfigureModule(castedApplicationConfiguration, runConfiguration, myFirstAttempt, serverRuntime); + myNotifier.showMessage(CloudBundle.getText("cloud.support.added", cloudName), MessageType.INFO); + return null; + } + + @Override + protected void runtimeErrorOccurred(@NotNull String errorMessage) { + myFirstAttempt = false; + new SshKeyChecker().checkServerError(errorMessage, myNotifier, project, this); + } + }.performAsync(); + } + + private DeployToServerRunConfiguration createRunConfiguration(Module module, + RemoteServer server, + DC deploymentConfiguration) { + Project project = module.getProject(); + + String serverName = server.getName(); + + String name = generateRunConfigurationName(serverName, module.getName()); + + final RunManagerEx runManager = RunManagerEx.getInstanceEx(project); + final RunnerAndConfigurationSettings runSettings + = runManager.createRunConfiguration(name, getRunConfigurationType().getConfigurationFactories()[0]); + + final DeployToServerRunConfiguration result = (DeployToServerRunConfiguration)runSettings.getConfiguration(); + + result.setServerName(serverName); + + final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module); + result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer)); + + result.setDeploymentConfiguration(deploymentConfiguration); + + runManager.addConfiguration(runSettings, false); + runManager.setSelectedConfiguration(runSettings); + + return result; + } + + private static String generateRunConfigurationName(String serverName, String moduleName) { + return CloudBundle.getText("run.configuration.name", serverName, moduleName); + } + + private DeployToServerConfigurationType getRunConfigurationType() { + String id = DeployToServerConfigurationType.getId(getCloudType()); + for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) { + if (configurationType instanceof DeployToServerConfigurationType) { + DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType; + if (deployConfigurationType.getId().equals(id)) { + return deployConfigurationType; + } + } + } + return null; + } + + @Override + public abstract ServerType getCloudType(); + + @Override + public abstract CloudApplicationConfigurable createApplicationConfigurable(@Nullable Project project, + Disposable parentDisposable); + + protected abstract DC createDeploymentConfiguration(); + + protected abstract void doConfigureModule(AC applicationConfiguration, + DeployToServerRunConfiguration runConfiguration, + boolean firstAttempt, + SR serverRuntime) throws ServerRuntimeException; +} diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.form b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.form new file mode 100644 index 000000000000..19cbaa7f2a5f --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.form @@ -0,0 +1,50 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java new file mode 100644 index 000000000000..4ca4aa4685df --- /dev/null +++ b/java/remote-servers/impl/src/com/intellij/remoteServer/impl/module/CloudModuleWizardStep.java @@ -0,0 +1,143 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.remoteServer.impl.module;/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.intellij.ide.util.projectWizard.ModuleWizardStep; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.remoteServer.ServerType; +import com.intellij.remoteServer.configuration.RemoteServer; +import com.intellij.util.containers.hash.HashMap; + +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + +public class CloudModuleWizardStep extends ModuleWizardStep { + + private JPanel myMainPanel; + private JPanel myAccountPanelPlaceHolder; + private JPanel myApplicationPanelPlaceHolder; + + private final CloudModuleBuilder myModuleBuilder; + private final Project myProject; + private final Disposable myParentDisposable; + + private CloudAccountSelectionPanel myAccountSelectionPanel; + + private Map, CloudApplicationConfigurable> myCloudType2ApplicationConfigurable; + + public CloudModuleWizardStep(CloudModuleBuilder moduleBuilder, Project project, Disposable parentDisposable) { + myModuleBuilder = moduleBuilder; + myProject = project; + myParentDisposable = parentDisposable; + + myCloudType2ApplicationConfigurable = new HashMap, CloudApplicationConfigurable>(); + + List> cloudTypes = new ArrayList>(); + for (CloudModuleBuilderContribution contribution : CloudModuleBuilderContribution.EP_NAME.getExtensions()) { + cloudTypes.add(contribution.getCloudType()); + } + + myAccountSelectionPanel = new CloudAccountSelectionPanel(cloudTypes); + myAccountPanelPlaceHolder.add(myAccountSelectionPanel.getMainPanel()); + + myAccountSelectionPanel.setAccountSelectionListener(new Runnable() { + + @Override + public void run() { + onAccountSelectionChanged(); + } + }); + onAccountSelectionChanged(); + } + + private RemoteServer getSelectedAccount() { + return myAccountSelectionPanel.getSelectedAccount(); + } + + private void onAccountSelectionChanged() { + CardLayout applicationPlaceHolderLayout = (CardLayout)myApplicationPanelPlaceHolder.getLayout(); + + RemoteServer account = getSelectedAccount(); + boolean haveAccount = account != null; + myApplicationPanelPlaceHolder.setVisible(haveAccount); + if (!haveAccount) { + return; + } + + ServerType cloudType = account.getType(); + String cardName = cloudType.getId(); + CloudApplicationConfigurable applicationConfigurable = getApplicationConfigurable(); + if (applicationConfigurable == null) { + applicationConfigurable + = CloudModuleBuilderContribution.getInstanceByType(cloudType).createApplicationConfigurable(myProject, myParentDisposable); + myCloudType2ApplicationConfigurable.put(cloudType, applicationConfigurable); + myApplicationPanelPlaceHolder.add(applicationConfigurable.getComponent(), cardName); + } + applicationPlaceHolderLayout.show(myApplicationPanelPlaceHolder, cardName); + + applicationConfigurable.setAccount(account); + } + + @Override + public JComponent getComponent() { + return myMainPanel; + } + + private CloudApplicationConfigurable getApplicationConfigurable() { + RemoteServer account = getSelectedAccount(); + if (account == null) { + return null; + } + return myCloudType2ApplicationConfigurable.get(account.getType()); + } + + @Override + public void updateDataModel() { + myModuleBuilder.setAccount(myAccountSelectionPanel.getSelectedAccount()); + CloudApplicationConfigurable configurable = getApplicationConfigurable(); + myModuleBuilder.setApplicationConfiguration(configurable == null ? null : configurable.createConfiguration()); + } + + @Override + public boolean validate() throws ConfigurationException { + myAccountSelectionPanel.validate(); + CloudApplicationConfigurable configurable = getApplicationConfigurable(); + if (configurable != null) { + configurable.validate(); + } + return super.validate(); + } +} diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java index c738b55b85ae..869f01cc7394 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java @@ -411,7 +411,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { final ParameterInfo initInfo = builder.findParameterization(Replacer.stripTypedVariableDecoration(initText)); if (initInfo != null) { - initInfo.setVariableInitialContext(true); + initInfo.setVariableInitializerContext(true); } } } @@ -431,20 +431,6 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { } } - @Override - public void visitMethod(PsiMethod method) { - super.visitMethod(method); - - String name = method.getName(); - if (StructuralSearchUtil.isTypedVariable(name)) { - name = Replacer.stripTypedVariableDecoration(name); - - ParameterInfo methodInfo = builder.findParameterization(name); - methodInfo.setScopeParameterization(true); - //if (scopedParameterizations != null) scopedParameterizations.put(method.getTextRange(), methodInfo); - } - } - @Override public void visitParameter(PsiParameter parameter) { super.visitParameter(parameter); @@ -462,8 +448,8 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { ParameterInfo typeInfo = builder.findParameterization(type); if (nameInfo != null && typeInfo != null && !(parameter.getParent() instanceof PsiCatchSection)) { - nameInfo.setParameterContext(false); - typeInfo.setParameterContext(false); + nameInfo.setArgumentContext(false); + typeInfo.setArgumentContext(false); typeInfo.setMethodParameterContext(true); nameInfo.setMethodParameterContext(true); typeInfo.setElement(parameter.getTypeElement()); @@ -524,7 +510,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { buf.append('\n'); } } - else if (info.isParameterContext()) { + else if (info.isArgumentContext()) { buf.append(','); } else if (parent instanceof PsiClass) { diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java index 401b84004858..0ea857b16362 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java @@ -321,18 +321,14 @@ public class JavaMatchingVisitor extends JavaElementVisitor { @Override public void visitNameValuePair(PsiNameValuePair pair) { final PsiIdentifier nameIdentifier = pair.getNameIdentifier(); - if (nameIdentifier == null) { - myMatchingVisitor.setResult(true); - return; - } final PsiNameValuePair elementNameValuePair = (PsiNameValuePair)myMatchingVisitor.getElement(); - PsiIdentifier matchedNameValuePair = elementNameValuePair.getNameIdentifier(); + final PsiIdentifier otherIdentifier = elementNameValuePair.getNameIdentifier(); - PsiAnnotationMemberValue annotationInitializer = pair.getValue(); + final PsiAnnotationMemberValue annotationInitializer = pair.getValue(); if (annotationInitializer != null) { - boolean isTypedInitializer = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(annotationInitializer) && - annotationInitializer instanceof PsiReferenceExpression; + final boolean isTypedInitializer = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(annotationInitializer) && + annotationInitializer instanceof PsiReferenceExpression; myMatchingVisitor.setResult(myMatchingVisitor.match(annotationInitializer, elementNameValuePair.getValue()) || (isTypedInitializer && @@ -344,13 +340,13 @@ public class JavaMatchingVisitor extends JavaElementVisitor { final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(nameIdentifier); if (handler instanceof SubstitutionHandler) { - myMatchingVisitor - .setResult(((SubstitutionHandler)handler).handle(matchedNameValuePair, - myMatchingVisitor.getMatchContext())); + myMatchingVisitor.setResult(((SubstitutionHandler)handler).handle(otherIdentifier, myMatchingVisitor.getMatchContext())); + } + else if (nameIdentifier != null) { + myMatchingVisitor.setResult(myMatchingVisitor.match(nameIdentifier, otherIdentifier)); } else { - myMatchingVisitor - .setResult(myMatchingVisitor.match(nameIdentifier, matchedNameValuePair)); + myMatchingVisitor.setResult(otherIdentifier == null || otherIdentifier.getText().equals("value")); } } } diff --git a/platform/analysis-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java b/platform/analysis-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java index bf150428456e..75a2eca11e43 100644 --- a/platform/analysis-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java +++ b/platform/analysis-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java @@ -107,8 +107,8 @@ public class HighlightDisplayLevel { } } - private static class ImageHolder { - private static final Image ourErrorMaskImage = ImageLoader.loadFromResource("/general/errorMask.png"); + public static class ImageHolder { + public static final Image ourErrorMaskImage = ImageLoader.loadFromResource("/general/errorMask.png"); } private static final int EMPTY_ICON_DIM = 12; diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java index c6b69bc6dc27..0f50f8d05ecf 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java +++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicatorProvider.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable; */ public abstract class ProgressIndicatorProvider { @Nullable - public static volatile ProgressIndicatorProvider ourInstance; + public static ProgressIndicatorProvider ourInstance; @Nullable public static ProgressIndicatorProvider getInstance() { @@ -36,27 +36,22 @@ public abstract class ProgressIndicatorProvider { @Nullable public static ProgressIndicator getGlobalProgressIndicator() { - ProgressIndicatorProvider provider = ourInstance; - return provider != null ? provider.getProgressIndicator() : null; + return ourInstance != null ? ourInstance.getProgressIndicator() : null; } public abstract NonCancelableSection startNonCancelableSection(); @NotNull public static NonCancelableSection startNonCancelableSectionIfSupported() { - ProgressIndicatorProvider provider = ourInstance; - return provider != null ? provider.startNonCancelableSection() : NonCancelableSection.EMPTY; + return ourInstance != null ? ourInstance.startNonCancelableSection() : NonCancelableSection.EMPTY; } public static volatile boolean ourNeedToCheckCancel = false; public static void checkCanceled() throws ProcessCanceledException { // smart optimization! There's a thread started in ProgressManagerImpl, that set's this flag up once in 10 milliseconds - if (ourNeedToCheckCancel) { - ProgressIndicatorProvider provider = ourInstance; - if (provider != null) { - provider.doCheckCanceled(); - ourNeedToCheckCancel = false; - } + if (ourNeedToCheckCancel && ourInstance != null) { + ourInstance.doCheckCanceled(); + ourNeedToCheckCancel = false; } } } diff --git a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java index d65e4367f130..a319700b4be2 100644 --- a/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java +++ b/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java @@ -50,14 +50,13 @@ public abstract class ProgressManager { }; } - private static volatile ProgressManager ourInstance; + private static ProgressManager ourInstance; public static ProgressManager getInstance() { - ProgressManager progressManager = ourInstance; - if (progressManager == null) { - ourInstance = progressManager = ServiceManager.getService(ProgressManager.class); + if (ourInstance == null) { + ourInstance = ServiceManager.getService(ProgressManager.class); } - return progressManager; + return ourInstance; } public abstract boolean hasProgressIndicator(); diff --git a/platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java b/platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java similarity index 100% rename from platform/platform-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java rename to platform/core-impl/src/com/intellij/ide/util/PropertiesComponentImpl.java diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index 5b82a62ae910..ae7ee4363247 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -56,6 +56,7 @@ import com.intellij.openapi.fileEditor.impl.EditorHistoryManager; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.keymap.MacKeymapUtil; +import com.intellij.openapi.keymap.impl.ModifierKeyDoubleClickHandler; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.progress.ProcessCanceledException; @@ -151,106 +152,25 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA private Component myContextComponent; private CalcThread myCalcThread; private static AtomicBoolean ourShiftIsPressed = new AtomicBoolean(false); - private final static Couple ourPressed = Couple.of(new AtomicBoolean(false), new AtomicBoolean(false)); - private final static Couple ourReleased = Couple.of(new AtomicBoolean(false), new AtomicBoolean(false)); - private static AtomicBoolean ourOtherKeyWasPressed = new AtomicBoolean(false); - private static AtomicLong ourLastTimePressed = new AtomicLong(0); private static AtomicBoolean showAll = new AtomicBoolean(false); private volatile ActionCallback myCurrentWorker = ActionCallback.DONE; private int myHistoryIndex = 0; boolean mySkipFocusGain = false; static { + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_SEARCH_EVERYWHERE, KeyEvent.VK_SHIFT, -1); + IdeEventQueue.getInstance().addPostprocessor(new IdeEventQueue.EventDispatcher() { @Override public boolean dispatch(AWTEvent event) { if (event instanceof KeyEvent) { - final KeyEvent keyEvent = (KeyEvent)event; - final int keyCode = keyEvent.getKeyCode(); - + final int keyCode = ((KeyEvent)event).getKeyCode(); if (keyCode == KeyEvent.VK_SHIFT) { ourShiftIsPressed.set(event.getID() == KeyEvent.KEY_PRESSED); - - if (keyEvent.isControlDown() || keyEvent.isAltDown() || keyEvent.isMetaDown()) { - resetState(); - return false; - } - if (ourOtherKeyWasPressed.get() && System.currentTimeMillis() - ourLastTimePressed.get() < 500) { - resetState(); - return false; - } - ourOtherKeyWasPressed.set(false); - if (ourPressed.first.get() && System.currentTimeMillis() - ourLastTimePressed.get() > 500) { - resetState(); - } - handleShift((KeyEvent)event); - return false; - } else { - ourLastTimePressed.set(System.currentTimeMillis()); - ourOtherKeyWasPressed.set(true); - if (keyCode == KeyEvent.VK_ESCAPE || keyCode == KeyEvent.VK_TAB) { - ourLastTimePressed.set(0); - } } - resetState(); } return false; } - - private void resetState() { - ourPressed.first.set(false); - ourPressed.second.set(false); - ourReleased.first.set(false); - ourReleased.second.set(false); - } - - private void handleShift(KeyEvent event) { - if (ourPressed.first.get() && System.currentTimeMillis() - ourLastTimePressed.get() > 300) { - resetState(); - return; - } - - if (event.getID() == KeyEvent.KEY_PRESSED) { - if (!ourPressed.first.get()) { - resetState(); - ourPressed.first.set(true); - ourLastTimePressed.set(System.currentTimeMillis()); - return; - } else { - if (ourPressed.first.get() && ourReleased.first.get()) { - ourPressed.second.set(true); - ourLastTimePressed.set(System.currentTimeMillis()); - return; - } - } - } else if (event.getID() == KeyEvent.KEY_RELEASED) { - if (ourPressed.first.get() && !ourReleased.first.get()) { - ourReleased.first.set(true); - ourLastTimePressed.set(System.currentTimeMillis()); - return; - } else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get()) { - resetState(); - run(event); - return; - } - } - resetState(); - } - - private void run(KeyEvent event) { - final ActionManager actionManager = ActionManager.getInstance(); - final AnAction action = actionManager.getAction(IdeActions.ACTION_SEARCH_EVERYWHERE); - if (KeymapManager.getInstance().getActiveKeymap().getShortcuts(IdeActions.ACTION_SEARCH_EVERYWHERE).length > 0) { - return; - } - final AnActionEvent anActionEvent = new AnActionEvent(event, - DataManager.getInstance().getDataContext(IdeFocusManager.findInstance().getFocusOwner()), - ActionPlaces.MAIN_MENU, - action.getTemplatePresentation(), - actionManager, - 0); - action.actionPerformed(anActionEvent); - } }, null); } @@ -1796,8 +1716,9 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA GotoActionModel model = new GotoActionModel(project, myFocusComponent, myEditor, myFile) { @Override protected MatchMode actionMatches(String pattern, @NotNull AnAction anAction) { - return NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE) - .matches(anAction.getTemplatePresentation().getText()) ? MatchMode.NAME : MatchMode.NONE; + String text = anAction.getTemplatePresentation().getText(); + return text != null && NameUtil.buildMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE) + .matches(text) ? MatchMode.NAME : MatchMode.NONE; } }; return new GotoActionItemProvider(model); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java index 8a4ad83395cb..91f0d3368521 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java @@ -459,7 +459,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C } final String groupName = myActionsMap.get(anAction); if (groupName == null) { - return matcher.matches(text, compiledPattern) ? MatchMode.NON_MENU : MatchMode.NONE; + return text != null && matcher.matches(text, compiledPattern) ? MatchMode.NON_MENU : MatchMode.NONE; } return text != null && matcher.matches(groupName + " " + text, compiledPattern) ? MatchMode.GROUP : MatchMode.NONE; } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java index 30d1bb592c42..b1385686bc3a 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -173,14 +173,6 @@ public class DirectoryIndexImpl extends DirectoryIndex { return null; } - @Override - public boolean isProjectExcludeRoot(@NotNull VirtualFile dir) { - checkAvailability(); - if (!(dir instanceof NewVirtualFile)) return false; - - return getRootIndex().isProjectExcludeRoot(dir); - } - @Override public String getPackageName(@NotNull VirtualFile dir) { checkAvailability(); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java index 080a3cc4e089..a910f6d596d2 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java @@ -541,7 +541,17 @@ public class SingleInspectionProfilePanel extends JPanel { } }); - myTreeExpander = new DefaultTreeExpander(myTreeTable.getTree()); + myTreeExpander = new DefaultTreeExpander(myTreeTable.getTree()) { + @Override + public boolean canExpand() { + return myTreeTable.isShowing(); + } + + @Override + public boolean canCollapse() { + return myTreeTable.isShowing(); + } + }; myProfileFilter = new MyFilterComponent(); return scrollPane; 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 60a173bdd1bc..966a456e1d38 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 @@ -149,8 +149,10 @@ public class InspectionsConfigTreeTable extends TreeTable { final MultiColoredHighlightSeverityIconSink sink = new MultiColoredHighlightSeverityIconSink(); for (final HighlightDisplayKey selectedInspectionsNode : inspectionsKeys) { final String toolId = selectedInspectionsNode.toString(); - sink.put(mySettings.getInspectionProfile().getToolDefaultState(toolId, mySettings.getProject()), - mySettings.getInspectionProfile().getNonDefaultTools(toolId, mySettings.getProject())); + if (mySettings.getInspectionProfile().getTools(toolId, mySettings.getProject()).isEnabled()) { + sink.put(mySettings.getInspectionProfile().getToolDefaultState(toolId, mySettings.getProject()), + mySettings.getInspectionProfile().getNonDefaultTools(toolId, mySettings.getProject())); + } } return sink.constructIcon(); } else if (column == IS_ENABLED_COLUMN) { @@ -207,6 +209,9 @@ public class InspectionsConfigTreeTable extends TreeTable { private boolean myIsFirst = true; public Icon constructIcon() { + if (myScopeToAverageSeverityMap.isEmpty()) { + return null; + } //TODO order scopes return !allScopesHasMixedSeverity() ? new MultiScopeSeverityIcon(myScopeToAverageSeverityMap) diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java index b74352c6d737..6f093ca66349 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/inspectionsTree/MultiScopeSeverityIcon.java @@ -46,7 +46,6 @@ public class MultiScopeSeverityIcon implements Icon { @Override public void paintIcon(final Component c, final Graphics g, final int i, final int j) { final int iconWidth = getIconWidth(); - final int iconHeightCoordinate = j + getIconHeight(); final int partWidth = iconWidth / myScopeToAverageSeverityMap.size(); @@ -57,9 +56,10 @@ public class MultiScopeSeverityIcon implements Icon { g.setColor(icon instanceof HighlightDisplayLevel.SingleColorIconWithMask ? ((HighlightDisplayLevel.SingleColorIconWithMask)icon).getColor() : MIXED_SEVERITY_COLOR); final int x = i + partWidth * idx; - g.fillRect(x, j, partWidth, iconHeightCoordinate); + g.fillRect(x, j, partWidth, getIconHeight()); idx++; } + g.drawImage(HighlightDisplayLevel.ImageHolder.ourErrorMaskImage, i, j, null); } @Override diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java index 22eb85914754..ebb7911e82be 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java @@ -360,14 +360,16 @@ public class MapReduceIndex implements UpdatableIndex contentData = myIndexer.map(content); + boolean sameValueForSavedIndexedResultAndCurrentOne = contentData.equals(data); if (!sameValueForSavedIndexedResultAndCurrentOne) { DebugAssertions.error( - "Unexpected difference in indexing of %s by index %s, file type %s, charset %s\nprevious indexed info %s", + "Unexpected difference in indexing of %s by index %s, file type %s, charset %s\ndiff %s\nprevious indexed info %s", fileContent.getFile(), myIndexId, fileContent.getFileType(), ((FileContentImpl)fileContent).getCharset(), + buildDiff(data, contentData), myIndexingTrace.get(hashId) ); } @@ -395,7 +397,7 @@ public class MapReduceIndex implements UpdatableIndex implements UpdatableIndex data, Map contentData) { + StringBuilder moreInfo = new StringBuilder(); + if (contentData.size() != data.size()) { + moreInfo.append("Indexer has different number of elements, previously ").append(data.size()).append(" after ") + .append(contentData.size()).append("\n"); + } else { + moreInfo.append("total ").append(contentData.size()).append(" entries\n"); + } + + for(Map.Entry keyValueEntry:contentData.entrySet()) { + if (!data.containsKey(keyValueEntry.getKey())) { + moreInfo.append("Previous data doesn't contain:").append(keyValueEntry.getKey()).append( " with value ").append(keyValueEntry.getValue()).append("\n"); + } + else { + Value value = data.get(keyValueEntry.getKey()); + if (!Comparing.equal(keyValueEntry.getValue(), value)) { + moreInfo.append("Previous data has different value for key:").append(keyValueEntry.getKey()).append( ", new value ").append(keyValueEntry.getValue()).append( ", oldValue:").append(value).append("\n"); + } + } + } + + for(Map.Entry keyValueEntry:data.entrySet()) { + if (!contentData.containsKey(keyValueEntry.getKey())) { + moreInfo.append("New data doesn't contain:").append(keyValueEntry.getKey()).append( " with value ").append(keyValueEntry.getValue()).append("\n"); + } + else { + Value value = contentData.get(keyValueEntry.getKey()); + if (!Comparing.equal(keyValueEntry.getValue(), value)) { + moreInfo.append("New data has different value for key:").append(keyValueEntry.getKey()).append( " new value ").append(value).append( ", oldValue:").append(keyValueEntry.getValue()).append("\n"); + } + } + } + return moreInfo; + } + private Map deserializeSavedPersistentData(ByteSequence bytes) throws IOException { DataInputStream stream = new DataInputStream(new UnsyncByteArrayInputStream(bytes.getBytes(), bytes.getOffset(), bytes.getLength())); int pairs = DataInputOutputUtil.readINT(stream); diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java index d4ac053e994e..fddd07785540 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java @@ -50,6 +50,8 @@ public interface IdeActions { @NonNls String ACTION_EDITOR_COMPLETE_STATEMENT = "EditorCompleteStatement"; @NonNls String ACTION_EDITOR_USE_SOFT_WRAPS = "EditorToggleUseSoftWraps"; @NonNls String ACTION_EDITOR_ADD_OR_REMOVE_CARET= "EditorAddOrRemoveCaret"; + @NonNls String ACTION_EDITOR_CLONE_CARET_BELOW= "EditorCloneCaretBelow"; + @NonNls String ACTION_EDITOR_CLONE_CARET_ABOVE= "EditorCloneCaretAbove"; @NonNls String ACTION_EDITOR_NEXT_TEMPLATE_VARIABLE = "NextTemplateVariable"; @NonNls String ACTION_EDITOR_PREVIOUS_TEMPLATE_VARIABLE = "PreviousTemplateVariable"; diff --git a/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java b/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java index 634144817fa7..e98bb05aba99 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java +++ b/platform/platform-api/src/com/intellij/openapi/options/SearchableConfigurable.java @@ -36,41 +36,49 @@ public interface SearchableConfigurable extends Configurable { boolean hasOwnContent(); boolean isVisible(); - abstract class Abstract implements Parent { private Configurable[] myKids; + @Override public JComponent createComponent() { return null; } + @Override public boolean hasOwnContent() { return false; } + @Override public boolean isModified() { return false; } + @Override public void apply() throws ConfigurationException { } + @Override public void reset() { } + @Override public void disposeUIResources() { myKids = null; } + @Override public Runnable enableSearch(final String option) { return null; } + @Override public boolean isVisible() { return true; } + @Override public final Configurable[] getConfigurables() { if (myKids != null) return myKids; myKids = buildConfigurables(); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java b/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java index 6f38d9a96356..101444a9d649 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/FixedSizeButton.java @@ -87,7 +87,7 @@ public class FixedSizeButton extends JButton { public Dimension getPreferredSize() { if (myComponent != null) { int size = myComponent.getPreferredSize().height; - if (myComponent instanceof ComboBox && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula())) { + if (myComponent instanceof JComboBox && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula())) { size -= 2; // decrement to match JTextField's preferred height } return new Dimension(size, size); @@ -120,9 +120,7 @@ public class FixedSizeButton extends JButton { public void setBounds(Rectangle r) { if (r.width != r.height) { int size = Math.min(r.width, r.height); - r = new Rectangle(r); - r.width = size; - r.height = size; + r = new Rectangle(r.x, r.y, size, size); } super.setBounds(r); } 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 faa26e2415b8..62864d01b91a 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java @@ -26,6 +26,7 @@ import com.intellij.ui.UIBundle; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -56,9 +57,9 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { private final Divider myFirstDivider; private final Divider myLastDivider; - private JComponent myFirstComponent; - private JComponent myInnerComponent; - private JComponent myLastComponent; + @Nullable private JComponent myFirstComponent; + @Nullable private JComponent myInnerComponent; + @Nullable private JComponent myLastComponent; private int myFirstSize = 10; private int myLastSize = 10; @@ -303,6 +304,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { repaint(); } + @Nullable public JComponent getFirstComponent() { return myFirstComponent; } @@ -312,7 +314,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { * repaint the splitter. If there is already * */ - public void setFirstComponent(JComponent component) { + public void setFirstComponent(@Nullable JComponent component) { if (myFirstComponent != component) { if (myFirstComponent != null) { remove(myFirstComponent); @@ -325,6 +327,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { } } + @Nullable public JComponent getLastComponent() { return myLastComponent; } @@ -335,7 +338,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { * repaint the splitter. * */ - public void setLastComponent(JComponent component) { + public void setLastComponent(@Nullable JComponent component) { if (myLastComponent != component) { if (myLastComponent != null) { remove(myLastComponent); @@ -348,7 +351,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { } } - + @Nullable public JComponent getInnerComponent() { return myInnerComponent; } @@ -359,7 +362,7 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { * repaint the splitter. * */ - public void setInnerComponent(JComponent component) { + public void setInnerComponent(@Nullable JComponent component) { if (myInnerComponent != component) { if (myInnerComponent != null) { remove(myInnerComponent); diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java index 1651757935c9..76bacb9cb452 100644 --- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java +++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java @@ -130,7 +130,7 @@ public abstract class GroupedElementsRenderer { public abstract static class List extends GroupedElementsRenderer { @Override - protected final void layout() { + protected void layout() { myRendererComponent.add(mySeparatorComponent, BorderLayout.NORTH); myRendererComponent.add(myComponent, BorderLayout.CENTER); } diff --git a/platform/platform-impl/src/com/intellij/jps/impl/JpsIdePluginManagerImpl.java b/platform/platform-impl/src/com/intellij/jps/impl/JpsIdePluginManagerImpl.java index 72e7b8a4973e..2d51053846fa 100644 --- a/platform/platform-impl/src/com/intellij/jps/impl/JpsIdePluginManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/jps/impl/JpsIdePluginManagerImpl.java @@ -37,15 +37,23 @@ public class JpsIdePluginManagerImpl extends JpsPluginManager { public JpsIdePluginManagerImpl() { ExtensionsArea rootArea = Extensions.getRootArea(); - //todo[nik] introduce more generic platform extension for JPS plugins instead + rootArea.getExtensionPoint(JpsPluginBean.EP_NAME).addExtensionPointListener(new ExtensionPointListener() { + @Override + public void extensionAdded(@NotNull JpsPluginBean extension, @Nullable PluginDescriptor pluginDescriptor) { + ContainerUtil.addIfNotNull(pluginDescriptor, myExternalBuildPlugins); + } + + @Override + public void extensionRemoved(@NotNull JpsPluginBean extension, @Nullable PluginDescriptor pluginDescriptor) { + } + }); if (rootArea.hasExtensionPoint("com.intellij.compileServer.plugin")) { ExtensionPoint extensionPoint = rootArea.getExtensionPoint("com.intellij.compileServer.plugin"); + //noinspection unchecked extensionPoint.addExtensionPointListener(new ExtensionPointListener() { @Override public void extensionAdded(@NotNull Object extension, @Nullable PluginDescriptor pluginDescriptor) { - if (pluginDescriptor != null) { - myExternalBuildPlugins.add(pluginDescriptor); - } + ContainerUtil.addIfNotNull(pluginDescriptor, myExternalBuildPlugins); } @Override diff --git a/platform/platform-impl/src/com/intellij/jps/impl/JpsPluginBean.java b/platform/platform-impl/src/com/intellij/jps/impl/JpsPluginBean.java new file mode 100644 index 000000000000..4979dd78cfe6 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/jps/impl/JpsPluginBean.java @@ -0,0 +1,26 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.jps.impl; + +import com.intellij.openapi.extensions.AbstractExtensionPointBean; +import com.intellij.openapi.extensions.ExtensionPointName; + +/** + * @author nik + */ +public class JpsPluginBean extends AbstractExtensionPointBean { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.jps.plugin"); +} diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java index 98498df8ecdc..9a566e9915ef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java @@ -634,7 +634,9 @@ public final class IdeKeyEventDispatcher implements Disposable { processor.onUpdatePassed(e, action, actionEvent); - ((DataManagerImpl.MyDataContext)myContext.getDataContext()).setEventCount(IdeEventQueue.getInstance().getEventCount(), this); + if (myContext.getDataContext() instanceof DataManagerImpl.MyDataContext) { // this is not true for test data contexts + ((DataManagerImpl.MyDataContext)myContext.getDataContext()).setEventCount(IdeEventQueue.getInstance().getEventCount(), this); + } actionManager.fireBeforeActionPerformed(action, actionEvent.getDataContext(), actionEvent); Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(actionEvent.getDataContext()); if (component != null && !component.isShowing()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java index 4c093211cfd6..7b4f5a0371ba 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/KeymapManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 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. @@ -15,6 +15,7 @@ */ package com.intellij.openapi.keymap.impl; +import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; @@ -27,6 +28,7 @@ import com.intellij.openapi.options.SchemesManager; import com.intellij.openapi.options.SchemesManagerFactory; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.registry.Registry; import com.intellij.util.containers.ContainerUtil; import org.jdom.Document; import org.jdom.Element; @@ -35,6 +37,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.event.KeyEvent; import java.io.File; import java.io.IOException; import java.util.*; @@ -92,6 +95,14 @@ public class KeymapManagerImpl extends KeymapManagerEx implements PersistentStat } } load(); + + if (Registry.is("editor.add.carets.on.double.control.arrows")) { + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_CLONE_CARET_ABOVE, KeyEvent.VK_CONTROL, KeyEvent.VK_UP); + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_CLONE_CARET_BELOW, KeyEvent.VK_CONTROL, KeyEvent.VK_DOWN); + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_LEFT, KeyEvent.VK_CONTROL, KeyEvent.VK_LEFT); + ModifierKeyDoubleClickHandler.getInstance().registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT, KeyEvent.VK_CONTROL, KeyEvent.VK_RIGHT); + } + ourKeymapManagerInitialized = true; } diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java new file mode 100644 index 000000000000..28536453b713 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ModifierKeyDoubleClickHandler.java @@ -0,0 +1,210 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.keymap.impl; + +import com.intellij.ide.DataManager; +import com.intellij.ide.IdeEventQueue; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.util.Clock; +import com.intellij.openapi.util.Couple; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.util.containers.ConcurrentHashMap; +import gnu.trove.TIntIntHashMap; +import gnu.trove.TIntIntProcedure; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Support for keyboard shortcuts like Control-double-click or Control-double-click+A + */ +public class ModifierKeyDoubleClickHandler { + private static final ModifierKeyDoubleClickHandler INSTANCE = new ModifierKeyDoubleClickHandler(); + + private final ConcurrentMap myDispatchers = new ConcurrentHashMap(); + + private ModifierKeyDoubleClickHandler() { } + + public static ModifierKeyDoubleClickHandler getInstance() { + return INSTANCE; + } + + /** + * @param actionId Id of action to be triggered on modifier+modifier[+actionKey] + * @param modifierKeyCode keyCode for modifier, e.g. KeyEvent.VK_SHIFT + * @param actionKeyCode keyCode for actionKey, or -1 if action should be triggered on bare modifier double click + */ + public void registerAction(@NotNull String actionId, + int modifierKeyCode, + int actionKeyCode) { + final MyDispatcher dispatcher = new MyDispatcher(actionId, modifierKeyCode, actionKeyCode); + IdeEventQueue.EventDispatcher oldDispatcher = myDispatchers.put(actionId, dispatcher); + IdeEventQueue.getInstance().addDispatcher(dispatcher, null); + if (oldDispatcher != null) { + IdeEventQueue.getInstance().removeDispatcher(oldDispatcher); + } + } + + public void unregisterAction(@NotNull String actionId) { + IdeEventQueue.EventDispatcher oldDispatcher = myDispatchers.remove(actionId); + if (oldDispatcher != null) { + IdeEventQueue.getInstance().removeDispatcher(oldDispatcher); + } + } + + private static class MyDispatcher implements IdeEventQueue.EventDispatcher { + private static final TIntIntHashMap KEY_CODE_TO_MODIFIER_MAP = new TIntIntHashMap(); + static { + KEY_CODE_TO_MODIFIER_MAP.put(KeyEvent.VK_ALT, InputEvent.ALT_MASK); + KEY_CODE_TO_MODIFIER_MAP.put(KeyEvent.VK_CONTROL, InputEvent.CTRL_MASK); + KEY_CODE_TO_MODIFIER_MAP.put(KeyEvent.VK_META, InputEvent.META_MASK); + KEY_CODE_TO_MODIFIER_MAP.put(KeyEvent.VK_SHIFT, InputEvent.SHIFT_MASK); + } + + private final String myActionId; + private final int myModifierKeyCode; + private final int myActionKeyCode; + + private final Couple ourPressed = Couple.of(new AtomicBoolean(false), new AtomicBoolean(false)); + private final Couple ourReleased = Couple.of(new AtomicBoolean(false), new AtomicBoolean(false)); + private final AtomicBoolean ourOtherKeyWasPressed = new AtomicBoolean(false); + private final AtomicLong ourLastTimePressed = new AtomicLong(0); + + public MyDispatcher(@NotNull String actionId, int modifierKeyCode, int actionKeyCode) { + myActionId = actionId; + myModifierKeyCode = modifierKeyCode; + myActionKeyCode = actionKeyCode; + } + + @Override + public boolean dispatch(AWTEvent event) { + if (event instanceof KeyEvent) { + final KeyEvent keyEvent = (KeyEvent)event; + final int keyCode = keyEvent.getKeyCode(); + + if (keyCode == myModifierKeyCode) { + if (hasOtherModifiers(keyEvent)) { + resetState(); + return false; + } + if (ourOtherKeyWasPressed.get() && Clock.getTime() - ourLastTimePressed.get() < 500) { + resetState(); + return false; + } + ourOtherKeyWasPressed.set(false); + if (ourPressed.first.get() && Clock.getTime() - ourLastTimePressed.get() > 500) { + resetState(); + } + handleModifier((KeyEvent)event); + return false; + } else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get() && myActionKeyCode != -1) { + if (keyCode == myActionKeyCode) { + if (event.getID() == KeyEvent.KEY_RELEASED) { + run(keyEvent); + } + return true; + } + return false; + } else { + ourLastTimePressed.set(Clock.getTime()); + ourOtherKeyWasPressed.set(true); + if (keyCode == KeyEvent.VK_ESCAPE || keyCode == KeyEvent.VK_TAB) { + ourLastTimePressed.set(0); + } + } + resetState(); + } + return false; + } + + private boolean hasOtherModifiers(KeyEvent keyEvent) { + final int modifiers = keyEvent.getModifiers(); + return !KEY_CODE_TO_MODIFIER_MAP.forEachEntry(new TIntIntProcedure() { + @Override + public boolean execute(int keyCode, int modifierMask) { + return keyCode == myModifierKeyCode || (modifiers & modifierMask) == 0; + } + }); + } + + private void handleModifier(KeyEvent event) { + if (ourPressed.first.get() && Clock.getTime() - ourLastTimePressed.get() > 300) { + resetState(); + return; + } + + if (event.getID() == KeyEvent.KEY_PRESSED) { + if (!ourPressed.first.get()) { + resetState(); + ourPressed.first.set(true); + ourLastTimePressed.set(Clock.getTime()); + return; + } else { + if (ourPressed.first.get() && ourReleased.first.get()) { + ourPressed.second.set(true); + ourLastTimePressed.set(Clock.getTime()); + return; + } + } + } else if (event.getID() == KeyEvent.KEY_RELEASED) { + if (ourPressed.first.get() && !ourReleased.first.get()) { + ourReleased.first.set(true); + ourLastTimePressed.set(Clock.getTime()); + return; + } else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get()) { + resetState(); + if (myActionKeyCode == -1 && !isActionBound()) { + run(event); + } + return; + } + } + resetState(); + } + + private void resetState() { + ourPressed.first.set(false); + ourPressed.second.set(false); + ourReleased.first.set(false); + ourReleased.second.set(false); + } + + private void run(KeyEvent event) { + final ActionManager actionManager = ActionManager.getInstance(); + final AnAction action = actionManager.getAction(myActionId); + final AnActionEvent anActionEvent = new AnActionEvent(event, + DataManager.getInstance().getDataContext(IdeFocusManager.findInstance().getFocusOwner()), + ActionPlaces.MAIN_MENU, + action.getTemplatePresentation(), + actionManager, + 0); + action.actionPerformed(anActionEvent); + } + + private boolean isActionBound() { + return KeymapManager.getInstance().getActiveKeymap().getShortcuts(myActionId).length > 0; + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoPanel.form b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoPanel.form index 167e5ef8ab00..0e86badb08c5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoPanel.form +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoPanel.form @@ -20,7 +20,7 @@ - + @@ -41,12 +41,6 @@ - - - - - - diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index 6bfc56df4399..f25093c6dd8d 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -763,7 +763,27 @@ public class AbstractPopup implements JBPopup { RootPaneContainer root = (RootPaneContainer)popupOwner; popupOwner = root.getRootPane(); } + if (LOG.isDebugEnabled()) { + LOG.debug("expected preferred size: " + myContent.getPreferredSize()); + } myPopup = factory.getPopup(popupOwner, myContent, targetBounds.x, targetBounds.y, this); + if (LOG.isDebugEnabled()) { + LOG.debug(" actual preferred size: " + myContent.getPreferredSize()); + } + if ((targetBounds.width != myContent.getWidth()) || (targetBounds.height != myContent.getHeight())) { + // JDK uses cached heavyweight popup that is not initialized properly + LOG.debug("the expected size is not equal to the actual size"); + Window popup = myPopup.getWindow(); + if (popup != null) { + popup.setSize(targetBounds.width, targetBounds.height); + if (myContent.getParent().getComponentCount() != 1) { + LOG.debug("unexpected count of components in heavy-weight popup"); + } + } + else { + LOG.debug("cannot fix size for non-heavy-weight popup"); + } + } if (myResizable) { final JRootPane root = myContent.getRootPane(); @@ -805,11 +825,7 @@ public class AbstractPopup implements JBPopup { listener.beforeShown(new LightweightWindowEvent(this)); } - // can be improved by moving in myPopup code - myPopup.getWindow().pack(); - myPopup.setRequestFocus(myRequestFocus); - LOG.debug("popup window size: " + myPopup.getWindow().getSize()); myPopup.show(); final Window window = SwingUtilities.getWindowAncestor(myContent); diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties index cdfe93846513..dd88b8304e0a 100644 --- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties +++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties @@ -1,6 +1,8 @@ xdebugger.colors.page.name=Debugger debugger.configurable.display.name=Debugger +debugger.dataViews.display.name=Data Views +debugger.stepping.display.name=Stepping xdebugger.default.content.title=Debug xdebugger.debugger.tab.title=Debugger @@ -111,4 +113,8 @@ scope.catch = Catch scope.class = Class scope.instance = Instance scope.library = Library -scope.unknown = Unknown \ No newline at end of file +scope.unknown = Unknown + +setting.value.tooltip.delay.label=&Value tooltip delay (ms): +setting.enable.auto.expressions.label=Enable auto expressions in Variables view +setting.sort.alphabetically.label=Sort a&lphabetically \ No newline at end of file diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index ab422ac82cba..0f430e0fee58 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -121,6 +121,8 @@ editor.smarterSelectionQuoting=true editor.skip.copy.and.cut.for.empty.selection=false editor.distraction.free.mode=false +editor.add.carets.on.double.control.arrows=true + ide.showIndexRebuildMessage=false ide.tabbedPane.bufferedPaint=true diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 61ee24ebe543..e8a45edbf138 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -12,6 +12,9 @@ + + diff --git a/platform/platform-resources/src/META-INF/xdebugger.xml b/platform/platform-resources/src/META-INF/xdebugger.xml index 6ec43c98f98a..68111b8eb7b2 100644 --- a/platform/platform-resources/src/META-INF/xdebugger.xml +++ b/platform/platform-resources/src/META-INF/xdebugger.xml @@ -15,7 +15,7 @@ - getSourceRootType(@NotNull DirectoryInfo info); - public abstract boolean isProjectExcludeRoot(@NotNull VirtualFile dir); - @NotNull public abstract Query getDirectoriesByPackageName(@NotNull String packageName, boolean includeLibrarySources); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java index 213f3e716c23..87448a584a23 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfo.java @@ -18,251 +18,59 @@ package com.intellij.openapi.roots.impl; import com.intellij.openapi.module.Module; import com.intellij.openapi.roots.OrderEntry; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.RootPolicy; -import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.BitUtil; -import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; import java.util.List; public abstract class DirectoryInfo { - public static final int MAX_ROOT_TYPE_ID = (1 << (Byte.SIZE - 3)) - 1; - private final Module module; // module to which content it belongs or null - private final VirtualFile libraryClassRoot; // class root in library - private final VirtualFile contentRoot; - private final VirtualFile sourceRoot; - - private static final byte MODULE_SOURCE_FLAG = 1; // set if files in this directory belongs to sources of the module (if field 'module' is not null) - private static final byte LIBRARY_SOURCE_FLAG = 2; // set if it's a directory with sources of some library - private static final byte EXCLUDED_FLAG = 4; // set if it's a directory under 'excluded' folder of a module - private final byte rootTypeData;//three least significant bits are used for MODULE_SOURCE_FLAG, LIBRARY_SOURCE_FLAG and EXCLUDED_FLAG, the remaining bits store module root type id (source/tests/resources/...) - - DirectoryInfo(Module module, - VirtualFile contentRoot, - VirtualFile sourceRoot, - VirtualFile libraryClassRoot, - byte rootTypeData) { - this.module = module; - this.libraryClassRoot = libraryClassRoot; - this.contentRoot = contentRoot; - this.sourceRoot = sourceRoot; - this.rootTypeData = rootTypeData; - } - /** * @return {@code true} if located under project content or library roots and not excluded or ignored */ - public boolean isInProject() { - return !isExcluded(); - } + public abstract boolean isInProject(); /** * @return {@code true} if located under ignored directory */ - public boolean isIgnored() { - return false; - } + public abstract boolean isIgnored(); - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + /** + * @return {@code true} if located project content, output or library root but excluded from the project + */ + public abstract boolean isExcluded(); - DirectoryInfo info = (DirectoryInfo)o; + public abstract boolean isInModuleSource(); - return rootTypeData == info.rootTypeData && - Comparing.equal(contentRoot, info.contentRoot) && - Comparing.equal(libraryClassRoot, info.libraryClassRoot) && - Comparing.equal(module, info.module) && - Arrays.equals(getOrderEntries(), info.getOrderEntries()) && - Comparing.equal(sourceRoot, info.sourceRoot); - } - - @Override - public int hashCode() { - int result = module != null ? module.hashCode() : 0; - result = 31 * result + (libraryClassRoot != null ? libraryClassRoot.hashCode() : 0); - result = 31 * result + (contentRoot != null ? contentRoot.hashCode() : 0); - result = 31 * result + (sourceRoot != null ? sourceRoot.hashCode() : 0); - result = 31 * result + (int)rootTypeData; - return result; - } - - @SuppressWarnings({"HardCodedStringLiteral"}) - public String toString() { - return "DirectoryInfo{" + - "module=" + getModule() + - ", isInModuleSource=" + isInModuleSource() + - ", rootTypeId=" + getSourceRootTypeId() + - ", isInLibrarySource=" + isInLibrarySource() + - ", isExcludedFromModule=" + isExcluded() + - ", libraryClassRoot=" + getLibraryClassRoot() + - ", contentRoot=" + getContentRoot() + - ", sourceRoot=" + getSourceRoot() + - ", orderEntries=" + Arrays.toString(getOrderEntries()) + - "}"; - } - - @NotNull - public abstract OrderEntry[] getOrderEntries(); + public abstract boolean isInLibrarySource(); @Nullable - OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) { - OrderEntry[] entries = getOrderEntries(); - if (entries.length < 10) { - for (OrderEntry entry : entries) { - if (entry.getOwnerModule() == ownerModule) return entry; - } - return null; - } - int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE); - return index < 0 ? null : entries[index]; - } + public abstract VirtualFile getSourceRoot(); - @NotNull - List findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) { - OrderEntry[] entries = getOrderEntries(); - if (entries.length == 1) { - OrderEntry entry = entries[0]; - return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.emptyList(); - } - int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE); - if (index < 0) { - return Collections.emptyList(); - } - int firstIndex = index; - while (firstIndex-1 >= 0 && entries[firstIndex-1].getOwnerModule() == ownerModule) { - firstIndex--; - } - int lastIndex = index+1; - while (lastIndex < entries.length && entries[lastIndex].getOwnerModule() == ownerModule) { - lastIndex++; - } - - OrderEntry[] subArray = new OrderEntry[lastIndex - firstIndex]; - System.arraycopy(entries, firstIndex, subArray, 0, lastIndex - firstIndex); - - return Arrays.asList(subArray); - } - - @NotNull - private static OrderEntry createFakeOrderEntry(@NotNull final Module ownerModule) { - return new OrderEntry() { - @NotNull - @Override - public VirtualFile[] getFiles(OrderRootType type) { - throw new IncorrectOperationException(); - } - - @NotNull - @Override - public String[] getUrls(OrderRootType rootType) { - throw new IncorrectOperationException(); - } - - @NotNull - @Override - public String getPresentableName() { - throw new IncorrectOperationException(); - } - - @Override - public boolean isValid() { - throw new IncorrectOperationException(); - } - - @NotNull - @Override - public Module getOwnerModule() { - return ownerModule; - } - - @Override - public R accept(RootPolicy policy, @Nullable R initialValue) { - throw new IncorrectOperationException(); - } - - @Override - public int compareTo(@NotNull OrderEntry o) { - throw new IncorrectOperationException(); - } - - @Override - public boolean isSynthetic() { - throw new IncorrectOperationException(); - } - }; - } - - public static final Comparator BY_OWNER_MODULE = new Comparator() { - @Override - public int compare(OrderEntry o1, OrderEntry o2) { - String name1 = o1.getOwnerModule().getName(); - String name2 = o2.getOwnerModule().getName(); - return name1.compareTo(name2); - } - }; - - @Nullable - public VirtualFile getSourceRoot() { - return sourceRoot; - } - - public VirtualFile getLibraryClassRoot() { - return libraryClassRoot; - } + public abstract int getSourceRootTypeId(); public boolean hasLibraryClassRoot() { return getLibraryClassRoot() != null; } + public abstract VirtualFile getLibraryClassRoot(); + @Nullable - public VirtualFile getContentRoot() { - return contentRoot; - } + public abstract VirtualFile getContentRoot(); - public boolean isInModuleSource() { - return BitUtil.isSet(rootTypeData, MODULE_SOURCE_FLAG); - } + @Nullable + public abstract Module getModule(); - public boolean isInLibrarySource() { - return BitUtil.isSet(rootTypeData, LIBRARY_SOURCE_FLAG); - } + @NotNull + public abstract OrderEntry[] getOrderEntries(); - public boolean isExcluded() { - return BitUtil.isSet(rootTypeData, EXCLUDED_FLAG); - } + @Nullable + abstract OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule); - public Module getModule() { - return module; - } + @NotNull + abstract List findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule); @TestOnly - void assertConsistency() { - OrderEntry[] entries = getOrderEntries(); - for (int i=1; i> 3; - } - - public static int createRootTypeData(boolean isInModuleSources, boolean isInLibrarySource, boolean isExcludedFromModule, - int moduleSourceRootTypeId) { - if (moduleSourceRootTypeId > MAX_ROOT_TYPE_ID) { - throw new IllegalArgumentException("Module source root type id " + moduleSourceRootTypeId + " exceeds the maximum allowable value (" + MAX_ROOT_TYPE_ID + ")"); - } - return (isInModuleSources ? MODULE_SOURCE_FLAG : 0) | (isInLibrarySource ? LIBRARY_SOURCE_FLAG : 0) | (isExcludedFromModule ? EXCLUDED_FLAG : 0) - | moduleSourceRootTypeId << 3; - } + abstract void assertConsistency(); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java new file mode 100644 index 000000000000..0be339bf3c5f --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/DirectoryInfoImpl.java @@ -0,0 +1,255 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.roots.impl; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * @author nik + */ +public abstract class DirectoryInfoImpl extends DirectoryInfo { + public static final Comparator BY_OWNER_MODULE = new Comparator() { + @Override + public int compare(OrderEntry o1, OrderEntry o2) { + String name1 = o1.getOwnerModule().getName(); + String name2 = o2.getOwnerModule().getName(); + return name1.compareTo(name2); + } + }; + public static final int MAX_ROOT_TYPE_ID = Byte.MAX_VALUE; + private final Module module; // module to which content it belongs or null + private final VirtualFile libraryClassRoot; // class root in library + private final VirtualFile contentRoot; + private final VirtualFile sourceRoot; + private final boolean myInModuleSource; + private final boolean myInLibrarySource; + private final boolean myExcluded; + private final byte mySourceRootTypeId; + + DirectoryInfoImpl(Module module, VirtualFile contentRoot, VirtualFile sourceRoot, VirtualFile libraryClassRoot, + boolean inModuleSource, boolean inLibrarySource, boolean isExcluded, int sourceRootTypeId) { + this.module = module; + this.libraryClassRoot = libraryClassRoot; + this.contentRoot = contentRoot; + this.sourceRoot = sourceRoot; + myInModuleSource = inModuleSource; + myInLibrarySource = inLibrarySource; + myExcluded = isExcluded; + if (sourceRootTypeId > MAX_ROOT_TYPE_ID) { + throw new IllegalArgumentException( + "Module source root type id " + sourceRootTypeId + " exceeds the maximum allowable value (" + MAX_ROOT_TYPE_ID + ")"); + } + mySourceRootTypeId = (byte)sourceRootTypeId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DirectoryInfoImpl info = (DirectoryInfoImpl)o; + + return mySourceRootTypeId == info.mySourceRootTypeId && + myInModuleSource == info.myInModuleSource && + myInLibrarySource == info.myInLibrarySource && + myExcluded == info.myExcluded && + Comparing.equal(contentRoot, info.contentRoot) && + Comparing.equal(libraryClassRoot, info.libraryClassRoot) && + Comparing.equal(module, info.module) && + Arrays.equals(getOrderEntries(), info.getOrderEntries()) && + Comparing.equal(sourceRoot, info.sourceRoot); + } + + @Override + public int hashCode() { + int result = module != null ? module.hashCode() : 0; + result = 31 * result + (libraryClassRoot != null ? libraryClassRoot.hashCode() : 0); + result = 31 * result + (contentRoot != null ? contentRoot.hashCode() : 0); + result = 31 * result + (sourceRoot != null ? sourceRoot.hashCode() : 0); + result = 31 * result + (myInModuleSource ? 1 : 0); + result = 31 * result + (myInLibrarySource ? 1 : 0); + result = 31 * result + (myExcluded ? 1 : 0); + result = 31 * result + (int)mySourceRootTypeId; + return result; + } + + @SuppressWarnings({"HardCodedStringLiteral"}) + public String toString() { + return "DirectoryInfo{" + + "module=" + getModule() + + ", isInModuleSource=" + isInModuleSource() + + ", rootTypeId=" + getSourceRootTypeId() + + ", isInLibrarySource=" + isInLibrarySource() + + ", isExcludedFromModule=" + isExcluded() + + ", libraryClassRoot=" + getLibraryClassRoot() + + ", contentRoot=" + getContentRoot() + + ", sourceRoot=" + getSourceRoot() + + ", orderEntries=" + Arrays.toString(getOrderEntries()) + + "}"; + } + + @NotNull + private static OrderEntry createFakeOrderEntry(@NotNull final Module ownerModule) { + return new OrderEntry() { + @NotNull + @Override + public VirtualFile[] getFiles(OrderRootType type) { + throw new IncorrectOperationException(); + } + + @NotNull + @Override + public String[] getUrls(OrderRootType rootType) { + throw new IncorrectOperationException(); + } + + @NotNull + @Override + public String getPresentableName() { + throw new IncorrectOperationException(); + } + + @Override + public boolean isValid() { + throw new IncorrectOperationException(); + } + + @NotNull + @Override + public Module getOwnerModule() { + return ownerModule; + } + + @Override + public R accept(RootPolicy policy, @Nullable R initialValue) { + throw new IncorrectOperationException(); + } + + @Override + public int compareTo(@NotNull OrderEntry o) { + throw new IncorrectOperationException(); + } + + @Override + public boolean isSynthetic() { + throw new IncorrectOperationException(); + } + }; + } + + @Nullable + OrderEntry findOrderEntryWithOwnerModule(@NotNull Module ownerModule) { + OrderEntry[] entries = getOrderEntries(); + if (entries.length < 10) { + for (OrderEntry entry : entries) { + if (entry.getOwnerModule() == ownerModule) return entry; + } + return null; + } + int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE); + return index < 0 ? null : entries[index]; + } + + @NotNull + List findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) { + OrderEntry[] entries = getOrderEntries(); + if (entries.length == 1) { + OrderEntry entry = entries[0]; + return entry.getOwnerModule() == ownerModule ? Arrays.asList(entries) : Collections.emptyList(); + } + int index = Arrays.binarySearch(entries, createFakeOrderEntry(ownerModule), BY_OWNER_MODULE); + if (index < 0) { + return Collections.emptyList(); + } + int firstIndex = index; + while (firstIndex-1 >= 0 && entries[firstIndex-1].getOwnerModule() == ownerModule) { + firstIndex--; + } + int lastIndex = index+1; + while (lastIndex < entries.length && entries[lastIndex].getOwnerModule() == ownerModule) { + lastIndex++; + } + + OrderEntry[] subArray = new OrderEntry[lastIndex - firstIndex]; + System.arraycopy(entries, firstIndex, subArray, 0, lastIndex - firstIndex); + + return Arrays.asList(subArray); + } + + public boolean isInProject() { + return !isExcluded(); + } + + public boolean isIgnored() { + return false; + } + + @Nullable + public VirtualFile getSourceRoot() { + return sourceRoot; + } + + public VirtualFile getLibraryClassRoot() { + return libraryClassRoot; + } + + @Nullable + public VirtualFile getContentRoot() { + return contentRoot; + } + + public boolean isInModuleSource() { + return myInModuleSource; + } + + public boolean isInLibrarySource() { + return myInLibrarySource; + } + + public boolean isExcluded() { + return myExcluded; + } + + public Module getModule() { + return module; + } + + @TestOnly + void assertConsistency() { + OrderEntry[] entries = getOrderEntries(); + for (int i=1; i findAllOrderEntriesWithOwnerModule(@NotNull Module ownerModule) { return Collections.emptyList(); } @@ -86,4 +83,45 @@ class NonProjectDirectoryInfo extends DirectoryInfo { public int hashCode() { return System.identityHashCode(this); } + + public boolean isIgnored() { + return false; + } + + @Nullable + public VirtualFile getSourceRoot() { + return null; + } + + public VirtualFile getLibraryClassRoot() { + return null; + } + + @Nullable + public VirtualFile getContentRoot() { + return null; + } + + public boolean isInModuleSource() { + return false; + } + + public boolean isInLibrarySource() { + return false; + } + + public boolean isExcluded() { + return false; + } + + public Module getModule() { + return null; + } + + void assertConsistency() { + } + + public int getSourceRootTypeId() { + return 0; + } } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java index a117e5fdac42..ca68cee3d061 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java @@ -224,7 +224,7 @@ public class RootIndex extends DirectoryIndex { } OrderEntry[] array = orderEntries.toArray(new OrderEntry[orderEntries.size()]); - Arrays.sort(array, DirectoryInfo.BY_OWNER_MODULE); + Arrays.sort(array, DirectoryInfoImpl.BY_OWNER_MODULE); return array; } @@ -246,7 +246,7 @@ public class RootIndex extends DirectoryIndex { } int id = myRootTypes.size(); - if (id > DirectoryInfo.MAX_ROOT_TYPE_ID) { + if (id > DirectoryInfoImpl.MAX_ROOT_TYPE_ID) { LOG.error("Too many different types of module source roots (" + id + ") registered: " + myRootTypes); } myRootTypes.add(rootType); @@ -314,11 +314,6 @@ public class RootIndex extends DirectoryIndex { return info; } - @Override - public boolean isProjectExcludeRoot(@NotNull final VirtualFile dir) { - return myProjectExcludedRoots.contains(dir); - } - @Override @NotNull public Query getDirectoriesByPackageName(@NotNull final String packageName, final boolean includeLibrarySources) { @@ -595,8 +590,8 @@ public class RootIndex extends DirectoryIndex { int typeId = moduleSourceRoot != null ? info.rootTypeId.get(moduleSourceRoot) : 0; Module module = parentModuleForExcluded != null ? parentModuleForExcluded : info.contentRootOf.get(moduleContentRoot); - byte rootTypeData = (byte)DirectoryInfo.createRootTypeData(inModuleSources, inLibrarySource, parentModuleForExcluded != null, typeId); - DirectoryInfo directoryInfo = new DirectoryInfo(module, moduleContentRoot, sourceRoot, libraryClassRoot, rootTypeData) { + DirectoryInfo directoryInfo = new DirectoryInfoImpl(module, moduleContentRoot, sourceRoot, libraryClassRoot, inModuleSources, inLibrarySource, + parentModuleForExcluded != null, typeId) { @NotNull @Override public OrderEntry[] getOrderEntries() { diff --git a/platform/remote-servers/impl/resources/resources/cloud.properties b/platform/remote-servers/impl/resources/resources/cloud.properties index 82c23fecf0a9..9e55748d88c0 100644 --- a/platform/remote-servers/impl/resources/resources/cloud.properties +++ b/platform/remote-servers/impl/resources/resources/cloud.properties @@ -9,3 +9,5 @@ run.configuration.name={0} - {1} choose.account.title=Choose {0} account\: git.cloud.app.detected={0} application detected at\: {1}.
You may setup deployment run configuration for the application choose.account.wizzard.title={0} deployment run configuration +cloud.support={0} Support +cloud.support.added=Finished adding {0} support\! diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.java index a614c4e642c9..7e68ca4c5b69 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/RemoteServerConfigurable.java @@ -7,6 +7,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.ui.NamedConfigurable; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.ServerConfiguration; import com.intellij.remoteServer.runtime.ServerConnection; @@ -79,7 +80,7 @@ public class RemoteServerConfigurable extends NamedConfigurable> if (result) { myUncheckedApply = false; - setConnectionStatus(""); + setConnectionStatus(false, false, ""); myConnectionTester = null; if (modified) { @@ -88,7 +89,7 @@ public class RemoteServerConfigurable extends NamedConfigurable> myInnerApplied = true; } catch (ConfigurationException e) { - setConnectionStatus(e.getMessage()); + setConnectionStatus(true, false, e.getMessage()); } } } @@ -97,7 +98,7 @@ public class RemoteServerConfigurable extends NamedConfigurable> @Override protected void run() { - setConnectionStatus("Connecting..."); + setConnectionStatus(false, false, "Connecting..."); myConnectionTester = new ConnectionTester(); myConnectionTester.testConnection(); @@ -105,19 +106,20 @@ public class RemoteServerConfigurable extends NamedConfigurable> }; } - private void setConnectionStatus(String text) { - setConnectionStatus(false, text); - } - - private void setConnectionStatus(boolean connected, String text) { + private void setConnectionStatus(boolean error, boolean connected, String text) { boolean changed = myConnected != connected; myConnected = connected; - myConnectionStatusLabel.setText(UIUtil.toHtml(text)); + setConnectionStatusText(error, text); if (changed) { notifyDataLoader(); } } + protected void setConnectionStatusText(boolean error, String text) { + myConnectionStatusLabel.setText(UIUtil.toHtml(text)); + myConnectionStatusLabel.setVisible(StringUtil.isNotEmpty(text)); + } + public void setDataLoader(CloudDataLoader dataLoader) { myDataLoader = dataLoader; notifyDataLoader(); @@ -238,7 +240,7 @@ public class RemoteServerConfigurable extends NamedConfigurable> @Override public void run() { if (myConnectionTester == ConnectionTester.this) { - setConnectionStatus(connected, connected ? "Connection successful" : "Cannot connect: " + connection.getStatusText()); + setConnectionStatus(!connected, connected, connected ? "Connection successful" : "Cannot connect: " + connection.getStatusText()); } } }); diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfile.java b/platform/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfile.java index ff7b379a161f..e40683dce04e 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfile.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/StructuralSearchProfile.java @@ -237,7 +237,7 @@ public abstract class StructuralSearchProfile { final PsiElement currentElement = matchResult.getMatch(); if (buf.length() > 0) { - if (info.isParameterContext()) { + if (info.isArgumentContext()) { buf.append(','); } else { buf.append(' '); diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ParameterInfo.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ParameterInfo.java index 43ce859b17dd..3e232731bd88 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ParameterInfo.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ParameterInfo.java @@ -5,15 +5,14 @@ import com.intellij.psi.PsiElement; public final class ParameterInfo { private String name; private int startIndex; - private boolean parameterContext; + private boolean argumentContext; private boolean methodParameterContext; private boolean statementContext; - private boolean variableInitialContext; + private boolean variableInitializerContext; private int afterDelimiterPos; private boolean hasCommaBefore; private int beforeDelimiterPos; private boolean hasCommaAfter; - private boolean scopeParameterization; private boolean replacementVariable; private PsiElement myElement; @@ -33,12 +32,12 @@ public final class ParameterInfo { this.startIndex = startIndex; } - public boolean isParameterContext() { - return parameterContext; + public boolean isArgumentContext() { + return argumentContext; } - public void setParameterContext(boolean parameterContext) { - this.parameterContext = parameterContext; + public void setArgumentContext(boolean argumentContext) { + this.argumentContext = argumentContext; } public boolean isMethodParameterContext() { @@ -57,12 +56,12 @@ public final class ParameterInfo { this.statementContext = statementContext; } - public boolean isVariableInitialContext() { - return variableInitialContext; + public boolean isVariableInitializerContext() { + return variableInitializerContext; } - public void setVariableInitialContext(boolean variableInitialContext) { - this.variableInitialContext = variableInitialContext; + public void setVariableInitializerContext(boolean variableInitializerContext) { + this.variableInitializerContext = variableInitializerContext; } public int getAfterDelimiterPos() { @@ -97,14 +96,6 @@ public final class ParameterInfo { this.hasCommaAfter = hasCommaAfter; } - public boolean isScopeParameterization() { - return scopeParameterization; - } - - public void setScopeParameterization(boolean scopeParameterization) { - this.scopeParameterization = scopeParameterization; - } - public boolean isReplacementVariable() { return replacementVariable; } diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java index 81933d9c9a91..e72fd5555531 100644 --- a/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java +++ b/platform/structuralsearch/source/com/intellij/structuralsearch/plugin/replace/impl/ReplacementBuilder.java @@ -16,6 +16,8 @@ import com.intellij.structuralsearch.impl.matcher.PatternTreeContext; import com.intellij.structuralsearch.impl.matcher.predicates.ScriptSupport; import com.intellij.structuralsearch.plugin.replace.ReplaceOptions; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -27,10 +29,8 @@ import java.util.*; public final class ReplacementBuilder { private String replacement; private List parameterizations; - private HashMap matchMap; private final Map replacementVarsMap; private final ReplaceOptions options; - //private Map scopedParameterizations; ReplacementBuilder(final Project project,final ReplaceOptions options) { replacementVarsMap = new HashMap(); @@ -76,7 +76,7 @@ public final class ReplacementBuilder { info.setStatementContext(true); } else if (ch == ',' || ch == ')') { - info.setParameterContext(true); + info.setArgumentContext(true); info.setHasCommaAfter(ch == ','); } info.setAfterDelimiterPos(pos); @@ -136,7 +136,7 @@ public final class ReplacementBuilder { } final StringBuilder result = new StringBuilder(replacement); - matchMap = new HashMap(); + HashMap matchMap = new HashMap(); fill(match, matchMap); int offset = 0; @@ -160,7 +160,7 @@ public final class ReplacementBuilder { result.delete(info.getAfterDelimiterPos() + offset, info.getAfterDelimiterPos() + 1 + offset); --offset; } - else if (info.isVariableInitialContext()) { + else if (info.isVariableInitializerContext()) { //if (info.afterDelimiterPos > 0) { result.delete(info.getBeforeDelimiterPos() + offset, info.getAfterDelimiterPos() + offset - 1); offset -= (info.getAfterDelimiterPos() - info.getBeforeDelimiterPos() - 1); @@ -188,6 +188,7 @@ public final class ReplacementBuilder { return scriptSupport.evaluate((MatchResultImpl)match, null); } + @Nullable public ParameterInfo findParameterization(String name) { if (parameterizations==null) return null; @@ -210,7 +211,7 @@ public final class ReplacementBuilder { } } - public void addParametrization(ParameterInfo e) { + public void addParametrization(@NotNull ParameterInfo e) { assert parameterizations != null; parameterizations.add(e); } diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java index 18e5e8e1ea5e..da479a70f93c 100644 --- a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralSearchTest.java @@ -2288,14 +2288,19 @@ public class StructuralSearchTest extends StructuralSearchTestCase { "@MyBean2(\"\")\n" + "public class TestBean {}\n" + "@MyBean2(\"\")\n" + - "@MyBean(\"\")\n" + + "@MyBean(value=\"\")\n" + "public class TestBean2 {}\n" + - "public class TestBean3 {}\n"; + "public class TestBean3 {}\n" + + "@MyBean(\"a\")\n" + + "@MyBean2(\"a\")\n" + + "public class TestBean4"; String s2 = "@MyBean(\"\")\n" + "@MyBean2(\"\")\n" + "public class $a$ {}\n"; assertEquals("Simple find annotated class",2,findMatchesCount(s1,s2,false)); + assertEquals("Match value of anonymous name value pair 1", 1, findMatchesCount(s1, "@MyBean(\"a\") class $a$ {}")); + assertEquals("Match value of anonymous name value pair 2", 2, findMatchesCount(s1, "@MyBean(\"\") class $a$ {}")); String s3 = "@VisualBean(\"????????? ?????????? ? ??\")\n" + "public class TestBean\n" + diff --git a/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java b/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java index 884a11711992..43aa9b37b510 100644 --- a/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java +++ b/platform/util/src/com/intellij/openapi/ui/VerticalFlowLayout.java @@ -48,6 +48,10 @@ public class VerticalFlowLayout extends FlowLayout implements Serializable { this(alignment, 5, 5, fillHorizontally, fillVertically); } + public VerticalFlowLayout(int hGap, int vGap) { + this(TOP, hGap, vGap, true, false); + } + public VerticalFlowLayout(@VerticalFlowAlignment int alignment, int hGap, int vGap, boolean fillHorizontally, boolean fillVertically) { setAlignment(alignment); this.hGap = hGap; diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMap.java b/platform/util/src/com/intellij/util/io/PersistentHashMap.java index de43fbd11b1b..dde187d804b5 100644 --- a/platform/util/src/com/intellij/util/io/PersistentHashMap.java +++ b/platform/util/src/com/intellij/util/io/PersistentHashMap.java @@ -80,7 +80,7 @@ public class PersistentHashMap extends PersistentEnumeratorDelegate< private final boolean myCanReEnumerate; private int myLargeIndexWatermarkId; // starting with this id we store offset in adjacent file in long format private boolean myIntAddressForNewRecord; - private static final boolean doHardConsistencyChecks = true; + private static final boolean doHardConsistencyChecks = false; private volatile boolean myBusyReading; private static class AppendStream extends DataOutputStream { diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 0582694b358d..7ed8021bd94b 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -48,7 +48,9 @@ import javax.swing.plaf.basic.BasicComboBoxUI; import javax.swing.plaf.basic.BasicRadioButtonUI; import javax.swing.plaf.basic.ComboPopup; import javax.swing.text.DefaultEditorKit; +import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.JTextComponent; +import javax.swing.text.NumberFormatter; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.StyleSheet; import javax.swing.undo.UndoManager; @@ -70,6 +72,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; +import java.text.NumberFormat; import java.util.*; import java.util.List; import java.util.concurrent.BlockingQueue; @@ -2986,4 +2989,19 @@ public class UIUtil { public static Color getSidePanelColor() { return new JBColor(new Color(0xD2D6DD), new Color(60, 68, 71)); } + + /** + * It is your responsibility to set correct horizontal align (left in case of UI Designer) + */ + public static void configureNumericFormattedTextField(@NotNull JFormattedTextField textField) { + NumberFormat format = NumberFormat.getIntegerInstance(); + format.setParseIntegerOnly(true); + format.setGroupingUsed(false); + NumberFormatter numberFormatter = new NumberFormatter(format); + numberFormatter.setMinimum(0); + textField.setFormatterFactory(new DefaultFormatterFactory(numberFormatter)); + textField.setHorizontalAlignment(SwingConstants.TRAILING); + + textField.setColumns(4); + } } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerBundle.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerBundle.java index a9594ca27ba7..23a262c32654 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerBundle.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerBundle.java @@ -29,7 +29,6 @@ import java.util.ResourceBundle; * @author nik */ public class XDebuggerBundle { - public static String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, @NotNull Object... params) { return CommonBundle.message(getBundle(), key, params); } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java index 3065a2e05dba..098501af7489 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java @@ -26,6 +26,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.frame.XSuspendContext; import com.intellij.xdebugger.frame.XValue; import com.intellij.xdebugger.frame.XValueCallback; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -167,7 +168,7 @@ public abstract class XDebuggerEvaluator { * @return delay before showing value tooltip (in ms) */ public int getValuePopupDelay() { - return 700; + return XDebuggerSettingsManager.getInstance().getDataViewSettings().getValueLookupDelay(); } public interface XEvaluationCallback extends XValueCallback { diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java index e3b101d2cb9b..9546278edf87 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/settings/XDebuggerSettings.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. @@ -19,8 +19,9 @@ import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.options.Configurable; import com.intellij.xdebugger.XDebuggerUtil; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Implement this class to provide settings page for debugger. Settings page will be placed under 'Debugger' node in the 'Settings' dialog. @@ -33,6 +34,20 @@ import org.jetbrains.annotations.NonNls; * @author nik */ public abstract class XDebuggerSettings implements PersistentStateComponent { + public enum Category { + DATA_VIEWS(true), STEPPING(true); + + private final boolean separatePage; + + Category(boolean separatePage) { + this.separatePage = separatePage; + } + + public boolean isSeparatePage() { + return separatePage; + } + } + public static final ExtensionPointName EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.settings"); private final String myId; @@ -48,6 +63,11 @@ public abstract class XDebuggerSettings implements PersistentStateComponent> T getDebuggerSettings(Class aClass) { - return XDebuggerSettingsManager.getInstance().getSettings(aClass); + return XDebuggerSettingsManager.getInstanceImpl().getSettings(aClass); } @Override diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/UnmuteOnStopAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/UnmuteOnStopAction.java index 79cef654c089..e9f36996dda7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/UnmuteOnStopAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/UnmuteOnStopAction.java @@ -26,11 +26,11 @@ import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager; public class UnmuteOnStopAction extends ToggleAction implements DumbAware { @Override public boolean isSelected(AnActionEvent e) { - return XDebuggerSettingsManager.getInstance().getGeneralSettings().isUnmuteOnStop(); + return XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().isUnmuteOnStop(); } @Override public void setSelected(AnActionEvent e, boolean state) { - XDebuggerSettingsManager.getInstance().getGeneralSettings().setUnmuteOnStop(state); + XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().setUnmuteOnStop(state); } } \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java index 4dedaae5ae8e..2273ab698768 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java @@ -111,7 +111,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { } }); - EvaluationMode mode = XDebuggerSettingsManager.getInstance().getGeneralSettings().getEvaluationDialogMode(); + EvaluationMode mode = XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().getEvaluationDialogMode(); myIsCodeFragmentEvaluationSupported = evaluator.isCodeFragmentEvaluationSupported(); if (mode == EvaluationMode.CODE_FRAGMENT && !myIsCodeFragmentEvaluationSupported) { mode = EvaluationMode.EXPRESSION; @@ -185,7 +185,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { private void switchToMode(EvaluationMode mode, XExpression text) { if (myMode == mode) return; - XDebuggerSettingsManager.getInstance().getGeneralSettings().setEvaluationDialogMode(mode); + XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().setEvaluationDialogMode(mode); myMode = mode; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java index 1669e102f15f..bf3e0010e6cf 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java @@ -29,6 +29,7 @@ import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint; import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler; import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -107,6 +108,6 @@ public class XQuickEvaluateHandler extends QuickEvaluateHandler { return evaluator.getValuePopupDelay(); } } - return 700; + return XDebuggerSettingsManager.getInstance().getDataViewSettings().getValueLookupDelay(); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java new file mode 100644 index 000000000000..d140a74f35c8 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurable.java @@ -0,0 +1,53 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.impl.settings; + +import com.intellij.openapi.options.Configurable; +import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.settings.XDebuggerSettings; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +class DataViewsConfigurable extends SubCompositeConfigurable implements Configurable.NoScroll { + @NotNull + @Override + public String getId() { + return "debugger.dataViews"; + } + + @Nls + @Override + public String getDisplayName() { + return XDebuggerBundle.message("debugger.dataViews.display.name"); + } + + @Override + protected DataViewsConfigurableUi createRootUi() { + return new DataViewsConfigurableUi(); + } + + @NotNull + @Override + protected XDebuggerSettings.Category getCategory() { + return XDebuggerSettings.Category.DATA_VIEWS; + } + + @NotNull + @Override + protected XDebuggerDataViewSettings getSettings() { + return XDebuggerSettingsManager.getInstanceImpl().getDataViewSettings(); + } +} \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurableUi.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurableUi.form new file mode 100644 index 000000000000..a6e3f94f3bec --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurableUi.form @@ -0,0 +1,50 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurableUi.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurableUi.java new file mode 100644 index 000000000000..76645db3a3d3 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DataViewsConfigurableUi.java @@ -0,0 +1,61 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.impl.settings; + +import com.intellij.openapi.util.text.StringUtilRt; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +public class DataViewsConfigurableUi { + private JCheckBox enableAutoExpressionsCheckBox; + private JFormattedTextField valueTooltipDelayTextField; + private JPanel panel; + private JCheckBox sortAlphabeticallyCheckBox; + + public DataViewsConfigurableUi() { + UIUtil.configureNumericFormattedTextField(valueTooltipDelayTextField); + } + + private int getValueTooltipDelay() { + Object value = valueTooltipDelayTextField.getValue(); + return value instanceof Number ? ((Number)value).intValue() : StringUtilRt.parseInt((String)value, XDebuggerDataViewSettings.DEFAULT_VALUE_TOOLTIP_DELAY); + } + + @NotNull + public JComponent getComponent() { + return panel; + } + + public boolean isModified(@NotNull XDebuggerDataViewSettings settings) { + return getValueTooltipDelay() != settings.getValueLookupDelay() || + sortAlphabeticallyCheckBox.isSelected() != settings.isSortValues() || + enableAutoExpressionsCheckBox.isSelected() != settings.isAutoExpressions(); + } + + public void reset(@NotNull XDebuggerDataViewSettings settings) { + valueTooltipDelayTextField.setValue(settings.getValueLookupDelay()); + sortAlphabeticallyCheckBox.setSelected(settings.isSortValues()); + enableAutoExpressionsCheckBox.setSelected(settings.isAutoExpressions()); + } + + public void apply(@NotNull XDebuggerDataViewSettings settings) { + settings.setValueLookupDelay(getValueTooltipDelay()); + settings.setSortValues(sortAlphabeticallyCheckBox.isSelected()); + settings.setAutoExpressions(enableAutoExpressionsCheckBox.isSelected()); + } +} \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java index ae0b71eaa20f..59d72fd24a3d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurable.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,10 +20,12 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.impl.DebuggerSupport; +import com.intellij.xdebugger.settings.XDebuggerSettings; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.util.ArrayList; import java.util.List; /** @@ -31,26 +33,77 @@ import java.util.List; */ public class DebuggerConfigurable implements SearchableConfigurable.Parent { public static final String DISPLAY_NAME = XDebuggerBundle.message("debugger.configurable.display.name"); + + static final Configurable[] EMPTY_CONFIGURABLES = new Configurable[0]; + private Configurable myRootConfigurable; private Configurable[] myChildren; - public DebuggerConfigurable(Configurable rootConfigurable, List children) { - myRootConfigurable = rootConfigurable; - myChildren = children.toArray(new Configurable[children.size()]); - } - + @Override public String getDisplayName() { return DISPLAY_NAME; } + @Override public String getHelpTopic() { - return myRootConfigurable != null? myRootConfigurable.getHelpTopic() : null; + return myRootConfigurable != null ? myRootConfigurable.getHelpTopic() : null; } + @Override public Configurable[] getConfigurables() { - return myChildren; + compute(); + + if (myChildren.length == 0 && myRootConfigurable instanceof SearchableConfigurable.Parent) { + return ((Parent)myRootConfigurable).getConfigurables(); + } + else { + return myChildren; + } } + private void compute() { + if (myChildren != null) { + return; + } + + List providers = DebuggerConfigurableProvider.getSortedProviders(); + + List configurables = new ArrayList(); + configurables.add(new DataViewsConfigurable()); + + List steppingConfigurables = DebuggerConfigurableProvider.getConfigurables(XDebuggerSettings.Category.STEPPING, providers); + if (!steppingConfigurables.isEmpty()) { + configurables.add(new SteppingConfigurable(steppingConfigurables)); + } + + Configurable rootConfigurable = null; + for (DebuggerSettingsPanelProvider provider : providers) { + configurables.addAll(provider.getConfigurables()); + Configurable aRootConfigurable = provider.getRootConfigurable(); + if (aRootConfigurable != null) { + if (rootConfigurable != null) { + configurables.add(aRootConfigurable); + } + else { + rootConfigurable = aRootConfigurable; + } + } + } + + if (configurables.isEmpty() && rootConfigurable == null) { + myChildren = EMPTY_CONFIGURABLES; + } + else if (rootConfigurable == null && configurables.size() == 1) { + myRootConfigurable = configurables.get(0); + myChildren = EMPTY_CONFIGURABLES; + } + else { + myChildren = configurables.toArray(new Configurable[configurables.size()]); + myRootConfigurable = rootConfigurable; + } + } + + @Override public void apply() throws ConfigurationException { for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) { support.getSettingsPanelProvider().apply(); @@ -60,38 +113,48 @@ public class DebuggerConfigurable implements SearchableConfigurable.Parent { } } + @Override public boolean hasOwnContent() { + compute(); return myRootConfigurable != null; } + @Override public boolean isVisible() { return true; } + @Override public Runnable enableSearch(final String option) { return null; } + @Override public JComponent createComponent() { + compute(); return myRootConfigurable != null ? myRootConfigurable.createComponent() : null; } + @Override public boolean isModified() { return myRootConfigurable != null && myRootConfigurable.isModified(); } + @Override public void reset() { if (myRootConfigurable != null) { myRootConfigurable.reset(); } } + @Override public void disposeUIResources() { if (myRootConfigurable != null) { myRootConfigurable.disposeUIResources(); } } + @Override @NotNull @NonNls public String getId() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java index 49e2e4ac6fcd..f66bd6797be2 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerConfigurableProvider.java @@ -17,10 +17,13 @@ package com.intellij.xdebugger.impl.settings; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableProvider; -import com.intellij.util.PlatformUtils; +import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.impl.DebuggerSupport; +import com.intellij.xdebugger.settings.XDebuggerSettings; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -29,46 +32,55 @@ import java.util.List; * @author nik */ public class DebuggerConfigurableProvider extends ConfigurableProvider { + @NotNull + static List getSortedProviders() { + List providers = null; + for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) { + DebuggerSettingsPanelProvider provider = support.getSettingsPanelProvider(); + if (providers == null) { + providers = new SmartList(); + } + providers.add(provider); + } + + if (ContainerUtil.isEmpty(providers)) { + return Collections.emptyList(); + } + + if (providers.size() > 1) { + Collections.sort(providers, new Comparator() { + @Override + public int compare(DebuggerSettingsPanelProvider o1, DebuggerSettingsPanelProvider o2) { + return o2.getPriority() - o1.getPriority(); + } + }); + } + return providers; + } + @Override public Configurable createConfigurable() { - final List providers = new ArrayList(); - final DebuggerSupport[] supports = DebuggerSupport.getDebuggerSupports(); - for (DebuggerSupport support : supports) { - providers.add(support.getSettingsPanelProvider()); - } + return new DebuggerConfigurable(); + } - List configurables = new ArrayList(); - Collections.sort(providers, new Comparator() { - public int compare(final DebuggerSettingsPanelProvider o1, final DebuggerSettingsPanelProvider o2) { - return o2.getPriority() - o1.getPriority(); - } - }); + @NotNull + static List getConfigurables(@NotNull XDebuggerSettings.Category category) { + List providers = getSortedProviders(); + return providers.isEmpty() ? Collections.emptyList() : getConfigurables(category, providers); + } - Configurable rootConfigurable = null; + @NotNull + static List getConfigurables(@NotNull XDebuggerSettings.Category category, @NotNull List providers) { + List configurables = null; for (DebuggerSettingsPanelProvider provider : providers) { - configurables.addAll(provider.getConfigurables()); - final Configurable aRootConfigurable = provider.getRootConfigurable(); - if (aRootConfigurable != null) { - if (rootConfigurable != null) { - configurables.add(aRootConfigurable); - } - else { - rootConfigurable = aRootConfigurable; + Collection providerConfigurables = provider.getConfigurable(category); + if (!providerConfigurables.isEmpty()) { + if (configurables == null) { + configurables = new SmartList(); } + configurables.addAll(providerConfigurables); } } - if (configurables.isEmpty() && rootConfigurable == null) { - return null; - } - - //Perhaps we always should have a root node 'Debugger' with separate nodes for language-specific settings under it. - //However for AppCode there is only one language which is clearly associated with the product - //This code should removed when we extract the common debugger settings to the root node. - if (PlatformUtils.isCidr() && rootConfigurable == null && configurables.size() == 1) { - rootConfigurable = configurables.get(0); - configurables = Collections.emptyList(); - } - - return new DebuggerConfigurable(rootConfigurable, configurables); + return ContainerUtil.isEmpty(configurables) ? Collections.emptyList() : configurables; } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java index ba0bb43621e9..5dc9db98de3f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/DebuggerSettingsPanelProvider.java @@ -16,18 +16,25 @@ package com.intellij.xdebugger.impl.settings; import com.intellij.openapi.options.Configurable; +import com.intellij.xdebugger.settings.XDebuggerSettings; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; +import java.util.Collections; /** * @author nik */ public abstract class DebuggerSettingsPanelProvider { + public int getPriority() { + return 0; + } - public abstract int getPriority(); - - public abstract Collection getConfigurables(); + @NotNull + public Collection getConfigurables() { + return Collections.emptyList(); + } public void apply() { } @@ -36,4 +43,15 @@ public abstract class DebuggerSettingsPanelProvider { public Configurable getRootConfigurable() { return null; } + + @NotNull + public Collection getConfigurable(@NotNull XDebuggerSettings.Category category) { + return Collections.emptyList(); + } + + /** + * General settings of category were applied + */ + public void applied(@NotNull XDebuggerSettings.Category category) { + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java new file mode 100644 index 000000000000..eca20339a2d8 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SteppingConfigurable.java @@ -0,0 +1,54 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.impl.settings; + +import com.intellij.openapi.options.Configurable; +import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.settings.XDebuggerSettings; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +class SteppingConfigurable extends SubCompositeConfigurable implements Configurable.NoScroll { + public SteppingConfigurable(@NotNull List configurables) { + assert !configurables.isEmpty(); + children = configurables.toArray(new Configurable[configurables.size()]); + } + + @NotNull + @Override + public String getId() { + return "debugger.stepping"; + } + + @Nls + @Override + public String getDisplayName() { + return XDebuggerBundle.message("debugger.stepping.display.name"); + } + + @Override + protected DataViewsConfigurableUi createRootUi() { + return null; + } + + @NotNull + @Override + protected XDebuggerSettings.Category getCategory() { + return XDebuggerSettings.Category.STEPPING; + } +} \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java new file mode 100644 index 000000000000..a9c5ec6db4a6 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/SubCompositeConfigurable.java @@ -0,0 +1,178 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.impl.settings; + +import com.intellij.openapi.options.Configurable; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SearchableConfigurable; +import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.xdebugger.impl.DebuggerSupport; +import com.intellij.xdebugger.settings.XDebuggerSettings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.List; + +abstract class SubCompositeConfigurable implements SearchableConfigurable.Parent { + protected DataViewsConfigurableUi root; + protected Configurable[] children; + protected JComponent rootComponent; + + @Override + public boolean hasOwnContent() { + return getCategory() != XDebuggerSettings.Category.STEPPING; + } + + @Override + public boolean isVisible() { + return true; + } + + @Nullable + @Override + public Runnable enableSearch(String option) { + return null; + } + + @Nullable + @Override + public String getHelpTopic() { + getConfigurables(); + return children != null && children.length == 1 ? children[0].getHelpTopic() : null; + } + + @Override + public final void disposeUIResources() { + root = null; + rootComponent = null; + + if (isChildrenMerged()) { + for (Configurable child : children) { + child.reset(); + } + } + children = null; + } + + protected XDebuggerDataViewSettings getSettings() { + return null; + } + + @Nullable + protected abstract DataViewsConfigurableUi createRootUi(); + + @NotNull + protected abstract XDebuggerSettings.Category getCategory(); + + private boolean isChildrenMerged() { + return children != null && (!getCategory().isSeparatePage() || children.length == 1); + } + + @Override + public final Configurable[] getConfigurables() { + if (children == null) { + List configurables = DebuggerConfigurableProvider.getConfigurables(getCategory()); + children = configurables.toArray(new Configurable[configurables.size()]); + } + return isChildrenMerged() ? DebuggerConfigurable.EMPTY_CONFIGURABLES : children; + } + + @Nullable + @Override + public final JComponent createComponent() { + if (rootComponent == null) { + if (root == null) { + root = createRootUi(); + } + + getConfigurables(); + if (isChildrenMerged()) { + if (children.length == 0) { + rootComponent = root == null ? null : root.getComponent(); + } + else if (root == null && children.length == 1) { + rootComponent = children[0].createComponent(); + } + else { + JPanel panel = new JPanel(new VerticalFlowLayout(0, IdeBorderFactory.TITLED_BORDER_BOTTOM_INSET)); + if (root != null) { + panel.add(root.getComponent()); + } + for (Configurable child : children) { + JComponent component = child.createComponent(); + if (component != null) { + component.setBorder(IdeBorderFactory.createTitledBorder(child.getDisplayName(), false)); + panel.add(component); + } + } + rootComponent = panel; + } + } + else { + rootComponent = root == null ? null : root.getComponent(); + } + } + return rootComponent; + } + + @Override + public final void reset() { + if (root != null) { + root.reset(getSettings()); + } + + if (isChildrenMerged()) { + for (Configurable child : children) { + child.reset(); + } + } + } + + @Override + public final boolean isModified() { + if (root != null && root.isModified(getSettings())) { + return true; + } + else if (isChildrenMerged()) { + for (Configurable child : children) { + if (child.isModified()) { + return true; + } + } + } + return false; + } + + @Override + public final void apply() throws ConfigurationException { + if (root != null) { + root.apply(getSettings()); + for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) { + support.getSettingsPanelProvider().applied(getCategory()); + } + } + + if (isChildrenMerged()) { + for (Configurable child : children) { + if (child.isModified()) { + child.apply(); + } + } + } + } +} \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerDataViewSettings.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerDataViewSettings.java index bff7c531119d..3dd802430ecf 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerDataViewSettings.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerDataViewSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 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. @@ -16,15 +16,21 @@ package com.intellij.xdebugger.impl.settings; import com.intellij.util.xmlb.annotations.Tag; -import com.intellij.xdebugger.evaluation.EvaluationMode; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; /** * @author nik */ @Tag("data-views") -public class XDebuggerDataViewSettings { +public class XDebuggerDataViewSettings implements XDebuggerSettingsManager.DataViewSettings { + static final int DEFAULT_VALUE_TOOLTIP_DELAY = 700; + private boolean mySortValues; + private boolean autoExpressions = true; + private int valueLookupDelay = DEFAULT_VALUE_TOOLTIP_DELAY; + + @Override @Tag("sort-values") public boolean isSortValues() { return mySortValues; @@ -33,4 +39,22 @@ public class XDebuggerDataViewSettings { public void setSortValues(boolean sortValues) { mySortValues = sortValues; } + + @Override + public int getValueLookupDelay() { + return valueLookupDelay; + } + + public void setValueLookupDelay(int value) { + valueLookupDelay = value; + } + + @Override + public boolean isAutoExpressions() { + return autoExpressions; + } + + public void setAutoExpressions(boolean autoExpressions) { + this.autoExpressions = autoExpressions; + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsManager.java index ae2dcbc4cca1..8842639fce75 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsManager.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerSettingsManager.java @@ -26,12 +26,15 @@ import com.intellij.util.xmlb.annotations.Tag; import com.intellij.xdebugger.settings.XDebuggerSettings; import org.jdom.Element; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import java.util.*; /** * @author nik + * todo rename to XDebuggerSettingsManagerImpl */ +@SuppressWarnings("ClassNameSameAsAncestorName") @State( name = XDebuggerSettingsManager.COMPONENT_NAME, storages = { @@ -40,17 +43,18 @@ import java.util.*; ) } ) -public class XDebuggerSettingsManager implements PersistentStateComponent{ +public class XDebuggerSettingsManager extends com.intellij.xdebugger.settings.XDebuggerSettingsManager implements PersistentStateComponent{ @NonNls public static final String COMPONENT_NAME = "XDebuggerSettings"; private Map> mySettingsById; private Map, XDebuggerSettings> mySettingsByClass; private XDebuggerDataViewSettings myDataViewSettings = new XDebuggerDataViewSettings(); private XDebuggerGeneralSettings myGeneralSettings = new XDebuggerGeneralSettings(); - public static XDebuggerSettingsManager getInstance() { - return ServiceManager.getService(XDebuggerSettingsManager.class); + public static XDebuggerSettingsManager getInstanceImpl() { + return (XDebuggerSettingsManager)com.intellij.xdebugger.settings.XDebuggerSettingsManager.getInstance(); } + @Override public SettingsState getState() { SettingsState settingsState = new SettingsState(); settingsState.setDataViewSettings(myDataViewSettings); @@ -69,6 +73,8 @@ public class XDebuggerSettingsManager implements PersistentStateComponent getConfigurables() { - ArrayList list = new ArrayList(); - for (XDebuggerSettings settings : XDebuggerSettingsManager.getInstance().getSettingsList()) { - list.add(settings.createConfigurable()); + List list = new SmartList(); + for (XDebuggerSettings settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) { + ContainerUtil.addIfNotNull(list, settings.createConfigurable()); } return list; } + @NotNull + @Override + public Collection getConfigurable(@NotNull XDebuggerSettings.Category category) { + List list = null; + for (XDebuggerSettings settings : XDebuggerSettingsManager.getInstanceImpl().getSettingsList()) { + Configurable configurable = settings.createConfigurable(category); + if (configurable != null) { + if (list == null) { + list = new SmartList(); + } + list.add(configurable); + } + } + return ContainerUtil.isEmpty(list) ? Collections.emptyList() : list; + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/SortValuesToggleAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/SortValuesToggleAction.java index 00d803d68244..e399dbd96eba 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/SortValuesToggleAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/SortValuesToggleAction.java @@ -27,12 +27,12 @@ import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager; public class SortValuesToggleAction extends ToggleAction implements DumbAware { @Override public boolean isSelected(AnActionEvent e) { - return XDebuggerSettingsManager.getInstance().getDataViewSettings().isSortValues(); + return XDebuggerSettingsManager.getInstanceImpl().getDataViewSettings().isSortValues(); } @Override public void setSelected(AnActionEvent e, boolean state) { - XDebuggerSettingsManager.getInstance().getDataViewSettings().setSortValues(state); + XDebuggerSettingsManager.getInstanceImpl().getDataViewSettings().setSortValues(state); XDebuggerUtilImpl.rebuildAllSessionsViews(e.getProject()); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java index 38d2547831fe..b9f90fe86b2b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java @@ -21,9 +21,9 @@ import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.SortedList; import com.intellij.xdebugger.frame.*; -import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; +import com.intellij.xdebugger.settings.XDebuggerSettingsManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java index ff4b0d2f1a89..a4b7431d276f 100644 --- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java +++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XDebuggerSettingsTest.java @@ -36,11 +36,11 @@ public class XDebuggerSettingsTest extends PlatformLiteFixture { registerExtensionPoint(XDebuggerSettings.EXTENSION_POINT, XDebuggerSettings.class); registerExtension(XDebuggerSettings.EXTENSION_POINT, new MyDebuggerSettings()); getApplication().registerService(XDebuggerUtil.class, XDebuggerUtilImpl.class); - getApplication().registerService(XDebuggerSettingsManager.class, XDebuggerSettingsManager.class); + getApplication().registerService(com.intellij.xdebugger.settings.XDebuggerSettingsManager.class, XDebuggerSettingsManager.class); } public void testSerialize() throws Exception { - XDebuggerSettingsManager settingsManager = XDebuggerSettingsManager.getInstance(); + XDebuggerSettingsManager settingsManager = XDebuggerSettingsManager.getInstanceImpl(); MyDebuggerSettings settings = MyDebuggerSettings.getInstance(); assertNotNull(settings); diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java index bebf5a559d15..023b4bc9f949 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/numeric/PointlessArithmeticExpressionInspection.java @@ -105,7 +105,7 @@ public class PointlessArithmeticExpressionInspection fromTarget = (i == length - 1) ? polyadicExpression.getTokenBeforeOperand(operand) : operand; break; } - else if ((tokenType.equals(JavaTokenType.MINUS) || tokenType.equals(JavaTokenType.DIV)) && + else if ((tokenType.equals(JavaTokenType.MINUS) && i == 1 || tokenType.equals(JavaTokenType.DIV)) && EquivalenceChecker.expressionsAreEquivalent(previousOperand, operand)) { fromTarget = previousOperand; untilTarget = operand; @@ -229,9 +229,10 @@ public class PointlessArithmeticExpressionInspection private boolean subtractionExpressionIsPointless(PsiExpression[] expressions) { PsiExpression previousExpression = null; - for (PsiExpression expression : expressions) { + for (int i = 0; i < expressions.length; i++) { + PsiExpression expression = expressions[i]; if (previousExpression != null && - (isZero(expression) || EquivalenceChecker.expressionsAreEquivalent(previousExpression, expression))) { + (isZero(expression) || i == 1 && EquivalenceChecker.expressionsAreEquivalent(previousExpression, expression))) { return true; } previousExpression = expression; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java index 019805adcf17..4ba7a97033ad 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/numeric/pointless_arithmetic_expression/PointlessArithmeticExpression.java @@ -124,4 +124,5 @@ class Expanded {{ long g = 8L / 8L; long h = 9L * 0L; int a = 8 * 0 * 8 * ; // don't warn + int minus = 2 - 1 - 1; }} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java index 8ffc5eebfbe0..f26a41771228 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/types/ReplaceMethodRefWithLambdaIntention.java @@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -45,24 +46,38 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention { protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { final PsiMethodReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(element, PsiMethodReferenceExpression.class); LOG.assertTrue(referenceExpression != null); + final PsiElement resolve = referenceExpression.resolve(); + final boolean isReceiver = resolve instanceof PsiMethod && PsiMethodReferenceUtil.hasReceiver(referenceExpression, (PsiMethod)resolve); + final PsiParameter[] psiParameters = resolve instanceof PsiMethod ? ((PsiMethod)resolve).getParameterList().getParameters() : null; final PsiType functionalInterfaceType = referenceExpression.getFunctionalInterfaceType(); final PsiClassType.ClassResolveResult functionalInterfaceResolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType); final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType); + LOG.assertTrue(interfaceMethod != null); + final PsiSubstitutor psiSubstitutor = LambdaUtil.getSubstitutor(interfaceMethod, functionalInterfaceResolveResult); final StringBuilder buf = new StringBuilder("("); LOG.assertTrue(functionalInterfaceType != null); buf.append(functionalInterfaceType.getCanonicalText()).append(")("); - LOG.assertTrue(interfaceMethod != null); - final PsiParameter[] parameters = interfaceMethod.getParameterList().getParameters(); + final PsiParameterList parameterList = interfaceMethod.getParameterList(); + final PsiParameter[] parameters = parameterList.getParameters(); final Map map = new HashMap(); final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(element.getProject()); final String paramsString = StringUtil.join(parameters, new Function() { @Override public String fun(PsiParameter parameter) { - String parameterName = parameter.getName(); - if (parameterName != null) { - final String baseName = codeStyleManager.variableNameToPropertyName(parameterName, VariableKind.PARAMETER); - parameterName = codeStyleManager.suggestUniqueVariableName(baseName, referenceExpression, true); + final int parameterIndex = parameterList.getParameterIndex(parameter); + String baseName; + if (isReceiver && parameterIndex == 0) { + final SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, psiSubstitutor.substitute(parameter.getType())); + baseName = nameInfo.names.length > 0 ? nameInfo.names[0] : parameter.getName(); + } + else { + final String initialName = psiParameters != null ? psiParameters[parameterIndex - (isReceiver ? 1 : 0)].getName() : parameter.getName(); + baseName = codeStyleManager.variableNameToPropertyName(initialName, VariableKind.PARAMETER); + } + + if (baseName != null) { + String parameterName = codeStyleManager.suggestUniqueVariableName(baseName, referenceExpression, true); map.put(parameter, parameterName); return parameterName; } @@ -92,11 +107,10 @@ public class ReplaceMethodRefWithLambdaIntention extends Intention { final boolean onArrayRef = JavaPsiFacade.getElementFactory(element.getProject()).getArrayClass(PsiUtil.getLanguageLevel(element)) == containingClass; - boolean isReceiver = PsiMethodReferenceUtil.isReceiverType(functionalInterfaceType, containingClass, resolveElement instanceof PsiMethod ? (PsiMethod)resolveElement : null); final PsiElement referenceNameElement = referenceExpression.getReferenceNameElement(); if (isReceiver){ - buf.append(parameters[0].getName()).append("."); + buf.append(map.get(parameters[0])).append("."); } else { if (!(referenceNameElement instanceof PsiKeyword)) { if (qualifier instanceof PsiTypeElement) { diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Ambiguity_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Ambiguity_after.java index b0e14f13dad8..2d27aef15301 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Ambiguity_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Ambiguity_after.java @@ -14,6 +14,6 @@ public class MyTest { static void call(int i, I2 s) {} public static void main(String[] args) { - call(1, (x) -> MyTest.m(x)); + call(1, (i) -> MyTest.m(i)); } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/ArrayMethodRef_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/ArrayMethodRef_after.java index 65a55a55e8aa..94c8d2f42151 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/ArrayMethodRef_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/ArrayMethodRef_after.java @@ -1,6 +1,6 @@ public class Foo { static void foo() { - Cln j = (p) -> p.clone(); + Cln j = (ints) -> ints.clone(); } interface Cln { diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInference1_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInference1_after.java index b61947e47488..bd874395a9f5 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInference1_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInference1_after.java @@ -10,8 +10,8 @@ public class MyTest { static void m(I s) {} static { - m((s) -> { - new Foo(s); + m((x) -> { + new Foo(x); }); } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInference_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInference_after.java index 22e5bef35348..cd937894625e 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInference_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInference_after.java @@ -11,6 +11,6 @@ public class MyTest { } static { - I s = (z) -> new MyTest(z); + I s = (x) -> new MyTest(x); } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInnerClass_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInnerClass_after.java index 600af263857a..0d1106d8e4b6 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInnerClass_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsInnerClass_after.java @@ -8,6 +8,6 @@ class MyTest { } static { - I i1 = (receiver) -> new Inner(receiver); + I i1 = (mt) -> new Inner(mt); } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsStaticInnerClass_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsStaticInnerClass_after.java index fdce48211ed4..c26cd8a6d244 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsStaticInnerClass_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/NewRefsStaticInnerClass_after.java @@ -10,6 +10,6 @@ class MyTest { static { - I i1 = (receiver) -> new Inner(receiver); + I i1 = (outer) -> new Inner(outer); } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Receiver_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Receiver_after.java index 9f5bcafa929d..5b3eaf82c2b9 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Receiver_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Receiver_after.java @@ -11,6 +11,6 @@ public class MyTest { } static { - I i = (I) (receiver) -> receiver.m(); + I i = (I) (myTest) -> myTest.m(); } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Subst_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Subst_after.java index c719ccefa15b..2ff6feee03b9 100644 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Subst_after.java +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/types/methodRefs2lambda/Subst_after.java @@ -5,5 +5,5 @@ class Bar { } class Test { - Comparator comparator = (o1, o2) -> o1.xxx(o2); + Comparator comparator = (bar, p) -> bar.xxx(p); } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java index a99de0b8eb10..df0e67385c8c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureUtil.java @@ -356,11 +356,11 @@ public class MvcModuleStructureUtil { private static void removeInvalidSourceRoots(List> actions, MvcProjectStructure structure) { final Set toRemove = ContainerUtil.newTroveSet(); - final Set toRemoveContent = ContainerUtil.newTroveSet(); + final Set toRemoveContent = ContainerUtil.newTroveSet(); for (ContentEntry entry : ModuleRootManager.getInstance(structure.myModule).getContentEntries()) { final VirtualFile file = entry.getFile(); if (file == null || !structure.isValidContentRoot(file)) { - toRemoveContent.add(entry); + toRemoveContent.add(entry.getUrl()); } else { for (SourceFolder folder : entry.getSourceFolders()) { @@ -376,7 +376,7 @@ public class MvcModuleStructureUtil { @Override public void consume(ModifiableRootModel model) { for (ContentEntry entry : model.getContentEntries()) { - if (toRemoveContent.remove(entry)) { + if (toRemoveContent.remove(entry.getUrl())) { model.removeContentEntry(entry); } else { diff --git a/resources-en/src/messages/DebuggerBundle.properties b/resources-en/src/messages/DebuggerBundle.properties index ff3238c7dab2..0b7069199dcc 100644 --- a/resources-en/src/messages/DebuggerBundle.properties +++ b/resources-en/src/messages/DebuggerBundle.properties @@ -173,7 +173,6 @@ label.array.renderer.configurable.start.index=Array sta&rt index: label.array.renderer.configurable.end.index=en&d index: label.array.renderer.configurable.max.count1=Show &maximum label.array.renderer.configurable.max.count2=array elements -base.renderer.configurable.display.name=Data Views label.base.renderer.configurable.autoscroll=Autoscroll to new &local variables label.base.renderer.configurable.show.synthetic.fields=S&ynthetic fields label.base.renderer.configurable.show.val.fields.as.locals=$val fields as local &variables @@ -186,10 +185,9 @@ label.base.renderer.configurable.show.static.final.fields=Static &final fields label.base.renderer.configurable.show.declared.type=Declared &type label.base.renderer.configurable.show.fq.names=Fully &qualified names label.base.renderer.configurable.show.object.id=Object &id -label.base.renderer.configurable.auto.expressions=Enable auto expressions in Variables view label.base.renderer.configurable.alternate.view=Enable alternative view for Coll&ections classes -label.base.renderer.configurable.enable.tostring=Enable 't&oString()' object view: -label.base.renderer.configurable.all.overridding=For all classes that override 'toString()' method +label.base.renderer.configurable.enable.toString=Enable 't&oString()' object view: +label.base.renderer.configurable.all.overriding=For all classes that override 'toString()' method label.base.renderer.configurable.classes.from.list=For classes from the list: label.compound.renderer.configurable.use.default.renderer=Use default renderer label.compound.renderer.configurable.use.expression=Use following expression: @@ -208,13 +206,11 @@ label.compound.renderer.configurable.table.header.name=Name label.compound.renderer.configurable.table.header.expression=Expression debugger.launching.configurable.display.name=Launching debugger.hotswap.configurable.display.name=HotSwap -debugger.stepping.configurable.display.name=Stepping label.debugger.launching.configurable.hide.window=Hide debug &window on process termination label.debugger.focusAppOnBreakpoint=Focus application on breakpoint label.debugger.hotswap.configurable.hotswap.background=Reload classes in &background label.debugger.hotswap.configurable.compile.before.hotswap=Make project before reloading classes label.debugger.hotswap.configurable.enable.vm.hang.warning=Enable 'JVM will hang' warning -label.debugger.general.configurable.tooltips.delay=&Value tooltips delay (ms): label.debugger.hotswap.configurable.reload.classes=Reload classes after compilation: label.debugger.hotswap.configurable.always=&Always label.debugger.hotswap.configurable.never=&Never