mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge commit 'origin/master'
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
@@ -25,19 +26,23 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -48,6 +53,7 @@ import java.util.Map;
|
||||
*/
|
||||
public class MarkObjectAction extends DebuggerAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.MarkObjectAction");
|
||||
public static final long AUTO_MARKUP_REFERRING_OBJECTS_LIMIT = 100L; // todo: some reasonable limit
|
||||
private final String MARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.text");
|
||||
private final String UNMARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.unmark.text");
|
||||
|
||||
@@ -79,13 +85,17 @@ public class MarkObjectAction extends DebuggerAction {
|
||||
valueDescriptor.setMarkup(debugProcess, null);
|
||||
}
|
||||
else {
|
||||
final ValueMarkup suggestedMarkup = new ValueMarkup(valueDescriptor.getName(), Color.RED);
|
||||
final String defaultText = valueDescriptor.getName();
|
||||
final Ref<Pair<ValueMarkup,Boolean>> result = new Ref<Pair<ValueMarkup, Boolean>>(null);
|
||||
try {
|
||||
final boolean suggestAdditionalMarkup = canSuggestAdditionalMarkup(debugProcess, valueDescriptor.getValue());
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
result.set(ObjectMarkupPropertiesDialog.chooseMarkup(suggestedMarkup, suggestAdditionalMarkup));
|
||||
ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(defaultText, suggestAdditionalMarkup);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
result.set(Pair.create(dialog.getConfiguredMarkup(), dialog.isMarkAdditionalFields()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -176,7 +186,7 @@ public class MarkObjectAction extends DebuggerAction {
|
||||
final ValueMarkup markup = result.get((ObjectReference)fieldValue);
|
||||
|
||||
final String fieldName = field.name();
|
||||
final Color autoMarkupColor = ValueMarkup.getAutoMarkupColor();
|
||||
final Color autoMarkupColor = getAutoMarkupColor();
|
||||
if (markup == null) {
|
||||
result.put((ObjectReference)fieldValue, new ValueMarkup(fieldName, autoMarkupColor, createMarkupTooltipText(null, refType, fieldName)));
|
||||
}
|
||||
@@ -197,8 +207,9 @@ public class MarkObjectAction extends DebuggerAction {
|
||||
// invoke the following method using Reflection in order to remain compilable on jdk 1.5
|
||||
// java.util.List<com.sun.jdi.ObjectReference> referringObjects(long l);
|
||||
try {
|
||||
final java.lang.reflect.Method apiMethod = ObjectReference.class.getMethod("referringObjects", long.class);
|
||||
return (List<ObjectReference>)apiMethod.invoke(value, ValueMarkup.AUTO_MARKUP_REFERRING_OBJECTS_LIMIT);
|
||||
final Method apiMethod = ObjectReference.class.getMethod("referringObjects", long.class);
|
||||
//noinspection unchecked
|
||||
return (List<ObjectReference>)apiMethod.invoke(value, AUTO_MARKUP_REFERRING_OBJECTS_LIMIT);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
LOG.error(e); // should not happen
|
||||
@@ -211,7 +222,7 @@ public class MarkObjectAction extends DebuggerAction {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static String createMarkupTooltipText(String prefix, ReferenceType refType, String fieldName) {
|
||||
private static String createMarkupTooltipText(@Nullable String prefix, ReferenceType refType, String fieldName) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
if (prefix == null) {
|
||||
builder.append("Value referenced from:");
|
||||
@@ -241,4 +252,10 @@ public class MarkObjectAction extends DebuggerAction {
|
||||
presentation.setVisible(enable);
|
||||
presentation.setText(text);
|
||||
}
|
||||
|
||||
public static Color getAutoMarkupColor() {
|
||||
final EditorColorsManager manager = EditorColorsManager.getInstance();
|
||||
final TextAttributes textAttributes = manager.getGlobalScheme().getAttributes(HighlightInfoType.STATIC_FIELD.getAttributesKey());
|
||||
return textAttributes.getForegroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.debugger.actions.ObjectMarkupPropertiesDialog">
|
||||
<grid id="27dc6" binding="myAdditionalPropertiesPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="5" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="372" height="96"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="1dc00" class="com.intellij.openapi.ui.ex.MultiLineLabel" binding="myDescriptionLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d6e49" class="javax.swing.JCheckBox" binding="myCbMarkAdditionalFields">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&Mark values referenced from constant fields"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
+28
-112
@@ -15,140 +15,56 @@
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.FixedSizeButton;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.ui.ex.MultiLineLabel;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.ui.ColorChooser;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialog;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Feb 4, 2007
|
||||
*/
|
||||
public class ObjectMarkupPropertiesDialog extends DialogWrapper {
|
||||
private final JTextField myTextMarkupField;
|
||||
private final JCheckBox myCbMarkAdditionalFields;
|
||||
private final SimpleColoredComponent myColorSample;
|
||||
private SimpleTextAttributes myAttributes;
|
||||
private final Alarm myUpdateAlarm;
|
||||
private static final int UPDATE_DELAY = 200;
|
||||
private static Boolean ourMarkCbSavedState;
|
||||
public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialog {
|
||||
@NonNls private static final String MARK_ALL_REFERENCED_VALUES_KEY = "debugger.mark.all.referenced.values";
|
||||
private JCheckBox myCbMarkAdditionalFields;
|
||||
private final boolean mySuggestAdditionalMarkup;
|
||||
private JPanel myAdditionalPropertiesPanel;
|
||||
private MultiLineLabel myDescriptionLabel;
|
||||
|
||||
public ObjectMarkupPropertiesDialog(@NotNull final ValueMarkup suggestion, boolean suggestAdditionalMarkup) {
|
||||
super(true);
|
||||
public ObjectMarkupPropertiesDialog(@NotNull final String defaultText, boolean suggestAdditionalMarkup) {
|
||||
super(defaultText);
|
||||
mySuggestAdditionalMarkup = suggestAdditionalMarkup;
|
||||
setTitle("Select object label");
|
||||
setModal(true);
|
||||
myTextMarkupField = new JTextField(30);
|
||||
myCbMarkAdditionalFields = new JCheckBox("Mark values referenced from constant fields", ourMarkCbSavedState == null? suggestAdditionalMarkup : ourMarkCbSavedState);
|
||||
myCbMarkAdditionalFields.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
ourMarkCbSavedState = myCbMarkAdditionalFields.isSelected();
|
||||
}
|
||||
});
|
||||
myColorSample = new SimpleColoredComponent();
|
||||
myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
myAttributes = createAttributes(suggestion.getColor());
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
myTextMarkupField.setText(suggestion.getText().trim());
|
||||
updateLabelSample(0);
|
||||
}
|
||||
});
|
||||
myDescriptionLabel.setText("If the value is referenced by a constant field of an abstract class,\n" +
|
||||
"IDEA could additionally mark all values referenced from this class with the names of referencing fields.");
|
||||
myCbMarkAdditionalFields.setSelected(PropertiesComponent.getInstance().getBoolean(MARK_ALL_REFERENCED_VALUES_KEY, true));
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myTextMarkupField;
|
||||
}
|
||||
|
||||
protected void dispose() {
|
||||
myUpdateAlarm.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected JComponent createCenterPanel() {
|
||||
final JPanel mainPanel = new JPanel(new GridBagLayout());
|
||||
mainPanel.add(new JLabel("Label:"), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
|
||||
mainPanel.add(myTextMarkupField, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
final JPanel samplePanel = new JPanel(new BorderLayout());
|
||||
samplePanel.add(myColorSample, BorderLayout.CENTER);
|
||||
samplePanel.setBorder(BorderFactory.createEtchedBorder());
|
||||
final FixedSizeButton chooseColorButton = new FixedSizeButton(samplePanel);
|
||||
|
||||
double weighty = mySuggestAdditionalMarkup ? 0.0 : 1.0;
|
||||
mainPanel.add(new JLabel("Preview: "), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, weighty, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0));
|
||||
mainPanel.add(samplePanel, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, weighty, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 0, 0), 0, 0));
|
||||
mainPanel.add(chooseColorButton, new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 0.0, weighty, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0));
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
if (mySuggestAdditionalMarkup) {
|
||||
final JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.add(new MultiLineLabel(
|
||||
"If the value is referenced by a constant field of an abstract class,\nIDEA could additionally mark all values referenced from this class with the names of referencing fields."
|
||||
), BorderLayout.CENTER);
|
||||
panel.add(myCbMarkAdditionalFields, BorderLayout.SOUTH);
|
||||
myCbMarkAdditionalFields.setMnemonic('M');
|
||||
|
||||
mainPanel.add(panel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0));
|
||||
PropertiesComponent.getInstance().setValue(MARK_ALL_REFERENCED_VALUES_KEY, Boolean.toString(myCbMarkAdditionalFields.isSelected()));
|
||||
}
|
||||
|
||||
myTextMarkupField.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
protected void textChanged(final DocumentEvent e) {
|
||||
updateLabelSample(UPDATE_DELAY);
|
||||
}
|
||||
});
|
||||
chooseColorButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final Color color = ColorChooser.chooseColor(myColorSample, "Choose label color", null);
|
||||
myAttributes = createAttributes(color);
|
||||
updateLabelSample(UPDATE_DELAY);
|
||||
}
|
||||
});
|
||||
return mainPanel;
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
private void updateLabelSample(final int updateDelay) {
|
||||
myUpdateAlarm.cancelAllRequests();
|
||||
myUpdateAlarm.addRequest(new Runnable() {
|
||||
public void run() {
|
||||
myColorSample.clear();
|
||||
myColorSample.append(myTextMarkupField.getText().trim(), myAttributes);
|
||||
myColorSample.repaint();
|
||||
}
|
||||
}, updateDelay);
|
||||
}
|
||||
|
||||
public static Pair<ValueMarkup,Boolean> chooseMarkup(ValueMarkup suggestion, boolean suggestAdditionalMarkup) {
|
||||
final ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(suggestion, suggestAdditionalMarkup);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
final String text = dialog.myTextMarkupField.getText().trim();
|
||||
final Color color = dialog.myAttributes.getFgColor();
|
||||
return text.length() > 0? new Pair<ValueMarkup, Boolean>(new ValueMarkup(text, color, suggestion.getToolTipText()), dialog.myCbMarkAdditionalFields.isSelected()) : null;
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
JComponent mainPanel = super.createCenterPanel();
|
||||
if (!mySuggestAdditionalMarkup) {
|
||||
return mainPanel;
|
||||
}
|
||||
return null;
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.add(BorderLayout.CENTER, mainPanel);
|
||||
panel.add(BorderLayout.SOUTH, myAdditionalPropertiesPanel);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private static SimpleTextAttributes createAttributes(final Color color) {
|
||||
return new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, color);
|
||||
public boolean isMarkAdditionalFields() {
|
||||
return myCbMarkAdditionalFields.isSelected();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ package com.intellij.debugger.engine.evaluation;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
|
||||
@@ -94,7 +94,6 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos
|
||||
private ExecutionEnvironment myEnvironment;
|
||||
private RunProfile myConfiguration;
|
||||
|
||||
public static final String BREAKPOINT_CONDITION = "breakpoint";
|
||||
private final ThreadsPanel myThreadsPanel;
|
||||
private static final String THREAD_DUMP_CONTENT_PREFIX = "Dump";
|
||||
private final Icon myIcon;
|
||||
@@ -104,10 +103,10 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos
|
||||
|
||||
myIcon = icon;
|
||||
|
||||
myUi = RunnerLayoutUi.Factory.getInstance(project).create("JavaDebugger", DebuggerBundle.message("title.generic.debug.dialog"), sessionName, this);
|
||||
myUi = RunnerLayoutUi.Factory.getInstance(project).create("JavaDebugger", XDebuggerBundle.message("xdebugger.default.content.title"), sessionName, this);
|
||||
|
||||
myUi.getDefaults().initTabDefaults(0, "Debugger", null).
|
||||
initFocusContent(DebuggerContentInfo.FRAME_CONTENT, BREAKPOINT_CONDITION).
|
||||
myUi.getDefaults().initTabDefaults(0, XDebuggerBundle.message("xdebugger.debugger.tab.title"), null).
|
||||
initFocusContent(DebuggerContentInfo.FRAME_CONTENT, XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION).
|
||||
initFocusContent(DebuggerContentInfo.CONSOLE_CONTENT, LayoutViewOptions.STARTUP, new LayoutAttractionPolicy.FocusOnce(false));
|
||||
|
||||
final DefaultActionGroup focus = new DefaultActionGroup();
|
||||
@@ -479,9 +478,9 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos
|
||||
|
||||
private void attractFramesOnPause(final int event) {
|
||||
if (DebuggerSession.EVENT_PAUSE == event) {
|
||||
myUi.attractBy(BREAKPOINT_CONDITION);
|
||||
myUi.attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
|
||||
} else if (DebuggerSession.EVENT_RESUME == event) {
|
||||
myUi.clearAttractionBy(BREAKPOINT_CONDITION);
|
||||
myUi.clearAttractionBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ public class DebuggerStatementEditor extends DebuggerEditorImpl {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
myEditor.setCenterByHeight(false);
|
||||
setLayout(new BorderLayout());
|
||||
add(myEditor, BorderLayout.CENTER);
|
||||
|
||||
|
||||
+1
-1
@@ -654,7 +654,7 @@ public abstract class BreakpointWithHighlighter extends Breakpoint {
|
||||
return new AnAction() {
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
ENABLED = !ENABLED;
|
||||
DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager().fireBreakpointChanged(BreakpointWithHighlighter.this);
|
||||
DebuggerManagerEx.getInstanceEx(BreakpointWithHighlighter.this.getProject()).getBreakpointManager().fireBreakpointChanged(BreakpointWithHighlighter.this);
|
||||
updateUI();
|
||||
}
|
||||
};
|
||||
|
||||
+2
-2
@@ -16,10 +16,10 @@
|
||||
package com.intellij.debugger.ui.breakpoints.actions;
|
||||
|
||||
import com.intellij.execution.ui.actions.AbstractFocusOnAction;
|
||||
import com.intellij.debugger.ui.DebuggerSessionTab;
|
||||
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
|
||||
|
||||
public class FocusOnBreakpointAction extends AbstractFocusOnAction {
|
||||
public FocusOnBreakpointAction() {
|
||||
super(DebuggerSessionTab.BREAKPOINT_CONDITION);
|
||||
super(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
|
||||
}
|
||||
}
|
||||
@@ -345,43 +345,37 @@ public class DebuggerTreeBase extends DnDAwareTree implements Disposable {
|
||||
if (tabSize < 0) {
|
||||
tabSize = 0;
|
||||
}
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
try {
|
||||
boolean special = false;
|
||||
for (int idx = 0; idx < text.length(); idx++) {
|
||||
char c = text.charAt(idx);
|
||||
if (special) {
|
||||
if (c == 't') { // convert tabs to spaces
|
||||
for (int i = 0; i < tabSize; i++) {
|
||||
buf.append(' ');
|
||||
}
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
boolean special = false;
|
||||
for (int idx = 0; idx < text.length(); idx++) {
|
||||
char c = text.charAt(idx);
|
||||
if (special) {
|
||||
if (c == 't') { // convert tabs to spaces
|
||||
for (int i = 0; i < tabSize; i++) {
|
||||
buf.append(' ');
|
||||
}
|
||||
else if (c == 'r') { // remove occurrences of '\r'
|
||||
}
|
||||
else if (c == 'n') {
|
||||
buf.append('\n');
|
||||
}
|
||||
else {
|
||||
buf.append('\\');
|
||||
buf.append(c);
|
||||
}
|
||||
special = false;
|
||||
}
|
||||
else if (c == 'r') { // remove occurrences of '\r'
|
||||
}
|
||||
else if (c == 'n') {
|
||||
buf.append('\n');
|
||||
}
|
||||
else {
|
||||
if (c == '\\') {
|
||||
special = true;
|
||||
}
|
||||
else {
|
||||
buf.append(c);
|
||||
}
|
||||
buf.append('\\');
|
||||
buf.append(c);
|
||||
}
|
||||
special = false;
|
||||
}
|
||||
else {
|
||||
if (c == '\\') {
|
||||
special = true;
|
||||
}
|
||||
else {
|
||||
buf.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
finally {
|
||||
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
|
||||
@@ -20,7 +20,7 @@ import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.ui.impl.watch.*;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ColoredTreeCellRenderer;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import com.intellij.debugger.ui.impl.tree.TreeBuilderNode;
|
||||
import com.intellij.debugger.ui.tree.DebuggerTreeNode;
|
||||
import com.intellij.debugger.ui.tree.NodeDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
|
||||
import com.intellij.debugger.ui.tree.render.NodeRenderer;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.ui.tree.NodeDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Key;
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.settings.ThreadsViewSettings;
|
||||
import com.intellij.debugger.ui.tree.StackFrameDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
||||
import com.intellij.debugger.settings.NodeRendererSettings;
|
||||
import com.intellij.debugger.ui.tree.NodeDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.debugger.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.debugger.ui.tree.render.ClassRenderer;
|
||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
|
||||
import com.intellij.debugger.ui.tree.render.NodeRenderer;
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.debugger.DebuggerContext;
|
||||
import com.intellij.debugger.engine.DebugProcess;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.intellij.execution.filters;
|
||||
|
||||
import com.intellij.execution.ConsoleFolding;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class AuxiliaryCallsFolding extends ConsoleFolding {
|
||||
@Override
|
||||
public boolean shouldFoldLine(String line) {
|
||||
final Trinity<String, String, TextRange> pair = ExceptionFilter.parseExceptionLine(line);
|
||||
return pair != null && shouldFold(pair.first, pair.second);
|
||||
}
|
||||
|
||||
private static boolean shouldFold(String className, String methodName) {
|
||||
for (StackFrameFilter provider : StackFrameFilter.EP_NAME.getExtensions()) {
|
||||
if (provider.isAuxiliaryFrame(className, methodName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getPlaceholderText(List<String> lines) {
|
||||
return " <" + lines.size() + " internal calls>";
|
||||
}
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
package com.intellij.execution.filters;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class ReflectionStackFrameFilter extends StackFrameFilter {
|
||||
public boolean isAuxiliaryFrame(String className, String methodName) {
|
||||
if (className.equals("java.lang.reflect.Method") && methodName.equals("invoke")) {
|
||||
return true;
|
||||
}
|
||||
if (className.equals("java.lang.reflect.Constructor") && methodName.equals("newInstance")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return className.startsWith("sun.reflect.");
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.intellij.execution.filters;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class StackFrameFilter {
|
||||
public static final ExtensionPointName<StackFrameFilter> EP_NAME = ExtensionPointName.create("com.intellij.stackFrameFilter");
|
||||
|
||||
public abstract boolean isAuxiliaryFrame(String className, String methodName);
|
||||
|
||||
}
|
||||
+2
-8
@@ -40,7 +40,7 @@ public class NewModuleAction extends AnAction implements DumbAware {
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final Project project = getProject(e);
|
||||
final Project project = getEventProject(e);
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
@@ -88,12 +88,6 @@ public class NewModuleAction extends AnAction implements DumbAware {
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
super.update(e);
|
||||
e.getPresentation().setEnabled(getProject(e) != null);
|
||||
e.getPresentation().setEnabled(getEventProject(e) != null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Project getProject(AnActionEvent e) {
|
||||
return e.getData(PlatformDataKeys.PROJECT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
@@ -24,6 +23,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.FieldConflictsResolver;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ChangeContextUtil {
|
||||
@@ -112,28 +112,28 @@ public class ChangeContextUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static PsiElement decodeContextInfo(PsiElement scope,
|
||||
PsiClass thisClass,
|
||||
public static PsiElement decodeContextInfo(@NotNull PsiElement scope,
|
||||
@Nullable PsiClass thisClass,
|
||||
@Nullable PsiExpression thisAccessExpr) throws IncorrectOperationException {
|
||||
if (scope.getCopyableUserData(ENCODED_KEY) != null){
|
||||
if (scope.getCopyableUserData(ENCODED_KEY) != null) {
|
||||
scope.putCopyableUserData(ENCODED_KEY, null);
|
||||
|
||||
if (scope instanceof PsiThisExpression){
|
||||
if (scope instanceof PsiThisExpression) {
|
||||
PsiThisExpression thisExpr = (PsiThisExpression)scope;
|
||||
scope = decodeThisExpression(thisExpr, thisClass, thisAccessExpr);
|
||||
}
|
||||
else if (scope instanceof PsiReferenceExpression){
|
||||
else if (scope instanceof PsiReferenceExpression) {
|
||||
scope = decodeReferenceExpression((PsiReferenceExpression)scope, thisAccessExpr, thisClass);
|
||||
}
|
||||
else {
|
||||
PsiClass refClass = scope.getCopyableUserData(REF_CLASS_KEY);
|
||||
scope.putCopyableUserData(REF_CLASS_KEY, null);
|
||||
|
||||
if (refClass != null && refClass.isValid()){
|
||||
if (refClass != null && refClass.isValid()) {
|
||||
PsiReference ref = scope.getReference();
|
||||
if (ref != null) {
|
||||
final String qualifiedName = refClass.getQualifiedName();
|
||||
if (qualifiedName != null){
|
||||
if (qualifiedName != null) {
|
||||
if (JavaPsiFacade.getInstance(refClass.getProject()).findClass(qualifiedName, scope.getResolveScope()) != null) {
|
||||
scope = ref.bindToElement(refClass);
|
||||
}
|
||||
@@ -143,14 +143,15 @@ public class ChangeContextUtil {
|
||||
}
|
||||
}
|
||||
|
||||
if (scope instanceof PsiClass){
|
||||
if (thisAccessExpr != null){
|
||||
if (scope instanceof PsiClass) {
|
||||
if (thisAccessExpr != null) {
|
||||
thisAccessExpr = (PsiExpression)qualifyThis(thisAccessExpr, thisClass);
|
||||
}
|
||||
}
|
||||
|
||||
for(PsiElement child = scope.getFirstChild(); child != null; child = child.getNextSibling()){
|
||||
child = decodeContextInfo(child, thisClass, thisAccessExpr);
|
||||
PsiElement child = scope.getFirstChild();
|
||||
while (child != null) {
|
||||
child = decodeContextInfo(child, thisClass, thisAccessExpr).getNextSibling();
|
||||
}
|
||||
|
||||
return scope;
|
||||
|
||||
@@ -302,17 +302,19 @@ public class CodeInsightUtil {
|
||||
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
public Boolean compute() {
|
||||
if (!context.isValid() || !inheritor.isValid() || !facade.getResolveHelper().isAccessible(inheritor, context, null)) return true;
|
||||
if (!context.isValid() || !inheritor.isValid() || !facade.getResolveHelper().isAccessible(inheritor, context, null))
|
||||
return true;
|
||||
|
||||
if(inheritor.getQualifiedName() == null && !manager.areElementsEquivalent(inheritor.getContainingFile(), context.getContainingFile().getOriginalFile())){
|
||||
if (inheritor.getQualifiedName() == null &&
|
||||
!manager.areElementsEquivalent(inheritor.getContainingFile(), context.getContainingFile().getOriginalFile())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (JavaCompletionUtil.isInExcludedPackage(inheritor)) return true;
|
||||
|
||||
PsiSubstitutor superSubstitutor = TypeConversionUtil.getClassSubstitutor(baseClass, inheritor, PsiSubstitutor.EMPTY);
|
||||
if(superSubstitutor == null) return true;
|
||||
if(getRawSubtypes){
|
||||
if (superSubstitutor == null) return true;
|
||||
if (getRawSubtypes) {
|
||||
result.add(createType(inheritor, facade.getElementFactory().createRawSubstitutor(inheritor), arrayDim));
|
||||
return true;
|
||||
}
|
||||
@@ -322,7 +324,10 @@ public class CodeInsightUtil {
|
||||
for (PsiTypeParameter baseParameter : PsiUtil.typeParametersIterable(baseClass)) {
|
||||
final PsiType substituted = superSubstitutor.substitute(baseParameter);
|
||||
PsiType arg = baseSubstitutor.substitute(baseParameter);
|
||||
if (arg instanceof PsiWildcardType) arg = ((PsiWildcardType)arg).getExtendsBound();
|
||||
if (arg instanceof PsiWildcardType) {
|
||||
PsiType bound = ((PsiWildcardType)arg).getBound();
|
||||
arg = bound != null ? bound : ((PsiWildcardType)arg).getExtendsBound();
|
||||
}
|
||||
PsiType substitution = resolveHelper.getSubstitutionForTypeParameter(inheritorParameter,
|
||||
substituted,
|
||||
arg,
|
||||
|
||||
+19
-9
@@ -50,10 +50,7 @@ import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.*;
|
||||
|
||||
@@ -198,7 +195,6 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);
|
||||
|
||||
if (ANNOTATION_ATTRIBUTE_NAME.accepts(position)) {
|
||||
@@ -216,10 +212,17 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
result.addElement(LookupElementBuilder.create("*"));
|
||||
}
|
||||
|
||||
addReferenceVariants(parameters, result, inheritors);
|
||||
Set<String> usedWords = addReferenceVariants(parameters, result, inheritors);
|
||||
|
||||
addKeywords(parameters, result);
|
||||
|
||||
if (psiElement().inside(PsiLiteralExpression.class).accepts(position)) {
|
||||
PsiReference reference = position.getContainingFile().findReferenceAt(parameters.getOffset());
|
||||
if (reference == null || reference.isSoft()) {
|
||||
WordCompletionContributor.addWordCompletionVariants(result, parameters, usedWords);
|
||||
}
|
||||
}
|
||||
|
||||
addAllClasses(parameters, result, inheritors);
|
||||
result.stopHere();
|
||||
}
|
||||
@@ -239,7 +242,8 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) {
|
||||
private static Set<String> addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) {
|
||||
final Set<String> usedWords = new HashSet<String>();
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final boolean checkAccess = parameters.getInvocationCount() <= 1;
|
||||
LegacyCompletionContributor.processReferences(parameters, result, new PairConsumer<PsiReference, CompletionResultSet>() {
|
||||
@@ -291,19 +295,25 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
LOG.error("Position=" + position + "\n;Reference=" + reference + "\n;variants=" + Arrays.toString(variants));
|
||||
}
|
||||
if (completion instanceof LookupElement && !inheritors.alreadyProcessed((LookupElement)completion)) {
|
||||
usedWords.add(((LookupElement)completion).getLookupString());
|
||||
result.addElement((LookupElement)completion);
|
||||
}
|
||||
else if (completion instanceof PsiClass) {
|
||||
if (!inheritors.alreadyProcessed((PsiClass)completion)) {
|
||||
result.addElement(JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true));
|
||||
JavaPsiClassReferenceElement item = JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true);
|
||||
usedWords.add(item.getLookupString());
|
||||
result.addElement(item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.addElement(LookupItemUtil.objectToLookupItem(completion));
|
||||
LookupElement element = LookupItemUtil.objectToLookupItem(completion);
|
||||
usedWords.add(element.getLookupString());
|
||||
result.addElement(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return usedWords;
|
||||
}
|
||||
|
||||
private static void addKeywords(CompletionParameters parameters, CompletionResultSet result) {
|
||||
|
||||
@@ -140,7 +140,8 @@ public class SuppressFix extends SuppressIntentionAction {
|
||||
if (newAnnotation != null) {
|
||||
if (annotation != null && annotation.isPhysical()) {
|
||||
annotation.replace(newAnnotation);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
final PsiNameValuePair[] attributes = newAnnotation.getParameterList().getAttributes();
|
||||
new AddAnnotationFix(SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME, modifierOwner, attributes).invoke(project, editor, container.getContainingFile());
|
||||
}
|
||||
|
||||
@@ -990,7 +990,7 @@ public class HighlightUtil {
|
||||
HighlightInfo errorResult = null;
|
||||
if (expression != null && expression.getType() != null) {
|
||||
PsiType type = expression.getType();
|
||||
if (!isValidTypeForSwitchSelector(type, expression)) {
|
||||
if (!isValidTypeForSwitchSelector(type, PsiUtil.isLanguageLevel7OrHigher(expression))) {
|
||||
String message =
|
||||
JavaErrorMessages.message("incompatible.types", JavaErrorMessages.message("valid.switch.selector.types"), formatType(type));
|
||||
errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, message);
|
||||
@@ -1002,7 +1002,7 @@ public class HighlightUtil {
|
||||
return errorResult;
|
||||
}
|
||||
|
||||
private static boolean isValidTypeForSwitchSelector(PsiType type, PsiExpression expression) {
|
||||
public static boolean isValidTypeForSwitchSelector(PsiType type, final boolean languageLevel7OrHigher) {
|
||||
if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.INT_RANK) return true;
|
||||
if (type instanceof PsiClassType) {
|
||||
PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
@@ -1010,7 +1010,7 @@ public class HighlightUtil {
|
||||
if (psiClass.isEnum()) {
|
||||
return true;
|
||||
}
|
||||
if (PsiUtil.isLanguageLevel7OrHigher(expression)) {
|
||||
if (languageLevel7OrHigher) {
|
||||
return Comparing.strEqual(psiClass.getQualifiedName(), CommonClassNames.JAVA_LANG_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -32,6 +32,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiExpressionTrimRenderer;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
@@ -113,7 +114,7 @@ public class AccessStaticViaInstanceFix implements LocalQuickFix {
|
||||
qualifiedWithClassName.setQualifierExpression(factory.createReferenceExpression(containingClass));
|
||||
final boolean canCopeWithSideEffects = hasSideEffects;
|
||||
final SideEffectWarningDialog dialog =
|
||||
new SideEffectWarningDialog(project, false, null, sideEffects.get(0).getText(), qualifierExpression.getText(),
|
||||
new SideEffectWarningDialog(project, false, null, sideEffects.get(0).getText(), PsiExpressionTrimRenderer.render(qualifierExpression),
|
||||
canCopeWithSideEffects){
|
||||
@Override
|
||||
protected String sideEffectsDescription() {
|
||||
|
||||
+13
-1
@@ -28,6 +28,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiExpressionTrimRenderer;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.refactoring.psi.PropertyUtils;
|
||||
@@ -149,7 +150,18 @@ public class RemoveUnusedVariableFix implements IntentionAction {
|
||||
PsiVariable variable,
|
||||
Editor editor,
|
||||
boolean canCopeWithSideEffects) {
|
||||
String text = sideEffects.isEmpty() ? "" : sideEffects.get(0).getText();
|
||||
String text;
|
||||
if (sideEffects.isEmpty()) {
|
||||
text = "";
|
||||
}
|
||||
else {
|
||||
final PsiElement sideEffect = sideEffects.get(0);
|
||||
if (sideEffect instanceof PsiExpression) {
|
||||
text = PsiExpressionTrimRenderer.render((PsiExpression)sideEffect);
|
||||
} else {
|
||||
text = sideEffect.getText();
|
||||
}
|
||||
}
|
||||
return showSideEffectsWarning(sideEffects, variable, editor, canCopeWithSideEffects, text, text);
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -33,18 +33,18 @@ public class MissingReturnExpressionFixer implements Fixer {
|
||||
throws IncorrectOperationException {
|
||||
if (psiElement instanceof PsiReturnStatement) {
|
||||
PsiReturnStatement retStatement = (PsiReturnStatement) psiElement;
|
||||
if (retStatement.getReturnValue() != null &&
|
||||
startLine(editor, retStatement) == startLine(editor, retStatement.getReturnValue())) {
|
||||
PsiExpression returnValue = retStatement.getReturnValue();
|
||||
if (returnValue != null &&
|
||||
lineNumber(editor, editor.getCaretModel().getOffset()) == lineNumber(editor, returnValue.getTextRange().getStartOffset())) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement parent = PsiTreeUtil.getParentOfType(psiElement, PsiClassInitializer.class, PsiMethod.class);
|
||||
if (parent instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod) parent;
|
||||
final PsiType returnType = method.getReturnType();
|
||||
final PsiType returnType = ((PsiMethod) parent).getReturnType();
|
||||
if (returnType != null && returnType != PsiType.VOID) {
|
||||
final int startOffset = retStatement.getTextRange().getStartOffset();
|
||||
if (retStatement.getReturnValue() != null) {
|
||||
if (returnValue != null) {
|
||||
editor.getDocument().insertString(startOffset + "return".length(), ";");
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class MissingReturnExpressionFixer implements Fixer {
|
||||
}
|
||||
}
|
||||
|
||||
private int startLine(Editor editor, PsiElement psiElement) {
|
||||
return editor.getDocument().getLineNumber(psiElement.getTextRange().getStartOffset());
|
||||
private static int lineNumber(Editor editor, int offset) {
|
||||
return editor.getDocument().getLineNumber(offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,71 +20,59 @@ import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.lang.findUsages.FindUsagesProvider;
|
||||
import com.intellij.lang.findUsages.LanguageFindUsages;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.CaretModel;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class AddAnnotationFix extends PsiElementBaseIntentionAction implements LocalQuickFix {
|
||||
private final String myAnnotation;
|
||||
private final PsiModifierListOwner myModifierListOwner;
|
||||
public class AddAnnotationFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
protected final String myAnnotation;
|
||||
private final String[] myAnnotationsToRemove;
|
||||
private final PsiNameValuePair[] myPairs;
|
||||
private final PsiNameValuePair[] myPairs; // not used when registering local quick fix
|
||||
private static final Logger LOG = Logger.getInstance("#" + AddAnnotationFix.class.getName());
|
||||
private final String myText;
|
||||
|
||||
public AddAnnotationFix(String fqn, PsiModifierListOwner modifierListOwner, String... annotationsToRemove) {
|
||||
myAnnotation = fqn;
|
||||
myModifierListOwner = modifierListOwner;
|
||||
myAnnotationsToRemove = annotationsToRemove;
|
||||
myPairs = null;
|
||||
public AddAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner modifierListOwner, @NotNull String... annotationsToRemove) {
|
||||
this(fqn, modifierListOwner, PsiNameValuePair.EMPTY_ARRAY, annotationsToRemove);
|
||||
}
|
||||
|
||||
public AddAnnotationFix(String fqn, PsiModifierListOwner modifierListOwner, PsiNameValuePair[] values, String... annotationsToRemove) {
|
||||
public AddAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner modifierListOwner, @NotNull PsiNameValuePair[] values, @NotNull String... annotationsToRemove) {
|
||||
super(modifierListOwner);
|
||||
myAnnotation = fqn;
|
||||
myModifierListOwner = modifierListOwner;
|
||||
myAnnotationsToRemove = annotationsToRemove;
|
||||
myPairs = values;
|
||||
|
||||
myText = calcText(modifierListOwner, myAnnotation);
|
||||
}
|
||||
|
||||
public AddAnnotationFix(@NonNls final String fqn, @NonNls String... annotationsToRemove) {
|
||||
this(fqn, null,annotationsToRemove);
|
||||
public static String calcText(PsiModifierListOwner modifierListOwner, @NotNull String annotation) {
|
||||
final String shortName = annotation.substring(annotation.lastIndexOf('.') + 1);
|
||||
if (modifierListOwner instanceof PsiNamedElement) {
|
||||
final String name = ((PsiNamedElement)modifierListOwner).getName();
|
||||
if (name != null) {
|
||||
FindUsagesProvider provider = LanguageFindUsages.INSTANCE.forLanguage(modifierListOwner.getLanguage());
|
||||
return CodeInsightBundle
|
||||
.message("inspection.i18n.quickfix.annotate.element.as", provider.getType(modifierListOwner), name, shortName);
|
||||
}
|
||||
}
|
||||
return CodeInsightBundle.message("inspection.i18n.quickfix.annotate.as", shortName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
final String shortName = myAnnotation.substring(myAnnotation.lastIndexOf('.') + 1);
|
||||
if (myModifierListOwner instanceof PsiNamedElement) {
|
||||
final String name = ((PsiNamedElement)myModifierListOwner).getName();
|
||||
if (name != null) {
|
||||
FindUsagesProvider provider = LanguageFindUsages.INSTANCE.forLanguage(myModifierListOwner.getLanguage());
|
||||
return CodeInsightBundle.message("inspection.i18n.quickfix.annotate.element.as", provider.getType(myModifierListOwner), name, shortName);
|
||||
}
|
||||
}
|
||||
return myModifierListOwner != null ?
|
||||
CodeInsightBundle.message("inspection.i18n.quickfix.annotate.as", shortName) :
|
||||
CodeInsightBundle.message("add.external.annotation.test", shortName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return getText();
|
||||
return myText;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -92,17 +80,13 @@ public class AddAnnotationFix extends PsiElementBaseIntentionAction implements L
|
||||
return CodeInsightBundle.message("intention.add.annotation.family");
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
try {
|
||||
invoke(project, null, descriptor.getPsiElement().getContainingFile());
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static PsiModifierListOwner getContainer(final PsiElement element) {
|
||||
public static PsiModifierListOwner getContainer(final PsiElement element) {
|
||||
PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false);
|
||||
if (listOwner == null) {
|
||||
final PsiIdentifier psiIdentifier = PsiTreeUtil.getParentOfType(element, PsiIdentifier.class, false);
|
||||
@@ -113,86 +97,60 @@ public class AddAnnotationFix extends PsiElementBaseIntentionAction implements L
|
||||
return listOwner;
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) {
|
||||
if (!element.isValid()) return false;
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(element)) return false;
|
||||
final PsiModifierListOwner owner;
|
||||
if (myModifierListOwner != null) {
|
||||
if (!myModifierListOwner.isValid()) return false;
|
||||
//if (!PsiManager.getInstance(project).isInProject(myModifierListOwner)
|
||||
// || myModifierListOwner.getModifierList() == null) {
|
||||
// if (!myModifierListOwner.isPhysical()) { //we might want to apply fix to just created method
|
||||
// return true;
|
||||
// }
|
||||
//}
|
||||
|
||||
owner = myModifierListOwner;
|
||||
}
|
||||
else if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) {
|
||||
owner = getContainer(element);
|
||||
}
|
||||
else {
|
||||
owner = null;
|
||||
}
|
||||
return owner != null && !AnnotationUtil.isAnnotated(owner, myAnnotation, false);
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
if (!startElement.isValid()) return false;
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(startElement)) return false;
|
||||
final PsiModifierListOwner myModifierListOwner = (PsiModifierListOwner)startElement;
|
||||
|
||||
return !AnnotationUtil.isAnnotated(myModifierListOwner, myAnnotation, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
|
||||
final PsiElement element;
|
||||
if (myModifierListOwner != null) {
|
||||
element = myModifierListOwner;
|
||||
}
|
||||
else {
|
||||
final CaretModel caretModel = editor.getCaretModel();
|
||||
final int position = caretModel.getOffset();
|
||||
element = file.findElementAt(position);
|
||||
}
|
||||
return element != null && isAvailable(project, editor, element);
|
||||
}
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable("is null when called from inspection") Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
final PsiModifierListOwner myModifierListOwner = (PsiModifierListOwner)startElement;
|
||||
|
||||
public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(project);
|
||||
if (myModifierListOwner != null) {
|
||||
final PsiModifierList modifierList = myModifierListOwner.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
if (modifierList.findAnnotation(myAnnotation) != null) return;
|
||||
final ExternalAnnotationsManager.AnnotationPlace annotationAnnotationPlace = annotationsManager.chooseAnnotationsPlace(myModifierListOwner);
|
||||
if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.NOWHERE) return;
|
||||
if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.EXTERNAL) {
|
||||
for (String fqn : myAnnotationsToRemove) {
|
||||
annotationsManager.deannotate(myModifierListOwner, fqn);
|
||||
}
|
||||
annotationsManager.annotateExternally(myModifierListOwner, myAnnotation, file, myPairs);
|
||||
}
|
||||
else {
|
||||
final PsiFile containingFile = myModifierListOwner.getContainingFile();
|
||||
if (!CodeInsightUtilBase.preparePsiElementForWrite(containingFile)) return;
|
||||
for (String fqn : myAnnotationsToRemove) {
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(myModifierListOwner, fqn);
|
||||
if (annotation != null) {
|
||||
annotation.delete();
|
||||
}
|
||||
}
|
||||
|
||||
final @NotNull PsiAnnotation inserted = modifierList.addAnnotation(myAnnotation);
|
||||
if (myPairs != null) {
|
||||
for (PsiNameValuePair pair : myPairs) {
|
||||
inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue());
|
||||
}
|
||||
}
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted);
|
||||
if (containingFile != file) {
|
||||
UndoUtil.markPsiFileForUndo(file);
|
||||
}
|
||||
final PsiModifierList modifierList = myModifierListOwner.getModifierList();
|
||||
LOG.assertTrue(modifierList != null);
|
||||
if (modifierList.findAnnotation(myAnnotation) != null) return;
|
||||
final ExternalAnnotationsManager.AnnotationPlace annotationAnnotationPlace = annotationsManager.chooseAnnotationsPlace(myModifierListOwner);
|
||||
if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.NOWHERE) return;
|
||||
if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.EXTERNAL) {
|
||||
for (String fqn : myAnnotationsToRemove) {
|
||||
annotationsManager.deannotate(myModifierListOwner, fqn);
|
||||
}
|
||||
annotationsManager.annotateExternally(myModifierListOwner, myAnnotation, file, myPairs);
|
||||
}
|
||||
else {
|
||||
final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
annotationsManager.annotateExternally(PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class, false), myAnnotation, file, null);
|
||||
final PsiFile containingFile = myModifierListOwner.getContainingFile();
|
||||
if (!CodeInsightUtilBase.preparePsiElementForWrite(containingFile)) return;
|
||||
for (String fqn : myAnnotationsToRemove) {
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(myModifierListOwner, fqn);
|
||||
if (annotation != null) {
|
||||
annotation.delete();
|
||||
}
|
||||
}
|
||||
|
||||
PsiAnnotation inserted = modifierList.addAnnotation(myAnnotation);
|
||||
for (PsiNameValuePair pair : myPairs) {
|
||||
inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue());
|
||||
}
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted);
|
||||
if (containingFile != file) {
|
||||
UndoUtil.markPsiFileForUndo(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] getAnnotationsToRemove() {
|
||||
return myAnnotationsToRemove;
|
||||
}
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: cdr
|
||||
* Date: Jul 20, 2007
|
||||
* Time: 2:57:38 PM
|
||||
*/
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationFix;
|
||||
import com.intellij.openapi.editor.CaretModel;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class AddAnnotationIntention extends BaseIntentionAction {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return CodeInsightBundle.message("intention.add.annotation.family");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract Pair<String, String[]> getAnnotations(@NotNull Project project);
|
||||
|
||||
// include not in project files
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
CaretModel caretModel = editor.getCaretModel();
|
||||
int position = caretModel.getOffset();
|
||||
PsiElement element = file.findElementAt(position);
|
||||
return element != null && isAvailable(project, element);
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull final Project project, @NotNull final PsiElement element) {
|
||||
if (!element.isValid()) return false;
|
||||
if (!PsiUtil.isLanguageLevel5OrHigher(element)) return false;
|
||||
final PsiModifierListOwner owner;
|
||||
if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) {
|
||||
owner = AddAnnotationFix.getContainer(element);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
if (owner == null) return false;
|
||||
Pair<String, String[]> annotations = getAnnotations(project);
|
||||
String toAdd = annotations.first;
|
||||
String[] toRemove = annotations.second;
|
||||
if (toRemove.length > 0 && AnnotationUtil.isAnnotated(owner, toRemove[0], false)) return false;
|
||||
setText(AddAnnotationFix.calcText(owner, toAdd));
|
||||
if (AnnotationUtil.isAnnotated(owner, toAdd, false)) return false;
|
||||
|
||||
if (owner instanceof PsiMethod) {
|
||||
PsiType returnType = ((PsiMethod)owner).getReturnType();
|
||||
|
||||
return returnType != null && !(returnType instanceof PsiPrimitiveType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
CaretModel caretModel = editor.getCaretModel();
|
||||
int position = caretModel.getOffset();
|
||||
PsiElement element = file.findElementAt(position);
|
||||
|
||||
PsiModifierListOwner owner = AddAnnotationFix.getContainer(element);
|
||||
if (owner == null || !owner.isValid()) return;
|
||||
Pair<String, String[]> annotations = getAnnotations(project);
|
||||
String toAdd = annotations.first;
|
||||
String[] toRemove = annotations.second;
|
||||
AddAnnotationFix fix = new AddAnnotationFix(toAdd, owner, toRemove);
|
||||
fix.invoke(project, editor, file);
|
||||
}
|
||||
}
|
||||
+6
-23
@@ -22,32 +22,15 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.intention.AddAnnotationFix;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AddDeprecationAnnotationFix extends AddAnnotationFix {
|
||||
public AddDeprecationAnnotationFix() {
|
||||
super("java.lang.annotation.Deprecated");
|
||||
}
|
||||
|
||||
|
||||
public class AddDeprecationAnnotationIntention extends AddAnnotationIntention {
|
||||
@NotNull
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) {
|
||||
if (!super.isAvailable(project, editor, element)) {
|
||||
return false;
|
||||
}
|
||||
PsiModifierListOwner owner = getContainer(element);
|
||||
if (owner == null) {
|
||||
return false;
|
||||
}
|
||||
if (owner instanceof PsiMethod) {
|
||||
PsiType returnType = ((PsiMethod)owner).getReturnType();
|
||||
|
||||
return returnType != null && !(returnType instanceof PsiPrimitiveType);
|
||||
}
|
||||
return true;
|
||||
public Pair<String, String[]> getAnnotations(@NotNull Project project) {
|
||||
return new Pair<String, String[]>("java.lang.annotation.Deprecated", ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
}
|
||||
}
|
||||
+5
-8
@@ -22,26 +22,23 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AddNotNullAnnotationFix extends AddNullableNotNullAnnotationFix {
|
||||
@Deprecated
|
||||
public AddNotNullAnnotationFix() {
|
||||
super(AnnotationUtil.NOT_NULL, AnnotationUtil.NULLABLE);
|
||||
}
|
||||
public AddNotNullAnnotationFix(PsiModifierListOwner owner) {
|
||||
public AddNotNullAnnotationFix(@NotNull PsiModifierListOwner owner) {
|
||||
super(NullableNotNullManager.getInstance(owner.getProject()).getDefaultNotNull(),
|
||||
owner,
|
||||
getNullables(owner));
|
||||
}
|
||||
|
||||
private static String[] getNullables(PsiModifierListOwner owner) {
|
||||
@NotNull
|
||||
private static String[] getNullables(@NotNull PsiModifierListOwner owner) {
|
||||
final List<String> nullables = NullableNotNullManager.getInstance(owner.getProject()).getNullables();
|
||||
return ArrayUtil.toStringArray(nullables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: cdr
|
||||
* Date: Jul 20, 2007
|
||||
* Time: 2:57:38 PM
|
||||
*/
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AddNotNullAnnotationIntention extends AddAnnotationIntention {
|
||||
@NotNull
|
||||
@Override
|
||||
public Pair<String, String[]> getAnnotations(@NotNull Project project) {
|
||||
return new Pair<String, String[]>(NullableNotNullManager.getInstance(project).getDefaultNotNull(), getNullables(project));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String[] getNullables(@NotNull Project project) {
|
||||
final List<String> nullables = NullableNotNullManager.getInstance(project).getNullables();
|
||||
return ArrayUtil.toStringArray(nullables);
|
||||
}
|
||||
}
|
||||
+4
-8
@@ -22,26 +22,22 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AddNullableAnnotationFix extends AddNullableNotNullAnnotationFix {
|
||||
@Deprecated
|
||||
public AddNullableAnnotationFix() {
|
||||
super(AnnotationUtil.NULLABLE, AnnotationUtil.NOT_NULL);
|
||||
}
|
||||
|
||||
public AddNullableAnnotationFix(PsiModifierListOwner owner) {
|
||||
public AddNullableAnnotationFix(@NotNull PsiModifierListOwner owner) {
|
||||
super(NullableNotNullManager.getInstance(owner.getProject()).getDefaultNullable(),
|
||||
owner,
|
||||
getNotNulls(owner));
|
||||
}
|
||||
|
||||
private static String[] getNotNulls(PsiModifierListOwner owner) {
|
||||
@NotNull
|
||||
private static String[] getNotNulls(@NotNull PsiModifierListOwner owner) {
|
||||
final List<String> notnulls = NullableNotNullManager.getInstance(owner.getProject()).getNotNulls();
|
||||
return ArrayUtil.toStringArray(notnulls);
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: cdr
|
||||
* Date: Jul 20, 2007
|
||||
* Time: 2:57:59 PM
|
||||
*/
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AddNullableAnnotationIntention extends AddAnnotationIntention {
|
||||
@NotNull
|
||||
@Override
|
||||
public Pair<String, String[]> getAnnotations(@NotNull Project project) {
|
||||
return new Pair<String, String[]>(NullableNotNullManager.getInstance(project).getDefaultNullable(), getNotNulls(project));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String[] getNotNulls(@NotNull Project project) {
|
||||
final List<String> notnulls = NullableNotNullManager.getInstance(project).getNotNulls();
|
||||
return ArrayUtil.toStringArray(notnulls);
|
||||
}
|
||||
}
|
||||
+7
-9
@@ -24,26 +24,24 @@ package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationFix;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AddNullableNotNullAnnotationFix extends AddAnnotationFix {
|
||||
public AddNullableNotNullAnnotationFix(final String annotation, final String... annotationToRemove) {
|
||||
super(annotation, annotationToRemove);
|
||||
}
|
||||
|
||||
public AddNullableNotNullAnnotationFix(final String fqn, final PsiModifierListOwner owner, final String... annotationToRemove) {
|
||||
public AddNullableNotNullAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner owner, @NotNull String... annotationToRemove) {
|
||||
super(fqn, owner, annotationToRemove);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) {
|
||||
if (!super.isAvailable(project, editor, element)) {
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
if (!super.isAvailable(project, file, startElement, endElement)) {
|
||||
return false;
|
||||
}
|
||||
PsiModifierListOwner owner = getContainer(element);
|
||||
PsiModifierListOwner owner = getContainer(startElement);
|
||||
if (owner == null || AnnotationUtil.isAnnotated(owner, getAnnotationsToRemove()[0], false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+3
-1
@@ -61,7 +61,9 @@ public class AddOverrideAnnotationAction implements IntentionAction {
|
||||
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
PsiMethod method = findMethod(file, editor.getCaretModel().getOffset());
|
||||
new AddAnnotationFix(JAVA_LANG_OVERRIDE, method).invoke(project, editor, file);
|
||||
if (method != null) {
|
||||
new AddAnnotationFix(JAVA_LANG_OVERRIDE, method).invoke(project, editor, file);
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiMethod findMethod(PsiFile file, int offset) {
|
||||
|
||||
@@ -109,7 +109,7 @@ public class AnnotateMethodFix implements LocalQuickFix {
|
||||
return getName();
|
||||
}
|
||||
|
||||
private void annotateMethod(final PsiMethod method) {
|
||||
private void annotateMethod(@NotNull PsiMethod method) {
|
||||
try {
|
||||
new AddAnnotationFix(myAnnotation, method, myAnnotationsToRemove).invoke(method.getProject(), null, method.getContainingFile());
|
||||
}
|
||||
|
||||
+3
-3
@@ -25,11 +25,9 @@ import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import sun.util.LocaleServiceProviderPool;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
@@ -111,7 +109,9 @@ public class PossibleHeapPollutionVarargsInspection extends BaseJavaLocalInspect
|
||||
final PsiElement psiElement = descriptor.getPsiElement();
|
||||
if (psiElement instanceof PsiIdentifier) {
|
||||
final PsiMethod psiMethod = (PsiMethod)psiElement.getParent();
|
||||
new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor);
|
||||
if (psiMethod != null) {
|
||||
new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.controlFlow.DefUseUtil;
|
||||
import com.intellij.psi.util.PsiExpressionTrimRenderer;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import gnu.trove.THashSet;
|
||||
@@ -243,7 +244,10 @@ public class DefUseInspection extends BaseLocalInspectionTool {
|
||||
int res = SideEffectWarningDialog.DELETE_ALL;
|
||||
if (hasSideEffects) {
|
||||
hasSideEffects = PsiUtil.isStatement(psiInitializer);
|
||||
res = RemoveUnusedVariableFix.showSideEffectsWarning(sideEffects, variable, FileEditorManager.getInstance(project).getSelectedTextEditor(), hasSideEffects, sideEffects.get(0).getText(), variable.getTypeElement().getText() + " " + variable.getName() + ";<br>" + psiInitializer.getText());
|
||||
res = RemoveUnusedVariableFix.showSideEffectsWarning(sideEffects, variable,
|
||||
FileEditorManager.getInstance(project).getSelectedTextEditor(),
|
||||
hasSideEffects, sideEffects.get(0).getText(),
|
||||
variable.getTypeElement().getText() + " " + variable.getName() + ";<br>" + PsiExpressionTrimRenderer.render((PsiExpression)psiInitializer));
|
||||
}
|
||||
try {
|
||||
if (res == SideEffectWarningDialog.DELETE_ALL) {
|
||||
|
||||
+2
-1
@@ -80,6 +80,7 @@ public class AnnotateOverriddenMethodParameterFix implements LocalQuickFix {
|
||||
CodeInsightUtilBase.preparePsiElementsForWrite(toAnnotate);
|
||||
for (PsiParameter psiParam : toAnnotate) {
|
||||
try {
|
||||
assert psiParam != null : toAnnotate;
|
||||
new AddAnnotationFix(myAnnotation, psiParam, myAnnosToRemove).invoke(project, null, psiParam.getContainingFile());
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
@@ -92,4 +93,4 @@ public class AnnotateOverriddenMethodParameterFix implements LocalQuickFix {
|
||||
public String getFamilyName() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+73
-41
@@ -23,11 +23,12 @@ import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
|
||||
import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
@@ -76,13 +77,9 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
for (int i = 0, expressionsLength = expressions.length; i < Math.min(expressionsLength, parameters.length); i++) {
|
||||
PsiExpression psiExpression = expressions[i];
|
||||
if (psiExpression.getType() == PsiType.NULL) {
|
||||
if (!AnnotationUtil.isNullable(parameters[i]) && !AnnotationUtil.isNotNull(parameters[i])) {
|
||||
holder.registerProblem(psiExpression, "Null is passed to parameter which is not yet @Nullable", new AddNullableAnnotationFix(parameters[i]){
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
final PsiParameter parameter = parameters[i];
|
||||
if (!AnnotationUtil.isNullable(parameter) && !AnnotationUtil.isNotNull(parameter)) {
|
||||
holder.registerProblem(psiExpression, "Null is passed to parameter which is not yet @Nullable", new MyAddNullableAnnotationFix(parameter));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,21 +104,22 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
final PsiMethod getter = PropertyUtil.findPropertyGetter(field.getContainingClass(), propName, isStatic, false);
|
||||
final String nullableSimpleName = StringUtil.getShortName(manager.getDefaultNullable());
|
||||
final String notNullSimpleName = StringUtil.getShortName(manager.getDefaultNotNull());
|
||||
if (getter != null) {
|
||||
final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
if (REPORT_NOT_ANNOTATED_GETTER) {
|
||||
if (!AnnotationUtil.isAnnotated(getter, manager.getAllAnnotations()) &&
|
||||
!TypeConversionUtil.isPrimitiveAndNotNull(getter.getReturnType())) {
|
||||
holder.registerProblem(getter.getNameIdentifier(), InspectionsBundle
|
||||
holder.registerProblem(nameIdentifier, InspectionsBundle
|
||||
.message("inspection.nullable.problems.annotated.field.getter.not.annotated", StringUtil.getShortName(anno)),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
|
||||
}
|
||||
}
|
||||
if (annotated.isDeclaredNotNull && manager.isNullable(getter, false)) {
|
||||
holder.registerProblem(getter.getNameIdentifier(), InspectionsBundle.message(
|
||||
holder.registerProblem(nameIdentifier, InspectionsBundle.message(
|
||||
"inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), nullableSimpleName),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
|
||||
} else if (annotated.isDeclaredNullable && manager.isNotNull(getter, false)) {
|
||||
holder.registerProblem(getter.getNameIdentifier(), InspectionsBundle.message(
|
||||
holder.registerProblem(nameIdentifier, InspectionsBundle.message(
|
||||
"inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
|
||||
}
|
||||
@@ -131,23 +129,31 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propName, isStatic, false);
|
||||
if (setter != null) {
|
||||
final PsiParameter[] parameters = setter.getParameterList().getParameters();
|
||||
assert parameters.length == 1;
|
||||
assert parameters.length == 1 : setter.getText();
|
||||
final PsiParameter parameter = parameters[0];
|
||||
assert parameter != null : setter.getText();
|
||||
if (REPORT_NOT_ANNOTATED_SETTER_PARAMETER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations()) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
|
||||
holder.registerProblem(parameter.getNameIdentifier(),
|
||||
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier1 != null : parameter;
|
||||
holder.registerProblem(nameIdentifier1,
|
||||
InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated",
|
||||
StringUtil.getShortName(anno)),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
|
||||
}
|
||||
if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
|
||||
holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle.message(
|
||||
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier1 != null : parameter;
|
||||
holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
|
||||
"inspection.nullable.problems.annotated.field.setter.parameter.conflict",
|
||||
StringUtil.getShortName(anno), nullableSimpleName),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
|
||||
} else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
|
||||
holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle.message(
|
||||
}
|
||||
else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
|
||||
final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier1 != null : parameter;
|
||||
holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
|
||||
"inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
|
||||
@@ -187,20 +193,27 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
return true;
|
||||
}
|
||||
if (REPORT_NOT_ANNOTATED_SETTER_PARAMETER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations())) {
|
||||
holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle
|
||||
final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier2 != null : parameter;
|
||||
holder.registerProblem(nameIdentifier2, InspectionsBundle
|
||||
.message("inspection.nullable.problems.annotated.field.constructor.parameter.not.annotated",
|
||||
StringUtil.getShortName(anno)),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
|
||||
return true;
|
||||
}
|
||||
if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
|
||||
holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle.message(
|
||||
final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier2 != null : parameter;
|
||||
holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
|
||||
"inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
|
||||
nullableSimpleName),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
|
||||
} else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
|
||||
holder.registerProblem(parameter.getNameIdentifier(), InspectionsBundle.message(
|
||||
}
|
||||
else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
|
||||
final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
|
||||
assert nameIdentifier2 != null : parameter;
|
||||
holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
|
||||
"inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
|
||||
notNullSimpleName),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
@@ -306,14 +319,11 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
&& !annotated.isDeclaredNotNull
|
||||
&& AnnotationUtil.isNotNull(superMethod)) {
|
||||
reported_not_annotated_method_overrides_notnull = true;
|
||||
final String defaultNotNull = nullableManager.getDefaultNotNull();
|
||||
final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
|
||||
holder.registerProblem(method.getNameIdentifier(),
|
||||
InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull"),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(
|
||||
nullableManager.getDefaultNotNull(), ArrayUtil.toStringArray(nullableManager.getNullables())) {
|
||||
public int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
|
||||
return NullableStuffInspection.this.annotateBaseMethod(method, superMethod, project);
|
||||
}
|
||||
});
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, createAnnotateMethodFix(defaultNotNull, annotationsToRemove));
|
||||
}
|
||||
if (REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE || REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL) {
|
||||
PsiParameter[] superParameters = superMethod.getParameterList().getParameters();
|
||||
@@ -366,17 +376,11 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
&& !nullableManager.isNotNull(overriding, false)) {
|
||||
method.getNameIdentifier(); //load tree
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls());
|
||||
final String defaultNotNull = nullableManager.getDefaultNotNull();
|
||||
final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
|
||||
holder.registerProblem(annotation, InspectionsBundle.message("nullable.stuff.problems.overridden.methods.are.not.annotated"),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(nullableManager.getDefaultNotNull(), ArrayUtil.toStringArray(nullableManager.getNullables())){
|
||||
protected boolean annotateOverriddenMethods() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return InspectionsBundle.message("annotate.overridden.methods.as.notnull");
|
||||
}
|
||||
});
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
new MyAnnotateMethodFix(defaultNotNull, annotationsToRemove));
|
||||
methodQuickFixSuggested = true;
|
||||
}
|
||||
if (hasAnnotatedParameter) {
|
||||
@@ -400,9 +404,8 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
}
|
||||
}
|
||||
|
||||
protected int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
|
||||
final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
|
||||
return new AnnotateMethodFix(manager.getDefaultNotNull(), ArrayUtil.toStringArray(manager.getNullables())).annotateBaseMethod(method, superMethod, project);
|
||||
protected AnnotateMethodFix createAnnotateMethodFix(final String defaultNotNull, final String[] annotationsToRemove) {
|
||||
return new AnnotateMethodFix(defaultNotNull, annotationsToRemove);
|
||||
}
|
||||
|
||||
private static void reportNullableNotNullConflict(final ProblemsHolder holder, final PsiModifierListOwner listOwner, final PsiAnnotation declaredNullable,
|
||||
@@ -419,6 +422,35 @@ public class NullableStuffInspection extends BaseLocalInspectionTool {
|
||||
return new OptionsPanel();
|
||||
}
|
||||
|
||||
private static class MyAddNullableAnnotationFix extends AddNullableAnnotationFix {
|
||||
public MyAddNullableAnnotationFix(PsiParameter parameter) {
|
||||
super(parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyAnnotateMethodFix extends AnnotateMethodFix {
|
||||
public MyAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) {
|
||||
super(defaultNotNull, annotationsToRemove);
|
||||
}
|
||||
|
||||
protected boolean annotateOverriddenMethods() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return InspectionsBundle.message("annotate.overridden.methods.as.notnull");
|
||||
}
|
||||
}
|
||||
|
||||
private class OptionsPanel extends JPanel {
|
||||
private JCheckBox myNNParameterOverridesN;
|
||||
private JCheckBox myNAMethodOverridesNN;
|
||||
|
||||
@@ -32,11 +32,6 @@ public class JavaWordCompletionFilter implements WordCompletionElementFilter {
|
||||
JavaDocTokenType.DOC_COMMENT_DATA, JavaTokenType.STRING_LITERAL);
|
||||
|
||||
public boolean isWordCompletionEnabledIn(final IElementType element) {
|
||||
final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion();
|
||||
if (process != null && process.isAutopopupCompletion()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ENABLED_TOKENS.contains(element);
|
||||
}
|
||||
}
|
||||
@@ -1372,7 +1372,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
|
||||
);
|
||||
}
|
||||
final boolean rBrace = isRBrace(child);
|
||||
Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(childrenIndent, true);
|
||||
Indent childIndent = rBrace ? Indent.getNoneIndent() : getCodeBlockInternalIndent(childrenIndent, false);
|
||||
if (!rBrace && child.getElementType() == JavaElementType.CODE_BLOCK
|
||||
&& (getBraceStyle() == CommonCodeStyleSettings.NEXT_LINE_SHIFTED
|
||||
|| getBraceStyle() == CommonCodeStyleSettings.NEXT_LINE_SHIFTED2))
|
||||
|
||||
@@ -170,7 +170,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiAnnotation createAnnotationFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiAnnotation createAnnotationFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ANNOTATION, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiAnnotation)) {
|
||||
@@ -187,7 +187,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiDocTag createDocTagFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiDocTag createDocTagFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
return createDocTagFromText(text);
|
||||
}
|
||||
|
||||
@@ -202,14 +202,14 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiDocComment createDocCommentFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiDocComment createDocCommentFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
return createDocCommentFromText(text);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass createClassFromText(@NotNull final String body, final PsiElement context) throws IncorrectOperationException {
|
||||
final PsiJavaFile aFile = createDummyJavaFile(StringUtil.join("class _Dummy_ { ", body, " }"));
|
||||
public PsiClass createClassFromText(@NotNull final String body, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final PsiJavaFile aFile = createDummyJavaFile(StringUtil.join("class _Dummy_ {\n", body, "\n}"));
|
||||
final PsiClass[] classes = aFile.getClasses();
|
||||
if (classes.length != 1) {
|
||||
throw new IncorrectOperationException("Incorrect class \"" + body + "\".");
|
||||
@@ -219,7 +219,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiField createFieldFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiField createFieldFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiField)) {
|
||||
@@ -230,7 +230,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context, final LanguageLevel level) throws IncorrectOperationException {
|
||||
public PsiMethod createMethodFromText(@NotNull final String text, @Nullable final PsiElement context, final LanguageLevel level) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, level), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiMethod)) {
|
||||
@@ -241,14 +241,14 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public final PsiMethod createMethodFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public final PsiMethod createMethodFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final LanguageLevel level = LanguageLevelProjectExtension.getInstance(myManager.getProject()).getLanguageLevel();
|
||||
return createMethodFromText(text, context, level);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiParameter createParameterFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiParameter createParameterFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, PARAMETER, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiParameter)) {
|
||||
@@ -259,7 +259,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiResourceVariable createResourceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiResourceVariable createResourceFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, RESOURCE, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiResourceVariable)) {
|
||||
@@ -270,13 +270,13 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiType createTypeFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiType createTypeFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
return createTypeInner(text, context, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiTypeElement createTypeElementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiTypeElement createTypeElementFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiTypeElement)) {
|
||||
@@ -285,7 +285,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
return (PsiTypeElement)element;
|
||||
}
|
||||
|
||||
protected PsiType createTypeInner(final String text, final PsiElement context, final boolean markAsCopy) throws IncorrectOperationException {
|
||||
protected PsiType createTypeInner(final String text, @Nullable final PsiElement context, final boolean markAsCopy) throws IncorrectOperationException {
|
||||
final PsiPrimitiveType primitiveType = PRIMITIVE_TYPES.get(text);
|
||||
if (primitiveType != null) return primitiveType;
|
||||
|
||||
@@ -298,7 +298,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiJavaCodeReferenceElement createReferenceFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final boolean isStaticImport = context instanceof PsiImportStaticStatement &&
|
||||
!((PsiImportStaticStatement)context).isOnDemand();
|
||||
final boolean mayHaveDiamonds = context instanceof PsiNewExpression &&
|
||||
@@ -314,7 +314,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiCodeBlock createCodeBlockFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiCodeBlock createCodeBlockFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CODE_BLOCK, level(context), true), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiCodeBlock)) {
|
||||
@@ -325,7 +325,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiStatement createStatementFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiStatement createStatementFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, STATEMENT, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiStatement)) {
|
||||
@@ -336,7 +336,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiExpression createExpressionFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiExpression createExpressionFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, EXPRESSION, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiExpression)) {
|
||||
@@ -353,7 +353,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiTypeParameter createTypeParameterFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiTypeParameter createTypeParameterFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE_PARAMETER, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiTypeParameter)) {
|
||||
@@ -364,7 +364,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiComment createCommentFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiComment createCommentFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final PsiJavaFile aFile = createDummyJavaFile(text);
|
||||
for (PsiElement aChildren : aFile.getChildren()) {
|
||||
if (aChildren instanceof PsiComment) {
|
||||
@@ -382,7 +382,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiEnumConstant createEnumConstantFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiEnumConstant createEnumConstantFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ENUM_CONSTANT, level(context)), context);
|
||||
final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode());
|
||||
if (!(element instanceof PsiEnumConstant)) {
|
||||
@@ -393,8 +393,9 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiCatchSection createCatchSection(@NotNull final PsiClassType exceptionType, @NotNull final String exceptionName,
|
||||
final PsiElement context) throws IncorrectOperationException {
|
||||
public PsiCatchSection createCatchSection(@NotNull final PsiClassType exceptionType,
|
||||
@NotNull final String exceptionName,
|
||||
@Nullable final PsiElement context) throws IncorrectOperationException {
|
||||
final String text = StringUtil
|
||||
.join("catch (", exceptionType.getCanonicalText(), " ", exceptionName, ") {}");
|
||||
final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CATCH_SECTION, level(context)), context);
|
||||
@@ -406,7 +407,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
return (PsiCatchSection)myManager.getCodeStyleManager().reformat(element);
|
||||
}
|
||||
|
||||
private void setupCatchBlock(final String exceptionName, final PsiElement context, final PsiCatchSection psiCatchSection)
|
||||
private void setupCatchBlock(final String exceptionName, @Nullable final PsiElement context, final PsiCatchSection psiCatchSection)
|
||||
throws IncorrectOperationException {
|
||||
final FileTemplate catchBodyTemplate = FileTemplateManager.getInstance().getCodeTemplate(JavaTemplateUtil.TEMPLATE_CATCH_BODY);
|
||||
LOG.assertTrue(catchBodyTemplate != null);
|
||||
@@ -433,6 +434,7 @@ public class PsiJavaParserFacadeImpl extends PsiParserFacadeImpl implements PsiJ
|
||||
psiCatchSection.getCatchBlock().replace(codeBlockFromText);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiType createPrimitiveType(@NotNull final String text, @NotNull final PsiAnnotation[] annotations) throws IncorrectOperationException {
|
||||
final PsiPrimitiveType primitiveType = getPrimitiveType(text);
|
||||
|
||||
@@ -62,7 +62,8 @@ public class JavaDirectoryServiceImpl extends JavaDirectoryService {
|
||||
|
||||
List<PsiClass> classes = null;
|
||||
for (PsiFile file : dir.getFiles()) {
|
||||
if (file instanceof PsiClassOwner) {
|
||||
FileViewProvider viewProvider = file.getViewProvider();
|
||||
if (file instanceof PsiClassOwner && file == viewProvider.getPsi(viewProvider.getBaseLanguage())) {
|
||||
PsiClass[] psiClasses = ((PsiClassOwner)file).getClasses();
|
||||
if (psiClasses.length == 0) continue;
|
||||
if (classes == null) classes = new ArrayList<PsiClass>();
|
||||
|
||||
@@ -32,6 +32,8 @@ public class KnownElementWeigher extends ProximityWeigher {
|
||||
if (element instanceof PsiClass) {
|
||||
@NonNls final String qname = ((PsiClass)element).getQualifiedName();
|
||||
if (qname != null) {
|
||||
if (qname.startsWith("java.lang")) return 4;
|
||||
if (qname.startsWith("java.util")) return 3;
|
||||
if (qname.startsWith("java.")) return 2;
|
||||
if (qname.startsWith("javax.")) return 1;
|
||||
if (qname.startsWith("com.")) return -1;
|
||||
|
||||
+5
-3
@@ -212,6 +212,7 @@ public class InplaceIntroduceConstantPopup {
|
||||
visibilityCombo.setRenderer(new ListCellRendererWrapper<String>(visibilityCombo.getRenderer()) {
|
||||
@Override
|
||||
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
|
||||
if (value == null) return;
|
||||
setText(PsiBundle.visibilityPresentation(value));
|
||||
}
|
||||
});
|
||||
@@ -283,7 +284,7 @@ public class InplaceIntroduceConstantPopup {
|
||||
renamer.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
}
|
||||
}, IntroduceConstantHandler.REFACTORING_NAME, null);
|
||||
}, IntroduceConstantHandler.REFACTORING_NAME, IntroduceConstantHandler.REFACTORING_NAME);
|
||||
}
|
||||
|
||||
private PsiField createFieldToStartTemplateOn(final String[] names, final PsiType psiType) {
|
||||
@@ -339,7 +340,8 @@ public class InplaceIntroduceConstantPopup {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
myEditor, field, false,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1,
|
||||
myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers());
|
||||
myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers(),
|
||||
IntroduceConstantHandler.REFACTORING_NAME);
|
||||
|
||||
myDefaultParameterTypePointer =
|
||||
SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType());
|
||||
@@ -436,7 +438,7 @@ public class InplaceIntroduceConstantPopup {
|
||||
protected JComponent getComponent() {
|
||||
if (!myInitListeners) {
|
||||
myInitListeners = true;
|
||||
final VisibilityListener visibilityListener = new VisibilityListener(myProject, myEditor) {
|
||||
final VisibilityListener visibilityListener = new VisibilityListener(myProject, IntroduceConstantHandler.REFACTORING_NAME, myEditor) {
|
||||
@Override
|
||||
protected String getVisibility() {
|
||||
return getSelectedVisibility();
|
||||
|
||||
+5
-4
@@ -176,7 +176,7 @@ public class InplaceIntroduceFieldPopup {
|
||||
renamer.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
}
|
||||
}, IntroduceFieldHandler.REFACTORING_NAME, null);
|
||||
}, IntroduceFieldHandler.REFACTORING_NAME, IntroduceFieldHandler.REFACTORING_NAME);
|
||||
}
|
||||
|
||||
private PsiField createFieldToStartTemplateOn(final String[] names,
|
||||
@@ -230,7 +230,8 @@ public class InplaceIntroduceFieldPopup {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
myEditor, psiVariable, false,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1,
|
||||
myInitializerExpression != null && myInitializerExpression.isPhysical() ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers());
|
||||
myInitializerExpression != null && myInitializerExpression.isPhysical() ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers(),
|
||||
IntroduceFieldHandler.REFACTORING_NAME);
|
||||
myDefaultParameterTypePointer =
|
||||
SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(myTypeSelectorManager.getDefaultType());
|
||||
myFieldRangeStart = myEditor.getDocument().createRangeMarker(psiVariable.getTextRange());
|
||||
@@ -276,13 +277,13 @@ public class InplaceIntroduceFieldPopup {
|
||||
protected JComponent getComponent() {
|
||||
if (!myInitListeners) {
|
||||
myInitListeners = true;
|
||||
myIntroduceFieldPanel.addVisibilityListener(new VisibilityListener(myProject, myEditor){
|
||||
myIntroduceFieldPanel.addVisibilityListener(new VisibilityListener(myProject, IntroduceFieldHandler.REFACTORING_NAME, myEditor){
|
||||
@Override
|
||||
protected String getVisibility() {
|
||||
return myIntroduceFieldPanel.getFieldVisibility();
|
||||
}
|
||||
});
|
||||
final FinalListener finalListener = new FinalListener(myProject);
|
||||
final FinalListener finalListener = new FinalListener(myProject, IntroduceFieldHandler.REFACTORING_NAME);
|
||||
myIntroduceFieldPanel.addFinalListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
|
||||
+6
-4
@@ -57,8 +57,8 @@ public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroduce
|
||||
boolean cantChangeFinalModifier,
|
||||
boolean hasTypeSuggestion,
|
||||
RangeMarker exprMarker,
|
||||
List<RangeMarker> occurrenceMarkers) {
|
||||
super(project, expression, editor, elementToRename, cantChangeFinalModifier, hasTypeSuggestion, exprMarker, occurrenceMarkers);
|
||||
List<RangeMarker> occurrenceMarkers, String commandName) {
|
||||
super(project, expression, editor, elementToRename, cantChangeFinalModifier, hasTypeSuggestion, exprMarker, occurrenceMarkers, commandName);
|
||||
}
|
||||
|
||||
protected abstract boolean isReplaceAllOccurrences();
|
||||
@@ -143,16 +143,18 @@ public abstract class AbstractInplaceIntroducer extends VariableInplaceIntroduce
|
||||
|
||||
protected abstract class VisibilityListener implements ChangeListener {
|
||||
private Project myProject;
|
||||
private final String myCommandName;
|
||||
private Editor myEditor;
|
||||
|
||||
protected VisibilityListener(Project project, Editor editor) {
|
||||
protected VisibilityListener(Project project, String commandName, Editor editor) {
|
||||
myProject = project;
|
||||
myCommandName = commandName;
|
||||
myEditor = editor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
new WriteCommandAction(myProject) {
|
||||
new WriteCommandAction(myProject, myCommandName, myCommandName) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = myEditor.getDocument();
|
||||
|
||||
+5
-2
@@ -20,7 +20,9 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
@@ -202,7 +204,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
renamer.performInplaceRename(false, nameSuggestions);
|
||||
}
|
||||
}
|
||||
}, IntroduceParameterHandler.REFACTORING_NAME, null);
|
||||
}, IntroduceParameterHandler.REFACTORING_NAME, IntroduceParameterHandler.REFACTORING_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -234,7 +236,8 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
public ParameterInplaceIntroducer(PsiParameter parameter) {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
myEditor, parameter, myMustBeFinal,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, InplaceIntroduceParameterPopup.this.getOccurrenceMarkers());
|
||||
myTypeSelectorManager.getTypesForAll().length > 1, myExprMarker, InplaceIntroduceParameterPopup.this.getOccurrenceMarkers(),
|
||||
IntroduceParameterHandler.REFACTORING_NAME);
|
||||
myDefaultParameterTypePointer = SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(parameter.getType());
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -478,7 +478,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
|
||||
final boolean cantChangeFinalModifier = hasWriteAccess || (inFinalContext && choice == OccurrencesChooser.ReplaceChoice.ALL);
|
||||
final VariableInplaceRenamer renamer =
|
||||
new VariableInplaceIntroducer(project, expression, editor, elementToRename, cantChangeFinalModifier,
|
||||
typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers);
|
||||
typeSelectorManager.getTypesForAll().length > 1, exprMarker, occurrenceMarkers, IntroduceVariableBase.REFACTORING_NAME);
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
renamer.performInplaceRename(false, new LinkedHashSet<String>(Arrays.asList(suggestedName.names)));
|
||||
}
|
||||
|
||||
+7
-6
@@ -38,7 +38,6 @@ import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
@@ -52,7 +51,6 @@ import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.ui.TitlePanel;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.util.ui.PositionTracker;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -87,7 +85,8 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
final boolean cantChangeFinalModifier,
|
||||
final boolean hasTypeSuggestion,
|
||||
final RangeMarker exprMarker,
|
||||
final List<RangeMarker> occurrenceMarkers) {
|
||||
final List<RangeMarker> occurrenceMarkers,
|
||||
final String commandName) {
|
||||
super(elementToRename, editor);
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
@@ -110,7 +109,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
myCanBeFinal = new NonFocusableCheckBox("Declare final");
|
||||
myCanBeFinal.setSelected(createFinals());
|
||||
myCanBeFinal.setMnemonic('f');
|
||||
myCanBeFinal.addActionListener(new FinalListener(project));
|
||||
myCanBeFinal.addActionListener(new FinalListener(project, commandName));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,9 +380,11 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
|
||||
public class FinalListener implements ActionListener {
|
||||
private final Project myProject;
|
||||
private final String myCommandName;
|
||||
|
||||
public FinalListener(Project project) {
|
||||
public FinalListener(Project project, String commandName) {
|
||||
myProject = project;
|
||||
myCommandName = commandName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -396,7 +397,7 @@ public class VariableInplaceIntroducer extends VariableInplaceRenamer {
|
||||
}
|
||||
|
||||
public void perform(final boolean generateFinal, final String modifier) {
|
||||
new WriteCommandAction(myProject){
|
||||
new WriteCommandAction(myProject, myCommandName, myCommandName){
|
||||
@Override
|
||||
protected void run(com.intellij.openapi.application.Result result) throws Throwable {
|
||||
final Document document = myEditor.getDocument();
|
||||
|
||||
+124
-28
@@ -16,16 +16,21 @@
|
||||
package com.intellij.refactoring.move.moveMembers;
|
||||
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.refactoring.util.EnumConstantsUtil;
|
||||
import com.intellij.refactoring.util.RefactoringHierarchyUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.util.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
@@ -33,12 +38,13 @@ import java.util.*;
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
*/
|
||||
|
||||
public class MoveJavaMemberHandler implements MoveMemberHandler {
|
||||
public MoveMembersProcessor.MoveMembersUsageInfo getUsage(PsiMember member,
|
||||
PsiReference psiReference,
|
||||
Set<PsiMember> membersToMove,
|
||||
PsiClass targetClass) {
|
||||
@Override
|
||||
@Nullable
|
||||
public MoveMembersProcessor.MoveMembersUsageInfo getUsage(@NotNull PsiMember member,
|
||||
@NotNull PsiReference psiReference,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull PsiClass targetClass) {
|
||||
PsiElement ref = psiReference.getElement();
|
||||
if (ref instanceof PsiReferenceExpression) {
|
||||
PsiReferenceExpression refExpr = (PsiReferenceExpression)ref;
|
||||
@@ -70,15 +76,102 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isInMovedElement(PsiElement element, Set<PsiMember> membersToMove) {
|
||||
protected static boolean isInMovedElement(PsiElement element, Set<PsiMember> membersToMove) {
|
||||
for (PsiMember member : membersToMove) {
|
||||
if (PsiTreeUtil.isAncestor(member, element, false)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean changeExternalUsage(MoveMembersOptions options, MoveMembersProcessor.MoveMembersUsageInfo usage) {
|
||||
if (!usage.getElement().isValid()) return true;
|
||||
@Override
|
||||
public void checkConflictsOnUsage(@NotNull MoveMembersProcessor.MoveMembersUsageInfo usageInfo,
|
||||
@Nullable String newVisibility,
|
||||
@Nullable PsiModifierList modifierListCopy,
|
||||
@NotNull PsiClass targetClass,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts) {
|
||||
final PsiElement element = usageInfo.getElement();
|
||||
if (element == null) return;
|
||||
|
||||
final PsiMember member = usageInfo.member;
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression();
|
||||
PsiClass accessObjectClass = null;
|
||||
if (qualifier != null) {
|
||||
accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement();
|
||||
}
|
||||
|
||||
if (!JavaResolveUtil.isAccessible(member, targetClass, modifierListCopy, element, accessObjectClass, null)) {
|
||||
String visibility = newVisibility != null ? newVisibility : VisibilityUtil.getVisibilityStringToDisplay(member);
|
||||
String message = RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2",
|
||||
RefactoringUIUtil.getDescription(member, false),
|
||||
visibility,
|
||||
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true));
|
||||
conflicts.putValue(member, CommonRefactoringUtil.capitalize(message));
|
||||
}
|
||||
}
|
||||
|
||||
if (member instanceof PsiField && targetClass.isInterface()) {
|
||||
ReadWriteAccessDetector accessDetector = ReadWriteAccessDetector.findDetector(member);
|
||||
if (accessDetector != null) {
|
||||
ReadWriteAccessDetector.Access access = accessDetector.getExpressionAccess(element);
|
||||
if (access != ReadWriteAccessDetector.Access.Read) {
|
||||
String message = RefactoringUIUtil.getDescription(member, true) + " has write access but is moved to an interface";
|
||||
conflicts.putValue(element, CommonRefactoringUtil.capitalize(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final PsiReference reference = usageInfo.getReference();
|
||||
if (reference != null) {
|
||||
RefactoringConflictsUtil.checkAccessibilityConflicts(reference, member, modifierListCopy, targetClass, membersToMove, conflicts);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkConflictsOnMember(@NotNull PsiMember member,
|
||||
@Nullable String newVisibility,
|
||||
@Nullable PsiModifierList modifierListCopy,
|
||||
@NotNull PsiClass targetClass,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts) {
|
||||
if (member instanceof PsiMethod && hasMethod(targetClass, (PsiMethod)member) ||
|
||||
member instanceof PsiField && hasField(targetClass, (PsiField)member)) {
|
||||
String message = RefactoringBundle.message("0.already.exists.in.the.target.class", RefactoringUIUtil.getDescription(member, false));
|
||||
conflicts.putValue(member, CommonRefactoringUtil.capitalize(message));
|
||||
}
|
||||
|
||||
RefactoringConflictsUtil.checkUsedElements(member, member, membersToMove, null, targetClass, targetClass, conflicts);
|
||||
}
|
||||
|
||||
protected static boolean hasMethod(PsiClass targetClass, PsiMethod method) {
|
||||
PsiMethod[] targetClassMethods = targetClass.getMethods();
|
||||
for (PsiMethod candidate : targetClassMethods) {
|
||||
if (candidate != method &&
|
||||
MethodSignatureUtil.areSignaturesEqual(method.getSignature(PsiSubstitutor.EMPTY),
|
||||
candidate.getSignature(PsiSubstitutor.EMPTY))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static boolean hasField(PsiClass targetClass, PsiField field) {
|
||||
String fieldName = field.getName();
|
||||
PsiField[] targetClassFields = targetClass.getFields();
|
||||
for (PsiField candidate : targetClassFields) {
|
||||
if (candidate != field &&
|
||||
fieldName.equals(candidate.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeExternalUsage(@NotNull MoveMembersOptions options, @NotNull MoveMembersProcessor.MoveMembersUsageInfo usage) {
|
||||
final PsiElement element = usage.getElement();
|
||||
if (element == null || !element.isValid()) return true;
|
||||
|
||||
if (usage.reference instanceof PsiReferenceExpression) {
|
||||
PsiReferenceExpression refExpr = (PsiReferenceExpression)usage.reference;
|
||||
@@ -101,14 +194,24 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
public PsiMember doMove(MoveMembersOptions options, PsiMember member, PsiElement anchor, PsiClass targetClass) {
|
||||
protected static void changeQualifier(PsiReferenceExpression refExpr, PsiClass aClass, PsiMember member) throws IncorrectOperationException {
|
||||
if (RefactoringUtil.hasOnDemandStaticImport(refExpr, aClass)) {
|
||||
refExpr.setQualifierExpression(null);
|
||||
}
|
||||
else if (!RefactoringUtil.hasStaticImportOn(refExpr, member)){
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory();
|
||||
refExpr.setQualifierExpression(factory.createReferenceExpression(aClass));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiMember doMove(@NotNull MoveMembersOptions options, @NotNull PsiMember member, PsiElement anchor, @NotNull PsiClass targetClass) {
|
||||
if (member instanceof PsiVariable) {
|
||||
((PsiVariable)member).normalizeDeclaration();
|
||||
}
|
||||
|
||||
ChangeContextUtil.encodeContextInfo(member, true);
|
||||
if (targetClass == null) return null;
|
||||
|
||||
|
||||
final PsiMember memberCopy;
|
||||
if (options.makeEnumConstant() &&
|
||||
@@ -118,8 +221,9 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
|
||||
}
|
||||
else {
|
||||
memberCopy = (PsiMember)member.copy();
|
||||
if (member.getContainingClass().isInterface() && !targetClass.isInterface()) {
|
||||
//might need to make modifiers explicit, see IDEADEV-11416
|
||||
final PsiClass containingClass = member.getContainingClass();
|
||||
if (containingClass != null && containingClass.isInterface() && !targetClass.isInterface()) {
|
||||
// might need to make modifiers explicit, see IDEADEV-11416
|
||||
final PsiModifierList list = memberCopy.getModifierList();
|
||||
assert list != null;
|
||||
list.setModifierProperty(PsiModifier.STATIC, member.hasModifierProperty(PsiModifier.STATIC));
|
||||
@@ -131,22 +235,14 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
|
||||
return anchor != null ? (PsiMember)targetClass.addAfter(memberCopy, anchor) : (PsiMember)targetClass.add(memberCopy);
|
||||
}
|
||||
|
||||
public void decodeContextInfo(PsiElement scope) {
|
||||
@Override
|
||||
public void decodeContextInfo(@NotNull PsiElement scope) {
|
||||
ChangeContextUtil.decodeContextInfo(scope, null, null);
|
||||
}
|
||||
|
||||
private static void changeQualifier(PsiReferenceExpression refExpr, PsiClass aClass, PsiMember member) throws IncorrectOperationException {
|
||||
if (RefactoringUtil.hasOnDemandStaticImport(refExpr, aClass)) {
|
||||
refExpr.setQualifierExpression(null);
|
||||
}
|
||||
else if (!RefactoringUtil.hasStaticImportOn(refExpr, member)){
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory();
|
||||
refExpr.setQualifierExpression(factory.createReferenceExpression(aClass));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getAnchor(final PsiMember member, final PsiClass targetClass) {
|
||||
public PsiElement getAnchor(@NotNull final PsiMember member, @NotNull final PsiClass targetClass) {
|
||||
if (member instanceof PsiField && member.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final List<PsiField> afterFields = new ArrayList<PsiField>();
|
||||
final PsiExpression psiExpression = ((PsiField)member).getInitializer();
|
||||
|
||||
+31
-13
@@ -16,10 +16,9 @@
|
||||
package com.intellij.refactoring.move.moveMembers;
|
||||
|
||||
import com.intellij.lang.LanguageExtension;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -30,17 +29,36 @@ import java.util.Set;
|
||||
public interface MoveMemberHandler {
|
||||
LanguageExtension<MoveMemberHandler> EP_NAME = new LanguageExtension<MoveMemberHandler>("com.intellij.refactoring.moveMemberHandler");
|
||||
|
||||
MoveMembersProcessor.MoveMembersUsageInfo getUsage(PsiMember member,
|
||||
PsiReference ref,
|
||||
Set<PsiMember> membersToMove,
|
||||
PsiClass targetClass);
|
||||
@Nullable
|
||||
MoveMembersProcessor.MoveMembersUsageInfo getUsage(@NotNull PsiMember member,
|
||||
@NotNull PsiReference ref,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull PsiClass targetClass);
|
||||
|
||||
boolean changeExternalUsage(MoveMembersOptions options, MoveMembersProcessor.MoveMembersUsageInfo usage);
|
||||
void checkConflictsOnUsage(@NotNull MoveMembersProcessor.MoveMembersUsageInfo usageInfo,
|
||||
@Nullable String newVisibility,
|
||||
@Nullable PsiModifierList modifierListCopy,
|
||||
@NotNull PsiClass targetClass,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts);
|
||||
|
||||
PsiMember doMove(MoveMembersOptions options, PsiMember member, PsiElement anchor, PsiClass targetClass);
|
||||
|
||||
void decodeContextInfo(PsiElement scope);
|
||||
void checkConflictsOnMember(@NotNull PsiMember member,
|
||||
@Nullable String newVisibility,
|
||||
@Nullable PsiModifierList modifierListCopy,
|
||||
@NotNull PsiClass targetClass,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts);
|
||||
|
||||
@Nullable
|
||||
PsiElement getAnchor(PsiMember member, PsiClass targetClass);
|
||||
PsiElement getAnchor(@NotNull PsiMember member, @NotNull PsiClass targetClass);
|
||||
|
||||
boolean changeExternalUsage(@NotNull MoveMembersOptions options, @NotNull MoveMembersProcessor.MoveMembersUsageInfo usage);
|
||||
|
||||
@NotNull
|
||||
PsiMember doMove(@NotNull MoveMembersOptions options,
|
||||
@NotNull PsiMember member,
|
||||
@Nullable PsiElement anchor,
|
||||
@NotNull PsiClass targetClass);
|
||||
|
||||
void decodeContextInfo(@NotNull PsiElement scope);
|
||||
}
|
||||
|
||||
+61
-109
@@ -15,17 +15,13 @@
|
||||
*/
|
||||
package com.intellij.refactoring.move.moveMembers;
|
||||
|
||||
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
@@ -34,7 +30,9 @@ import com.intellij.refactoring.listeners.RefactoringElementListener;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.move.MoveHandler;
|
||||
import com.intellij.refactoring.move.MoveMemberViewDescriptor;
|
||||
import com.intellij.refactoring.util.*;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.MoveRenameUsageInfo;
|
||||
import com.intellij.refactoring.util.RefactoringConflictsUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usageView.UsageViewDescriptor;
|
||||
import com.intellij.usageView.UsageViewUtil;
|
||||
@@ -44,6 +42,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -61,16 +60,16 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
|
||||
private String myCommandName = MoveMembersImpl.REFACTORING_NAME;
|
||||
private MoveMembersOptions myOptions;
|
||||
|
||||
public MoveMembersProcessor(Project project, MoveCallback moveCallback, MoveMembersOptions options) {
|
||||
public MoveMembersProcessor(Project project, MoveMembersOptions options) {
|
||||
this(project, null, options);
|
||||
}
|
||||
|
||||
public MoveMembersProcessor(Project project, @Nullable MoveCallback moveCallback, MoveMembersOptions options) {
|
||||
super(project);
|
||||
myMoveCallback = moveCallback;
|
||||
setOptions(options);
|
||||
}
|
||||
|
||||
public MoveMembersProcessor(Project project, MoveMembersOptions options) {
|
||||
this(project, null, options);
|
||||
}
|
||||
|
||||
protected String getCommandName() {
|
||||
return myCommandName;
|
||||
}
|
||||
@@ -152,10 +151,11 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
|
||||
|
||||
protected void performRefactoring(final UsageInfo[] usages) {
|
||||
try {
|
||||
// correct references to moved members from the outside
|
||||
PsiClass targetClass = JavaPsiFacade.getInstance(myProject).findClass(myOptions.getTargetClassName(),
|
||||
GlobalSearchScope.projectScope(myProject));
|
||||
if (targetClass == null) return;
|
||||
|
||||
// collect anchors to place moved members at
|
||||
final Map<PsiMember, PsiElement> anchors = new HashMap<PsiMember, PsiElement>();
|
||||
for (PsiMember member : myMembersToMove) {
|
||||
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage());
|
||||
@@ -163,12 +163,14 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
|
||||
anchors.put(member, handler.getAnchor(member, targetClass));
|
||||
}
|
||||
}
|
||||
|
||||
// correct references to moved members from the outside
|
||||
ArrayList<MoveMembersUsageInfo> otherUsages = new ArrayList<MoveMembersUsageInfo>();
|
||||
for (UsageInfo usageInfo : usages) {
|
||||
MoveMembersUsageInfo usage = (MoveMembersUsageInfo)usageInfo;
|
||||
if (!usage.reference.isValid()) continue;
|
||||
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(usageInfo.getElement().getLanguage());
|
||||
if (handler!=null) {
|
||||
if (handler != null) {
|
||||
if (handler.changeExternalUsage(myOptions, usage)) continue;
|
||||
}
|
||||
otherUsages.add(usage);
|
||||
@@ -190,7 +192,7 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
|
||||
final RefactoringElementListener elementListener = getTransaction().getElementListener(member);
|
||||
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage());
|
||||
if (handler != null) {
|
||||
PsiMember newMember=handler.doMove(myOptions, member, anchors.get(member), targetClass);
|
||||
PsiMember newMember = handler.doMove(myOptions, member, anchors.get(member), targetClass);
|
||||
elementListener.elementMoved(newMember);
|
||||
|
||||
fixModifierList(newMember, usages);
|
||||
@@ -201,7 +203,6 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
// qualifier info must be decoded after members are moved
|
||||
//ChangeContextUtil.decodeContextInfo(myTargetClass, null, null);
|
||||
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(myTargetClass.getLanguage());
|
||||
if (handler != null) handler.decodeContextInfo(myTargetClass);
|
||||
|
||||
@@ -236,65 +237,63 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
|
||||
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
|
||||
final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>();
|
||||
final UsageInfo[] usages = refUsages.get();
|
||||
try {
|
||||
addInaccessibleConflicts(conflicts, usages);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
analyzeMoveConflicts(myMembersToMove, myTargetClass, myNewVisibility, conflicts);
|
||||
RefactoringConflictsUtil.analyzeModuleConflicts(myProject, myMembersToMove, usages, myTargetClass, conflicts);
|
||||
return showConflicts(conflicts, usages);
|
||||
}
|
||||
|
||||
private void addInaccessibleConflicts(final MultiMap<PsiElement, String> conflicts, final UsageInfo[] usages) throws IncorrectOperationException {
|
||||
String newVisibility = myNewVisibility;
|
||||
if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { //Still need to check for access object
|
||||
if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { // still need to check for access object
|
||||
newVisibility = PsiModifier.PUBLIC;
|
||||
}
|
||||
|
||||
Map<PsiMember, PsiModifierList> modifierListCopies = new HashMap<PsiMember, PsiModifierList>();
|
||||
final Map<PsiMember, PsiModifierList> modifierListCopies = new HashMap<PsiMember, PsiModifierList>();
|
||||
for (PsiMember member : myMembersToMove) {
|
||||
PsiModifierList copy = member.getModifierList();
|
||||
if (copy != null) copy = (PsiModifierList)copy.copy();
|
||||
if (newVisibility != null) {
|
||||
if (copy != null) VisibilityUtil.setVisibility(copy, newVisibility);
|
||||
PsiModifierList modifierListCopy = member.getModifierList();
|
||||
if (modifierListCopy != null) {
|
||||
modifierListCopy = (PsiModifierList)modifierListCopy.copy();
|
||||
}
|
||||
modifierListCopies.put(member, copy);
|
||||
if (modifierListCopy != null && newVisibility != null) {
|
||||
try {
|
||||
VisibilityUtil.setVisibility(modifierListCopy, newVisibility);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
modifierListCopies.put(member, modifierListCopy);
|
||||
}
|
||||
|
||||
analyzeConflictsOnUsages(usages, myMembersToMove, newVisibility, myTargetClass, modifierListCopies, conflicts);
|
||||
analyzeConflictsOnMembers(myMembersToMove, newVisibility, myTargetClass, modifierListCopies, conflicts);
|
||||
|
||||
RefactoringConflictsUtil.analyzeModuleConflicts(myProject, myMembersToMove, usages, myTargetClass, conflicts);
|
||||
|
||||
return showConflicts(conflicts, usages);
|
||||
}
|
||||
|
||||
private static void analyzeConflictsOnUsages(UsageInfo[] usages,
|
||||
Set<PsiMember> membersToMove,
|
||||
String newVisibility,
|
||||
PsiClass targetClass,
|
||||
Map<PsiMember, PsiModifierList> modifierListCopies,
|
||||
MultiMap<PsiElement, String> conflicts) {
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage instanceof MoveMembersUsageInfo) {
|
||||
final MoveMembersUsageInfo usageInfo = (MoveMembersUsageInfo)usage;
|
||||
PsiElement element = usage.getElement();
|
||||
if (element != null) {
|
||||
final PsiMember member = usageInfo.member;
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression();
|
||||
PsiClass accessObjectClass = null;
|
||||
if (qualifier != null) {
|
||||
accessObjectClass = (PsiClass)PsiUtil.getAccessObjectClass(qualifier).getElement();
|
||||
}
|
||||
if (!(usage instanceof MoveMembersUsageInfo)) continue;
|
||||
final MoveMembersUsageInfo usageInfo = (MoveMembersUsageInfo)usage;
|
||||
final PsiMember member = usageInfo.member;
|
||||
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage());
|
||||
if (handler != null) {
|
||||
handler.checkConflictsOnUsage(usageInfo, newVisibility, modifierListCopies.get(member), targetClass, membersToMove, conflicts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!JavaResolveUtil.isAccessible(member, myTargetClass, modifierListCopies.get(member), element, accessObjectClass, null)) {
|
||||
newVisibility = newVisibility == null ? VisibilityUtil.getVisibilityStringToDisplay(member) : newVisibility;
|
||||
String message =
|
||||
CommonRefactoringUtil.capitalize(RefactoringBundle.message("0.with.1.visibility.is.not.accessible.from.2", RefactoringUIUtil.getDescription(member, false),
|
||||
newVisibility, RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(element), true)));
|
||||
conflicts.putValue(member, message);
|
||||
}
|
||||
}
|
||||
|
||||
if (member instanceof PsiField && myTargetClass.isInterface()) {
|
||||
final ReadWriteAccessDetector accessDetector = ReadWriteAccessDetector.findDetector(member);
|
||||
if (accessDetector != null) {
|
||||
final ReadWriteAccessDetector.Access access = accessDetector.getExpressionAccess(element);
|
||||
if (access != ReadWriteAccessDetector.Access.Read) {
|
||||
conflicts.putValue(element, CommonRefactoringUtil.capitalize(RefactoringUIUtil.getDescription(member, true)) + " has write access but is moved to an interface");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private static void analyzeConflictsOnMembers(Set<PsiMember> membersToMove,
|
||||
String newVisibility,
|
||||
PsiClass targetClass,
|
||||
Map<PsiMember, PsiModifierList> modifierListCopies,
|
||||
MultiMap<PsiElement, String> conflicts) {
|
||||
for (final PsiMember member : membersToMove) {
|
||||
final MoveMemberHandler handler = MoveMemberHandler.EP_NAME.forLanguage(member.getLanguage());
|
||||
if (handler != null) {
|
||||
handler.checkConflictsOnMember(member, newVisibility, modifierListCopies.get(member), targetClass, membersToMove, conflicts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,53 +307,6 @@ public class MoveMembersProcessor extends BaseRefactoringProcessor {
|
||||
super.doRun();
|
||||
}
|
||||
|
||||
private static void analyzeMoveConflicts(@NotNull Set<PsiMember> membersToMove, final PsiClass targetClass, final String newVisibility,
|
||||
MultiMap<PsiElement, String> conflicts) {
|
||||
for (final PsiMember member : membersToMove) {
|
||||
if (member instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)member;
|
||||
if (hasMethod(targetClass, method)) {
|
||||
String message = RefactoringBundle.message("0.already.exists.in.the.target.class", RefactoringUIUtil.getDescription(method, false));
|
||||
message = CommonRefactoringUtil.capitalize(message);
|
||||
conflicts.putValue(method, message);
|
||||
}
|
||||
}
|
||||
else if (member instanceof PsiField) {
|
||||
PsiField field = (PsiField)member;
|
||||
if (hasField(targetClass, field)) {
|
||||
String message = RefactoringBundle.message("0.already.exists.in.the.target.class", RefactoringUIUtil.getDescription(field, false));
|
||||
message = CommonRefactoringUtil.capitalize(message);
|
||||
conflicts.putValue(field, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
RefactoringConflictsUtil.analyzeAccessibilityConflicts(membersToMove, targetClass, conflicts, newVisibility);
|
||||
}
|
||||
|
||||
private static boolean hasMethod(PsiClass targetClass, PsiMethod method) {
|
||||
PsiMethod[] targetClassMethods = targetClass.getMethods();
|
||||
for (PsiMethod candidate : targetClassMethods) {
|
||||
if (candidate != method &&
|
||||
MethodSignatureUtil.areSignaturesEqual(method.getSignature(PsiSubstitutor.EMPTY),
|
||||
candidate.getSignature(PsiSubstitutor.EMPTY))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasField(PsiClass targetClass, PsiField field) {
|
||||
String fieldName = field.getName();
|
||||
PsiField[] targetClassFields = targetClass.getFields();
|
||||
for (PsiField candidate : targetClassFields) {
|
||||
if (candidate != field &&
|
||||
fieldName.equals(candidate.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<PsiElement> getMembers() {
|
||||
return new ArrayList<PsiElement>(myMembersToMove);
|
||||
}
|
||||
|
||||
@@ -48,13 +48,16 @@ public class RefactoringConflictsUtil {
|
||||
private RefactoringConflictsUtil() { }
|
||||
|
||||
public static void analyzeAccessibilityConflicts(@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull final PsiClass targetClass,
|
||||
final MultiMap<PsiElement, String> conflicts, String newVisibility) {
|
||||
@NotNull PsiClass targetClass,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts,
|
||||
@Nullable String newVisibility) {
|
||||
analyzeAccessibilityConflicts(membersToMove, targetClass, conflicts, newVisibility, targetClass, null);
|
||||
}
|
||||
|
||||
public static void analyzeAccessibilityConflicts(@NotNull Set<PsiMember> membersToMove, @Nullable final PsiClass targetClass, final MultiMap<PsiElement, String> conflicts,
|
||||
String newVisibility,
|
||||
public static void analyzeAccessibilityConflicts(@NotNull Set<PsiMember> membersToMove,
|
||||
@Nullable PsiClass targetClass,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts,
|
||||
@Nullable String newVisibility,
|
||||
@NotNull PsiElement context,
|
||||
@Nullable Set<PsiMethod> abstractMethods) {
|
||||
if (VisibilityUtil.ESCALATE_VISIBILITY.equals(newVisibility)) { //Still need to check for access object
|
||||
@@ -63,41 +66,65 @@ public class RefactoringConflictsUtil {
|
||||
|
||||
for (PsiMember member : membersToMove) {
|
||||
checkUsedElements(member, member, membersToMove, abstractMethods, targetClass, context, conflicts);
|
||||
checkAccessibilityConflicts(member, newVisibility, targetClass, membersToMove, conflicts);
|
||||
}
|
||||
}
|
||||
|
||||
PsiModifierList modifierList = member.getModifierList();
|
||||
if (modifierList != null) modifierList = (PsiModifierList)modifierList.copy();
|
||||
|
||||
if (newVisibility != null) {
|
||||
try {
|
||||
if (modifierList != null) VisibilityUtil.setVisibility(modifierList, newVisibility);
|
||||
}
|
||||
catch (IncorrectOperationException ex) {
|
||||
/* do nothing and hope for the best */
|
||||
}
|
||||
public static void checkAccessibilityConflicts(@NotNull PsiMember member,
|
||||
@Nullable String newVisibility,
|
||||
@Nullable PsiClass targetClass,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts) {
|
||||
PsiModifierList modifierListCopy = member.getModifierList();
|
||||
if (modifierListCopy != null) {
|
||||
modifierListCopy = (PsiModifierList)modifierListCopy.copy();
|
||||
}
|
||||
if (newVisibility != null && modifierListCopy != null) {
|
||||
try {
|
||||
VisibilityUtil.setVisibility(modifierListCopy, newVisibility);
|
||||
}
|
||||
JavaPsiFacade manager = JavaPsiFacade.getInstance(member.getProject());
|
||||
for (PsiReference psiReference : ReferencesSearch.search(member)) {
|
||||
PsiElement ref = psiReference.getElement();
|
||||
if (!RefactoringHierarchyUtil.willBeInTargetClass(ref, membersToMove, targetClass, false)) {
|
||||
//Check for target class accessibility
|
||||
if (targetClass != null && !manager.getResolveHelper().isAccessible(targetClass, targetClass.getModifierList(), ref, null, null)) {
|
||||
String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class",
|
||||
RefactoringUIUtil.getDescription(targetClass, true),
|
||||
VisibilityUtil.getVisibilityStringToDisplay(targetClass),
|
||||
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true));
|
||||
message = CommonRefactoringUtil.capitalize(message);
|
||||
conflicts.putValue(targetClass, message);
|
||||
}
|
||||
//check for member accessibility
|
||||
else if (!manager.getResolveHelper().isAccessible(member, modifierList, ref, null, null)) {
|
||||
String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class",
|
||||
RefactoringUIUtil.getDescription(member, true),
|
||||
VisibilityUtil.getVisibilityStringToDisplay(member),
|
||||
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true));
|
||||
message = CommonRefactoringUtil.capitalize(message);
|
||||
conflicts.putValue(member, message);
|
||||
}
|
||||
}
|
||||
catch (IncorrectOperationException ignore) { } // do nothing and hope for the best
|
||||
}
|
||||
|
||||
checkAccessibilityConflicts(member, modifierListCopy, targetClass, membersToMove, conflicts);
|
||||
}
|
||||
|
||||
public static void checkAccessibilityConflicts(@NotNull PsiMember member,
|
||||
@Nullable PsiModifierList modifierListCopy,
|
||||
@Nullable PsiClass targetClass,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts) {
|
||||
for (PsiReference psiReference : ReferencesSearch.search(member)) {
|
||||
checkAccessibilityConflicts(psiReference, member, modifierListCopy, targetClass, membersToMove, conflicts);
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkAccessibilityConflicts(@NotNull PsiReference reference,
|
||||
@NotNull PsiMember member,
|
||||
@Nullable PsiModifierList modifierListCopy,
|
||||
@Nullable PsiClass targetClass,
|
||||
@NotNull Set<PsiMember> membersToMove,
|
||||
@NotNull MultiMap<PsiElement, String> conflicts) {
|
||||
JavaPsiFacade manager = JavaPsiFacade.getInstance(member.getProject());
|
||||
PsiElement ref = reference.getElement();
|
||||
if (!RefactoringHierarchyUtil.willBeInTargetClass(ref, membersToMove, targetClass, false)) {
|
||||
// check for target class accessibility
|
||||
if (targetClass != null && !manager.getResolveHelper().isAccessible(targetClass, targetClass.getModifierList(), ref, null, null)) {
|
||||
String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class",
|
||||
RefactoringUIUtil.getDescription(targetClass, true),
|
||||
VisibilityUtil.getVisibilityStringToDisplay(targetClass),
|
||||
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true));
|
||||
message = CommonRefactoringUtil.capitalize(message);
|
||||
conflicts.putValue(targetClass, message);
|
||||
}
|
||||
// check for member accessibility
|
||||
else if (!manager.getResolveHelper().isAccessible(member, modifierListCopy, ref, null, null)) {
|
||||
String message = RefactoringBundle.message("0.is.1.and.will.not.be.accessible.from.2.in.the.target.class",
|
||||
RefactoringUIUtil.getDescription(member, true),
|
||||
VisibilityUtil.getVisibilityStringToDisplay(member),
|
||||
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(ref), true));
|
||||
message = CommonRefactoringUtil.capitalize(message);
|
||||
conflicts.putValue(member, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +182,7 @@ public class RefactoringConflictsUtil {
|
||||
|
||||
public static void checkAccessibility(PsiMember refMember,
|
||||
@NotNull PsiElement newContext,
|
||||
PsiClass accessClass,
|
||||
@Nullable PsiClass accessClass,
|
||||
PsiMember member,
|
||||
MultiMap<PsiElement, String> conflicts) {
|
||||
if (!PsiUtil.isAccessible(refMember, newContext, accessClass)) {
|
||||
@@ -176,24 +203,24 @@ public class RefactoringConflictsUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void analyzeModuleConflicts(Project project,
|
||||
Collection<? extends PsiElement> scope,
|
||||
public static void analyzeModuleConflicts(final Project project,
|
||||
final Collection<? extends PsiElement> scopes,
|
||||
final UsageInfo[] usages,
|
||||
PsiElement target,
|
||||
final PsiElement target,
|
||||
final MultiMap<PsiElement,String> conflicts) {
|
||||
if (scope == null) return;
|
||||
if (scopes == null) return;
|
||||
final VirtualFile vFile = PsiUtilBase.getVirtualFile(target);
|
||||
if (vFile == null) return;
|
||||
analyzeModuleConflicts(project, scope, usages, vFile, conflicts);
|
||||
|
||||
analyzeModuleConflicts(project, scopes, usages, vFile, conflicts);
|
||||
}
|
||||
|
||||
public static void analyzeModuleConflicts(Project project,
|
||||
public static void analyzeModuleConflicts(final Project project,
|
||||
final Collection<? extends PsiElement> scopes,
|
||||
final UsageInfo[] usages,
|
||||
final VirtualFile vFile,
|
||||
final MultiMap<PsiElement, String> conflicts) {
|
||||
if (scopes == null) return;
|
||||
|
||||
for (final PsiElement scope : scopes) {
|
||||
if (scope instanceof PsiPackage || scope instanceof PsiDirectory) return;
|
||||
}
|
||||
@@ -207,16 +234,16 @@ public class RefactoringConflictsUtil {
|
||||
@Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
|
||||
super.visitReferenceElement(reference);
|
||||
final PsiElement resolved = reference.resolve();
|
||||
if (resolved != null && !reported.contains(resolved) && !CommonRefactoringUtil.isAncestor(resolved, scopes) &&
|
||||
if (resolved != null &&
|
||||
!reported.contains(resolved) &&
|
||||
!CommonRefactoringUtil.isAncestor(resolved, scopes) &&
|
||||
!PsiSearchScopeUtil.isInScope(resolveScope, resolved)) {
|
||||
final String scopeDescription =
|
||||
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(reference), true);
|
||||
final String scopeDescription = RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(reference), true);
|
||||
final String message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.in.module.2",
|
||||
CommonRefactoringUtil.capitalize(
|
||||
RefactoringUIUtil.getDescription(resolved, true)), scopeDescription,
|
||||
CommonRefactoringUtil.htmlEmphasize(
|
||||
targetModule.getName()));
|
||||
conflicts.putValue(resolved, message);
|
||||
RefactoringUIUtil.getDescription(resolved, true),
|
||||
scopeDescription,
|
||||
CommonRefactoringUtil.htmlEmphasize(targetModule.getName()));
|
||||
conflicts.putValue(resolved, CommonRefactoringUtil.capitalize(message));
|
||||
reported.add(resolved);
|
||||
}
|
||||
}
|
||||
@@ -255,19 +282,17 @@ public class RefactoringConflictsUtil {
|
||||
assert referencedElement != null : moveRenameUsageInfo;
|
||||
if (module == targetModule && isInTestSources) {
|
||||
message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.production.of.module.2",
|
||||
CommonRefactoringUtil.capitalize(
|
||||
RefactoringUIUtil.getDescription(referencedElement, true)),
|
||||
RefactoringUIUtil.getDescription(referencedElement, true),
|
||||
scopeDescription,
|
||||
CommonRefactoringUtil.htmlEmphasize(module.getName()));
|
||||
}
|
||||
else {
|
||||
message = RefactoringBundle.message("0.referenced.in.1.will.not.be.accessible.from.module.2",
|
||||
CommonRefactoringUtil.capitalize(
|
||||
RefactoringUIUtil.getDescription(referencedElement, true)),
|
||||
RefactoringUIUtil.getDescription(referencedElement, true),
|
||||
scopeDescription,
|
||||
CommonRefactoringUtil.htmlEmphasize(module.getName()));
|
||||
}
|
||||
conflicts.putValue(referencedElement, message);
|
||||
conflicts.putValue(referencedElement, CommonRefactoringUtil.capitalize(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,4 +300,4 @@ public class RefactoringConflictsUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
Object method() {
|
||||
return
|
||||
null<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
Object method() {
|
||||
return
|
||||
null;<caret>
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
public class Foo {
|
||||
private List<String> myList;
|
||||
|
||||
private void sort() {
|
||||
Collections.sort(myList, new Comparator<String>() {
|
||||
@Override
|
||||
public int compare(String o1, String o2) {
|
||||
<selection>return 0; //To change body of implemented methods use File | Settings | File Templates.</selection>
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
public class Foo {
|
||||
private List<String> myList;
|
||||
|
||||
private void sort() {
|
||||
Collections.sort(myList, new Comparator<caret>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
public class MyClass {
|
||||
String b = "My<caret>";
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
public class MyClass {
|
||||
String b = "MyClass<caret>";
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.testFramework.EditorActionTestCase;
|
||||
@@ -185,6 +184,8 @@ public class CompleteStatementTest extends EditorActionTestCase {
|
||||
|
||||
public void testIDEADEV40479() throws Exception { doTest(); }
|
||||
|
||||
public void testMultilineReturn() throws Exception { doTest(); }
|
||||
|
||||
public void testIDEADEV13019() throws Exception {
|
||||
doTestBracesNextLineStyle();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ import com.intellij.codeInsight.completion.impl.CompletionServiceImpl
|
||||
import com.intellij.codeInsight.lookup.Lookup
|
||||
import com.intellij.codeInsight.lookup.LookupManager
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl
|
||||
import com.intellij.codeInsight.template.TemplateManager
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.ide.ui.UISettings
|
||||
import com.intellij.openapi.actionSystem.IdeActions
|
||||
@@ -690,4 +692,36 @@ class Foo {
|
||||
assert myFixture.editor.document.text.contains('foo(aaa,)')
|
||||
}
|
||||
|
||||
public void testCompletionWhenLiveTemplateAreNotSufficient() {
|
||||
((TemplateManagerImpl)TemplateManager.getInstance(getProject())).setTemplateTesting(true);
|
||||
try {
|
||||
myFixture.configureByText("a.java", """
|
||||
class Foo {
|
||||
{
|
||||
Iterable<String> l1 = null;
|
||||
Iterable<String> l2 = null;
|
||||
Object asdf = null;
|
||||
iter<caret>
|
||||
}
|
||||
}
|
||||
""")
|
||||
type '\t'
|
||||
assert myFixture.lookupElementStrings == ['l2', 'l1']
|
||||
type 'as'
|
||||
assert lookup
|
||||
assert myFixture.lookupElementStrings == ['asdf', 'assert']
|
||||
}
|
||||
finally {
|
||||
((TemplateManagerImpl)TemplateManager.getInstance(getProject())).setTemplateTesting(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testNoWordCompletionAutoPopup() {
|
||||
myFixture.configureByText "a.java", 'class Bar { void foo() { "f<caret>" }}'
|
||||
type 'o'
|
||||
assert !lookup
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+7
@@ -11,6 +11,7 @@ import com.intellij.codeInsight.template.TemplateContextType;
|
||||
import com.intellij.codeInsight.template.TemplateManager;
|
||||
import com.intellij.codeInsight.template.impl.TemplateImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateSettings;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
@@ -984,6 +985,12 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
|
||||
assertStringItems("Bar", "Goo");
|
||||
}
|
||||
|
||||
public void testNoWrongSubstitutorFromStats() throws Throwable {
|
||||
doTest();
|
||||
FileDocumentManager.getInstance().saveDocument(myFixture.getEditor().getDocument());
|
||||
doTest(); // stats are changed now
|
||||
}
|
||||
|
||||
public void testCommonPrefixWithSelection() throws Throwable {
|
||||
doItemTest();
|
||||
}
|
||||
|
||||
+7
-12
@@ -40,17 +40,12 @@ public class WordCompletionTest extends CompletionTestCase {
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
|
||||
return new PsiReference[]{new PsiReferenceBase<PsiElement>(element) {
|
||||
return new PsiReference[]{new PsiReferenceBase<PsiElement>(element, true) {
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
@@ -63,17 +58,12 @@ public class WordCompletionTest extends CompletionTestCase {
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull final ProcessingContext context) {
|
||||
return new PsiReference[]{new PsiReferenceBase<PsiElement>(element) {
|
||||
return new PsiReference[]{new PsiReferenceBase<PsiElement>(element, false) {
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
@@ -89,6 +79,11 @@ public class WordCompletionTest extends CompletionTestCase {
|
||||
checkResultByFile(BASE_PATH + "3_after.java");
|
||||
}
|
||||
|
||||
public void testInJavaLiterals() throws Exception {
|
||||
configureByFile(BASE_PATH + "InJavaLiterals.java");
|
||||
checkResultByFile(BASE_PATH + "InJavaLiterals_after.java");
|
||||
}
|
||||
|
||||
public void testComments() throws Throwable {
|
||||
configureByFile(BASE_PATH + "4.java");
|
||||
checkResultByFile(BASE_PATH + "4_after.java");
|
||||
|
||||
+15
-8
@@ -1,9 +1,10 @@
|
||||
package com.intellij.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInspection.AnnotateMethodFix;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.nullable.NullableStuffInspection;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
public class AnnotateMethodTest extends LightQuickFix15TestCase {
|
||||
@@ -18,14 +19,20 @@ public class AnnotateMethodTest extends LightQuickFix15TestCase {
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{new NullableStuffInspection(){
|
||||
@Override
|
||||
protected int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
|
||||
@NonNls String name = method.getName();
|
||||
int ret = name.startsWith("annotateBase") ? 0 // yes, annotate all
|
||||
: name.startsWith("dontAnnotateBase") ? 1 // do not annotate base
|
||||
: 2; //abort
|
||||
myMustBeAvailableAfterInvoke = ret == 2;
|
||||
return ret;
|
||||
protected AnnotateMethodFix createAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) {
|
||||
return new AnnotateMethodFix(defaultNotNull, annotationsToRemove){
|
||||
@Override
|
||||
public int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
|
||||
@NonNls String name = method.getName();
|
||||
int ret = name.startsWith("annotateBase") ? 0 // yes, annotate all
|
||||
: name.startsWith("dontAnnotateBase") ? 1 // do not annotate base
|
||||
: 2; //abort
|
||||
myMustBeAvailableAfterInvoke = ret == 2;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
@@ -79,4 +79,5 @@ public interface CommonClassNames {
|
||||
@NonNls String CLASS_FILE_EXTENSION = ".class";
|
||||
|
||||
@NonNls String JAVA_UTIL_CONCURRENT_FUTURE = "java.util.concurrent.Future";
|
||||
@NonNls String JAVA_UTIL_ARRAY_LIST = "java.util.ArrayList";
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -22,8 +21,9 @@ import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/*
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
@@ -41,7 +41,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @deprecated use {@link #createDocTagFromText(String)} (to remove in IDEA 11)
|
||||
*/
|
||||
@NotNull
|
||||
PsiDocTag createDocTagFromText(@NotNull String docTagText, PsiElement context) throws IncorrectOperationException;
|
||||
PsiDocTag createDocTagFromText(@NotNull String docTagText, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a JavaDoc comment from the specified text.
|
||||
@@ -57,7 +57,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @deprecated use {@link #createDocCommentFromText(String)} (to remove in IDEA 11)
|
||||
*/
|
||||
@NotNull
|
||||
PsiDocComment createDocCommentFromText(@NotNull String docCommentText, PsiElement context) throws IncorrectOperationException;
|
||||
PsiDocComment createDocCommentFromText(@NotNull String docCommentText, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java class from the specified text.
|
||||
@@ -69,7 +69,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text is not a valid class body.
|
||||
*/
|
||||
@NotNull
|
||||
PsiClass createClassFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiClass createClassFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java field from the specified text.
|
||||
@@ -80,7 +80,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text is not a valid field body.
|
||||
*/
|
||||
@NotNull
|
||||
PsiField createFieldFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiField createFieldFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java method from the specified text with the specified language level.
|
||||
@@ -92,7 +92,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text is not a valid method body.
|
||||
*/
|
||||
@NotNull
|
||||
PsiMethod createMethodFromText(@NotNull @NonNls String text, PsiElement context, LanguageLevel languageLevel) throws IncorrectOperationException;
|
||||
PsiMethod createMethodFromText(@NotNull @NonNls String text, @Nullable PsiElement context, LanguageLevel languageLevel) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java method from the specified text.
|
||||
@@ -103,7 +103,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text is not a valid method body.
|
||||
*/
|
||||
@NotNull
|
||||
PsiMethod createMethodFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiMethod createMethodFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java parameter from the specified text.
|
||||
@@ -114,7 +114,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text is not a valid parameter body.
|
||||
*/
|
||||
@NotNull
|
||||
PsiParameter createParameterFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiParameter createParameterFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java try-resource from the specified text.
|
||||
@@ -125,7 +125,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text is not a valid resource definition.
|
||||
*/
|
||||
@NotNull
|
||||
PsiResourceVariable createResourceFromText(@NotNull final String text, final PsiElement context) throws IncorrectOperationException;
|
||||
PsiResourceVariable createResourceFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java type from the specified text.
|
||||
@@ -137,7 +137,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type.
|
||||
*/
|
||||
@NotNull
|
||||
PsiType createTypeFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiType createTypeFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java type element from the specified text.
|
||||
@@ -149,7 +149,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type.
|
||||
*/
|
||||
@NotNull
|
||||
PsiTypeElement createTypeElementFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiTypeElement createTypeElementFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java code reference from the specified text.
|
||||
@@ -161,7 +161,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type.
|
||||
*/
|
||||
@NotNull
|
||||
PsiJavaCodeReferenceElement createReferenceFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiJavaCodeReferenceElement createReferenceFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java code block from the specified text.
|
||||
@@ -172,7 +172,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid code block.
|
||||
*/
|
||||
@NotNull
|
||||
PsiCodeBlock createCodeBlockFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiCodeBlock createCodeBlockFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java statement from the specified text.
|
||||
@@ -183,7 +183,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid statement.
|
||||
*/
|
||||
@NotNull
|
||||
PsiStatement createStatementFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiStatement createStatementFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java expression from the specified text.
|
||||
@@ -194,7 +194,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid expression.
|
||||
*/
|
||||
@NotNull
|
||||
PsiExpression createExpressionFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiExpression createExpressionFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java comment from the specified text.
|
||||
@@ -205,7 +205,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid comment.
|
||||
*/
|
||||
@NotNull
|
||||
PsiComment createCommentFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiComment createCommentFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a type parameter from the specified text.
|
||||
@@ -216,7 +216,7 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid type parameter.
|
||||
*/
|
||||
@NotNull
|
||||
PsiTypeParameter createTypeParameterFromText(@NotNull @NonNls String text, PsiElement context) throws IncorrectOperationException;
|
||||
PsiTypeParameter createTypeParameterFromText(@NotNull @NonNls String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates an annotation from the specified text.
|
||||
@@ -227,11 +227,10 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @throws com.intellij.util.IncorrectOperationException if the text does not specify a valid annotation.
|
||||
*/
|
||||
@NotNull
|
||||
PsiAnnotation createAnnotationFromText(@NotNull @NonNls String annotationText, PsiElement context) throws IncorrectOperationException;
|
||||
PsiAnnotation createAnnotationFromText(@NotNull @NonNls String annotationText, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
@NotNull
|
||||
PsiEnumConstant createEnumConstantFromText(@NotNull String text, PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
PsiEnumConstant createEnumConstantFromText(@NotNull String text, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a <code>catch</code> section for catching an exception of the specified
|
||||
@@ -243,8 +242,8 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @return the created catch section instance.
|
||||
* @throws IncorrectOperationException if some of the parameters are not valid.
|
||||
*/
|
||||
@NotNull PsiCatchSection createCatchSection(@NotNull PsiClassType exceptionType, @NotNull String exceptionName, PsiElement context)
|
||||
throws IncorrectOperationException;
|
||||
@NotNull
|
||||
PsiCatchSection createCatchSection(@NotNull PsiClassType exceptionType, @NotNull String exceptionName, @Nullable PsiElement context) throws IncorrectOperationException;
|
||||
|
||||
/**
|
||||
* Creates a Java type from the specified text.
|
||||
@@ -254,5 +253,6 @@ public interface PsiJavaParserFacade extends PsiParserFacade {
|
||||
* @return the created type instance.
|
||||
* @throws IncorrectOperationException if some of the parameters are not valid.
|
||||
*/
|
||||
@NotNull
|
||||
PsiType createPrimitiveType(@NotNull String text, @NotNull PsiAnnotation[] annotations) throws IncorrectOperationException;
|
||||
}
|
||||
|
||||
@@ -169,8 +169,10 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
|
||||
DaemonCodeAnalyzerImpl daemonCodeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject());
|
||||
toInitializeDaemon = !daemonCodeAnalyzer.isInitialized();
|
||||
daemonCodeAnalyzer.prepareForTest(toInitializeDaemon);
|
||||
((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runStartupActivities();
|
||||
((StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject())).runPostStartupActivities();
|
||||
final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject());
|
||||
startupManager.runStartupActivities();
|
||||
startupManager.startCacheUpdate();
|
||||
startupManager.runPostStartupActivities();
|
||||
DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
|
||||
|
||||
if (isPerformanceTest()) {
|
||||
|
||||
+2
-2
@@ -17,6 +17,7 @@ package com.intellij.refactoring.move.moveMembers;
|
||||
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -47,7 +48,7 @@ public class MockMoveMembersOptions implements MoveMembersOptions {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setMemberVisibility(String visibility) {
|
||||
public void setMemberVisibility(@Nullable String visibility) {
|
||||
myMemberVisibility = visibility;
|
||||
}
|
||||
|
||||
@@ -60,5 +61,4 @@ public class MockMoveMembersOptions implements MoveMembersOptions {
|
||||
public String getTargetClassName() {
|
||||
return myTargetClassName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 135 B After Width: | Height: | Size: 235 B |
Binary file not shown.
|
After Width: | Height: | Size: 234 B |
Binary file not shown.
|
After Width: | Height: | Size: 135 B |
Binary file not shown.
|
After Width: | Height: | Size: 138 B |
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.completion;
|
||||
|
||||
import com.intellij.lang.LanguageParserDefinitions;
|
||||
import com.intellij.lang.ParserDefinition;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.util.ThreeState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class SkipAutopopupInStrings extends CompletionConfidence {
|
||||
@NotNull
|
||||
@Override
|
||||
public ThreeState shouldFocusLookup(@NotNull CompletionParameters parameters) {
|
||||
return ThreeState.UNSURE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ThreeState shouldSkipAutopopup(@Nullable PsiElement contextElement, @NotNull PsiFile psiFile, int offset) {
|
||||
if (contextElement != null) {
|
||||
ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(PsiUtilBase.getLanguageAtOffset(psiFile, offset));
|
||||
if (definition != null) {
|
||||
ElementPattern<PsiElement> pattern = PlatformPatterns.psiElement().withElementType(definition.getStringLiteralElements());
|
||||
if (pattern.accepts(contextElement) || pattern.accepts(contextElement.getParent())) {
|
||||
return ThreeState.YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ThreeState.UNSURE;
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package com.intellij.execution.ui.layout;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.ui.content.Content;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface LayoutViewOptions {
|
||||
|
||||
|
||||
@@ -25,11 +25,6 @@ import com.intellij.psi.tree.IElementType;
|
||||
|
||||
public class DefaultWordCompletionFilter implements WordCompletionElementFilter {
|
||||
public boolean isWordCompletionEnabledIn(final IElementType element) {
|
||||
final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion();
|
||||
if (process != null && process.isAutopopupCompletion()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(element.getLanguage());
|
||||
return parserDefinition != null && parserDefinition.getCommentTokens().contains(element);
|
||||
}
|
||||
|
||||
+5
-1
@@ -7,6 +7,8 @@ import com.intellij.psi.ReferenceRange;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -20,7 +22,9 @@ public final class SingleTargetRequestResultProcessor extends RequestResultProce
|
||||
}
|
||||
|
||||
public boolean processTextOccurrence(PsiElement element, int offsetInElement, final Processor<PsiReference> consumer) {
|
||||
for (PsiReference ref : ourReferenceService.getReferences(element, new PsiReferenceService.Hints(myTarget, offsetInElement))) {
|
||||
final List<PsiReference> references = ourReferenceService.getReferences(element,
|
||||
new PsiReferenceService.Hints(myTarget, offsetInElement));
|
||||
for (PsiReference ref : references) {
|
||||
if (ReferenceRange.containsOffsetInElement(ref, offsetInElement)) {
|
||||
if (ref.isReferenceTo(myTarget)) {
|
||||
if (!consumer.process(ref)) {
|
||||
|
||||
@@ -218,8 +218,12 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
|
||||
for(Map.Entry<FileType, IndentOptionsEditor> entry : myAdditionalIndentOptions.entrySet()) {
|
||||
FileType fileType = entry.getKey();
|
||||
CodeStyleSettings.IndentOptions additionalIndentOptions = settings.getAdditionalIndentOptions(fileType);
|
||||
if (additionalIndentOptions == null) {
|
||||
continue;
|
||||
}
|
||||
IndentOptionsEditor editor = entry.getValue();
|
||||
editor.apply(settings, settings.getAdditionalIndentOptions(fileType));
|
||||
editor.apply(settings, additionalIndentOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,9 +283,13 @@ public class GeneralCodeStylePanel extends CodeStyleAbstractPanel {
|
||||
}
|
||||
|
||||
for(Map.Entry<FileType, IndentOptionsEditor> entry : myAdditionalIndentOptions.entrySet()) {
|
||||
IndentOptionsEditor editor = entry.getValue();
|
||||
FileType fileType = entry.getKey();
|
||||
if (editor.isModified(settings, settings.getAdditionalIndentOptions(fileType))) {
|
||||
CodeStyleSettings.IndentOptions additionalIndentOptions = settings.getAdditionalIndentOptions(fileType);
|
||||
if (additionalIndentOptions == null) {
|
||||
continue;
|
||||
}
|
||||
IndentOptionsEditor editor = entry.getValue();
|
||||
if (editor.isModified(settings, additionalIndentOptions)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -621,6 +621,7 @@ public abstract class OptionTableWithPreviewPanel extends MultilanguageCodeStyle
|
||||
}
|
||||
});
|
||||
myBooleanEditor.putClientProperty("JComponent.sizeVariant", "small");
|
||||
myOptionsEditor.putClientProperty("JComponent.sizeVariant", "small");
|
||||
}
|
||||
|
||||
public Object getCellEditorValue() {
|
||||
|
||||
+5
-18
@@ -19,7 +19,6 @@ import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.LanguageWordCompletion;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.psi.PlainTextTokenTypes;
|
||||
@@ -71,6 +70,10 @@ public class WordCompletionContributor extends CompletionContributor implements
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parameters.getInvocationCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PsiFile file = insertedElement.getContainingFile();
|
||||
final CompletionData data = CompletionUtil.getCompletionDataByElement(insertedElement, file);
|
||||
if (data != null && !(data instanceof SyntaxTableCompletionData)) {
|
||||
@@ -95,8 +98,7 @@ public class WordCompletionContributor extends CompletionContributor implements
|
||||
ASTNode textContainer = element != null ? element.getNode() : null;
|
||||
while (textContainer != null) {
|
||||
final IElementType elementType = textContainer.getElementType();
|
||||
if (LanguageWordCompletion.INSTANCE.isEnabledIn(elementType) ||
|
||||
isPlainText(parameters, elementType)) {
|
||||
if (LanguageWordCompletion.INSTANCE.isEnabledIn(elementType) || elementType == PlainTextTokenTypes.PLAIN_TEXT) {
|
||||
return true;
|
||||
}
|
||||
textContainer = textContainer.getTreeParent();
|
||||
@@ -104,19 +106,4 @@ public class WordCompletionContributor extends CompletionContributor implements
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isPlainText(CompletionParameters parameters, IElementType elementType) {
|
||||
if (elementType != PlainTextTokenTypes.PLAIN_TEXT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (parameters.getInvocationCount() > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parameters.getOriginalFile().getViewProvider().getVirtualFile().isInLocalFileSystem();
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -18,6 +18,8 @@ package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.actions.BaseCodeInsightAction;
|
||||
import com.intellij.codeInsight.editorActions.emacs.EmacsProcessingHandler;
|
||||
import com.intellij.codeInsight.editorActions.emacs.LanguageEmacsExtension;
|
||||
import com.intellij.lang.LanguageFormatting;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -57,6 +59,14 @@ public class EmacsStyleIndentAction extends BaseCodeInsightAction implements Dum
|
||||
return;
|
||||
}
|
||||
|
||||
EmacsProcessingHandler emacsProcessingHandler = LanguageEmacsExtension.INSTANCE.forLanguage(file.getLanguage());
|
||||
if (emacsProcessingHandler != null) {
|
||||
EmacsProcessingHandler.Result result = emacsProcessingHandler.changeIndent(project, editor, file);
|
||||
if (result == EmacsProcessingHandler.Result.STOP) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final Document document = editor.getDocument();
|
||||
final int startOffset = editor.getCaretModel().getOffset();
|
||||
final int line = editor.offsetToLogicalPosition(startOffset).line;
|
||||
|
||||
+11
-12
@@ -28,7 +28,6 @@ import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
@@ -43,7 +42,6 @@ import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -96,6 +94,7 @@ public class JoinLinesHandler extends EditorWriteActionHandler {
|
||||
if (i >= doc.getLineCount() - 1) break;
|
||||
int lineEndOffset = doc.getLineEndOffset(startLine);
|
||||
|
||||
docManager.doPostponedOperationsAndUnblockDocument(doc);
|
||||
docManager.commitDocument(doc);
|
||||
CharSequence text = doc.getCharsSequence();
|
||||
int firstNonSpaceOffsetInNextLine = doc.getLineStartOffset(startLine + 1);
|
||||
@@ -120,7 +119,7 @@ public class JoinLinesHandler extends EditorWriteActionHandler {
|
||||
TextRange limits = findStartAndEnd(text, lastNonSpaceOffsetInStartLine, firstNonSpaceOffsetInNextLine, doc.getTextLength());
|
||||
start = limits.getStartOffset(); end = limits.getEndOffset();
|
||||
// run raw joiners
|
||||
for(JoinLinesHandlerDelegate delegate: Extensions.getExtensions(JoinRawLinesHandlerDelegate.EP_NAME)) {
|
||||
for(JoinLinesHandlerDelegate delegate: Extensions.getExtensions(JoinLinesHandlerDelegate.EP_NAME)) {
|
||||
if (delegate instanceof JoinRawLinesHandlerDelegate) {
|
||||
rc = ((JoinRawLinesHandlerDelegate)delegate).tryJoinRawLines(doc, psiFile, start, end);
|
||||
if (rc != CANNOT_JOIN) {
|
||||
@@ -239,16 +238,16 @@ public class JoinLinesHandler extends EditorWriteActionHandler {
|
||||
}
|
||||
|
||||
private static void doPostponedOperationsAndUnblockDocument(@NotNull PsiDocumentManager docManager, @NotNull DocumentEx document) {
|
||||
boolean restore = CodeEditUtil.isSuspendedNodesReformattingAllowed();
|
||||
CodeEditUtil.setAllowSuspendNodesReformatting(false);
|
||||
try {
|
||||
//boolean restore = CodeEditUtil.isSuspendedNodesReformattingAllowed();
|
||||
//CodeEditUtil.setAllowSuspendNodesReformatting(false);
|
||||
//try {
|
||||
docManager.doPostponedOperationsAndUnblockDocument(document);
|
||||
}
|
||||
finally {
|
||||
if (restore) {
|
||||
CodeEditUtil.setAllowSuspendNodesReformatting(true);
|
||||
}
|
||||
}
|
||||
//}
|
||||
//finally {
|
||||
// if (restore) {
|
||||
// CodeEditUtil.setAllowSuspendNodesReformatting(true);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
private static boolean isCommentElement(final PsiElement element) {
|
||||
|
||||
@@ -34,6 +34,9 @@ public class SelectWordUtil {
|
||||
|
||||
private static boolean ourExtensionsLoaded = false;
|
||||
|
||||
private SelectWordUtil() {
|
||||
}
|
||||
|
||||
public static void registerSelectioner(ExtendWordSelectionHandler selectioner) {
|
||||
SELECTIONERS = ArrayUtil.append(SELECTIONERS, selectioner);
|
||||
}
|
||||
@@ -60,7 +63,11 @@ public class SelectWordUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static TextRange getCamelSelectionRange(CharSequence editorText, int cursorOffset) {
|
||||
if (cursorOffset < 0 || cursorOffset >= editorText.length()) {
|
||||
return null;
|
||||
}
|
||||
if (cursorOffset > 0 && !Character.isJavaIdentifierPart(editorText.charAt(cursorOffset)) &&
|
||||
Character.isJavaIdentifierPart(editorText.charAt(cursorOffset - 1))) {
|
||||
cursorOffset--;
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.editorActions.emacs;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 4/11/11 2:36 PM
|
||||
*/
|
||||
public class DefaultEmacsProcessingHandler implements EmacsProcessingHandler {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Result changeIndent(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
|
||||
return Result.CONTINUE;
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.editorActions.emacs;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* This interface is assumed to define general contract for Emacs-like functionality.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 4/11/11 1:56 PM
|
||||
*/
|
||||
public interface EmacsProcessingHandler {
|
||||
|
||||
/**
|
||||
* Enumerates possible processing results.
|
||||
*/
|
||||
enum Result {
|
||||
/**
|
||||
* Proceed to the next handler in a chain.
|
||||
*/
|
||||
CONTINUE,
|
||||
|
||||
/**
|
||||
* Stop current processing as everything is done by the current handler
|
||||
*/
|
||||
STOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Emacs handles <code>Tab</code> pressing as
|
||||
* <a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/Basic-Indent.html#Basic-Indent">'auto indent line'</a>
|
||||
* most of the time. However, there are extensions to this like <a href="https://launchpad.net/python-mode">python-mode</a>
|
||||
* that changes indentation level of the current line (makes it belong to the other code block).
|
||||
* <p/>
|
||||
* So, current method may be implemented by changing code block for the active line by changing its indentation.
|
||||
* {@link Result#STOP} should be returned then.
|
||||
*
|
||||
* @param project current project
|
||||
* @param editor current editor
|
||||
* @param file current file
|
||||
* @return processing result
|
||||
*/
|
||||
@NotNull
|
||||
Result changeIndent(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file);
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.editorActions.emacs;
|
||||
|
||||
import com.intellij.lang.LanguageExtension;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 4/11/11 2:21 PM
|
||||
*/
|
||||
public class LanguageEmacsExtension extends LanguageExtension<EmacsProcessingHandler> {
|
||||
|
||||
public static final String EP_NAME = "com.intellij.lang.emacs";
|
||||
public static final LanguageEmacsExtension INSTANCE = new LanguageEmacsExtension();
|
||||
|
||||
public LanguageEmacsExtension() {
|
||||
super(EP_NAME, new DefaultEmacsProcessingHandler());
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.completion.CompletionLookupArranger;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
|
||||
import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler;
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
@@ -124,6 +125,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
private JLabel mySortingLabel;
|
||||
private final JScrollPane myScrollPane;
|
||||
private JButton myScrollBarIncreaseButton;
|
||||
private boolean myStartCompletionWhenNothingMatches;
|
||||
|
||||
public LookupImpl(Project project, Editor editor, @NotNull LookupArranger arranger){
|
||||
super(new JPanel(new BorderLayout()));
|
||||
@@ -328,6 +330,13 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
myFrozenItems.clear();
|
||||
refreshUi();
|
||||
ensureSelectionVisible();
|
||||
if (myStartCompletionWhenNothingMatches && myList.getModel().getSize() == 1 && myList.getModel().getElementAt(0) instanceof EmptyLookupItem) {
|
||||
CompletionAutoPopupHandler.scheduleAutoPopup(myProject, myEditor, getPsiFile());
|
||||
}
|
||||
}
|
||||
|
||||
public void setStartCompletionWhenNothingMatches(boolean startCompletionWhenNothingMatches) {
|
||||
myStartCompletionWhenNothingMatches = startCompletionWhenNothingMatches;
|
||||
}
|
||||
|
||||
private void ensureSelectionVisible() {
|
||||
|
||||
@@ -113,6 +113,9 @@ public class LookupManagerImpl extends LookupManager {
|
||||
|
||||
final LookupImpl lookup = createLookup(editor, items, prefix, arranger);
|
||||
lookup.show();
|
||||
if (CodeInsightSettings.getInstance().AUTO_POPUP_COMPLETION_LOOKUP) {
|
||||
lookup.setStartCompletionWhenNothingMatches(true);
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -321,7 +321,7 @@ public class GlobalInspectionContextImpl extends UserDataHolderBase implements G
|
||||
new File(outputPath).mkdirs();
|
||||
final File file = new File(outputPath, toolName + ext);
|
||||
if (isLocalTool) {
|
||||
FileUtil.writeToFile(file, "</" + InspectionsBundle.message("inspection.problems") + ">");
|
||||
FileUtil.writeToFile(file, ("</" + InspectionsBundle.message("inspection.problems") + ">").getBytes("UTF-8"), true);
|
||||
}
|
||||
else {
|
||||
PathMacroManager.getInstance(getProject()).collapsePaths(doc.getRootElement());
|
||||
|
||||
@@ -285,7 +285,7 @@ public class ConsoleHistoryController {
|
||||
}
|
||||
|
||||
private void saveHistory(final XmlSerializer out) throws IOException {
|
||||
out.startDocument(System.getProperty(CharsetToolkit.FILE_ENCODING_PROPERTY), null);
|
||||
out.startDocument("UTF8", null);
|
||||
out.startTag(null, "console-history");
|
||||
out.attribute(null, "id", myId);
|
||||
for (String s : myModel.getHistory()) {
|
||||
|
||||
@@ -95,7 +95,9 @@ public class ConsoleBuffer {
|
||||
private int myDeferredOutputLength;
|
||||
|
||||
/**
|
||||
* Buffer for deferred stdin and stderr output.
|
||||
* Buffer for deferred stdin output.
|
||||
* <p/>
|
||||
* Is assumed to store user input data until it's delivered to the target process. That activity is driven from outside this class.
|
||||
*/
|
||||
private StringBuffer myDeferredUserInput = new StringBuffer();
|
||||
|
||||
@@ -201,6 +203,10 @@ public class ConsoleBuffer {
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
clear(true);
|
||||
}
|
||||
|
||||
public void clear(boolean clearUserInputAsWell) {
|
||||
if (myUseCyclicBuffer) {
|
||||
myDeferredOutput.clear();
|
||||
myDeferredOutput.add(new StringBuilder(myCyclicBufferUnitSize));
|
||||
@@ -212,8 +218,10 @@ public class ConsoleBuffer {
|
||||
}
|
||||
myDeferredOutputLength = 0;
|
||||
myDeferredTypes.clear();
|
||||
myDeferredUserInput = new StringBuffer();
|
||||
myDeferredTokens.clear();
|
||||
if (clearUserInputAsWell) {
|
||||
myDeferredUserInput = new StringBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -563,7 +563,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
addToken(deferredToken.getLength(), deferredToken.getHyperlinkInfo(), deferredToken.contentType);
|
||||
}
|
||||
deferredTokensSize = deferredTokens.size();
|
||||
myBuffer.clear();
|
||||
myBuffer.clear(false);
|
||||
}
|
||||
final Document document = myEditor.getDocument();
|
||||
final int oldLineCount = document.getLineCount();
|
||||
|
||||
@@ -96,30 +96,27 @@ public class FindUtil {
|
||||
}
|
||||
|
||||
public static void configureFindModel(boolean replace, Editor editor, FindModel model) {
|
||||
String selectedText = editor.getSelectionModel().getSelectedText();
|
||||
model.setReplaceState(replace);
|
||||
if (selectedText != null) {
|
||||
if (replace) {
|
||||
if (!StringUtil.isEmpty(selectedText)) {
|
||||
if (selectedText.indexOf('\n') >= 0) {
|
||||
model.setGlobal(false);
|
||||
}
|
||||
else {
|
||||
model.setStringToFind(selectedText);
|
||||
model.setGlobal(true);
|
||||
}
|
||||
} else {
|
||||
model.setGlobal(true);
|
||||
}
|
||||
} else {
|
||||
model.setStringToFind(selectedText);
|
||||
model.setGlobal(true);
|
||||
}
|
||||
final String selectedText = editor.getSelectionModel().getSelectedText();
|
||||
|
||||
if (model.isGlobal()) {
|
||||
model.setStringToFind(selectedText);
|
||||
boolean isGlobal = true;
|
||||
String stringToFind = null;
|
||||
if (!StringUtil.isEmpty(selectedText)) {
|
||||
if (selectedText.indexOf('\n') >= 0) {
|
||||
if (replace){
|
||||
isGlobal = false;
|
||||
stringToFind = model.getStringToFind();
|
||||
}
|
||||
}
|
||||
if (stringToFind == null) {
|
||||
stringToFind = selectedText;
|
||||
}
|
||||
} else {
|
||||
stringToFind = model.getStringToFind();
|
||||
}
|
||||
|
||||
model.setReplaceState(replace);
|
||||
model.setStringToFind(stringToFind);
|
||||
model.setGlobal(isGlobal);
|
||||
model.setPromptOnReplace(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.find.findUsages;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.usages.Usage;
|
||||
import com.intellij.util.Processor;
|
||||
|
||||
/**
|
||||
* @author gregsh
|
||||
*/
|
||||
public abstract class CustomUsageSearcher {
|
||||
public static final ExtensionPointName<CustomUsageSearcher> EP_NAME = ExtensionPointName.create("com.intellij.customUsageSearcher");
|
||||
|
||||
public abstract void processElementUsages(final PsiElement element, final Processor<Usage> processor, final FindUsagesOptions options);
|
||||
}
|
||||
@@ -380,6 +380,14 @@ public class FindUsagesManager implements JDOMExternalizable {
|
||||
}
|
||||
});
|
||||
handler.processElementUsages(element, usageInfoProcessor, options);
|
||||
for (CustomUsageSearcher searcher : Extensions.getExtensions(CustomUsageSearcher.EP_NAME)) {
|
||||
try {
|
||||
searcher.processElementUsages(element, processor, options);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Project project = ApplicationManager.getApplication().runReadAction(new Computable<Project>() {
|
||||
|
||||
@@ -97,7 +97,7 @@ class FindDialog extends DialogWrapper {
|
||||
private final FindModel myModel;
|
||||
private final Runnable myOkHandler;
|
||||
private FixedSizeButton mySelectDirectoryButton;
|
||||
private StateRestoringCheckBox useFileFilter;
|
||||
private StateRestoringCheckBox myUseFileFilter;
|
||||
private ComboBox myFileFilter;
|
||||
private JCheckBox myCbToSkipResultsWhenOneUsage;
|
||||
private final Project myProject;
|
||||
@@ -405,7 +405,7 @@ class FindDialog extends DialogWrapper {
|
||||
|
||||
myFileFilter = new ComboBox(100);
|
||||
initCombobox(myFileFilter);
|
||||
filterPanel.add(useFileFilter = createCheckbox(FindBundle.message("find.filter.file.mask.checkbox")),BorderLayout.WEST);
|
||||
filterPanel.add(myUseFileFilter = createCheckbox(FindBundle.message("find.filter.file.mask.checkbox")),BorderLayout.WEST);
|
||||
filterPanel.add(myFileFilter,BorderLayout.CENTER);
|
||||
myFileFilter.setEditable(true);
|
||||
String[] fileMasks = FindSettings.getInstance().getRecentFileMasks();
|
||||
@@ -414,10 +414,10 @@ class FindDialog extends DialogWrapper {
|
||||
}
|
||||
myFileFilter.setEnabled(false);
|
||||
|
||||
useFileFilter.addActionListener(
|
||||
myUseFileFilter.addActionListener(
|
||||
new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (!useFileFilter.isSelected()) {
|
||||
if (!myUseFileFilter.isSelected()) {
|
||||
myFileFilter.setEnabled(false);
|
||||
} else {
|
||||
myFileFilter.setEnabled(true);
|
||||
@@ -533,7 +533,7 @@ class FindDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
final String mask = myFileFilter == null ? null : (String)myFileFilter.getSelectedItem();
|
||||
final String mask = (myFileFilter == null || !myUseFileFilter.isSelected()) ? null : (String)myFileFilter.getSelectedItem();
|
||||
|
||||
if (mask != null) {
|
||||
if (mask.length() == 0) {
|
||||
@@ -1031,7 +1031,7 @@ class FindDialog extends DialogWrapper {
|
||||
model.setFindAll(findAll);
|
||||
|
||||
String mask = null;
|
||||
if (useFileFilter!=null && useFileFilter.isSelected()) {
|
||||
if (myUseFileFilter !=null && myUseFileFilter.isSelected()) {
|
||||
mask = (String)myFileFilter.getSelectedItem();
|
||||
}
|
||||
model.setFileFilter(mask);
|
||||
@@ -1109,7 +1109,7 @@ class FindDialog extends DialogWrapper {
|
||||
if (myModel.getFileFilter()!=null && myModel.getFileFilter().length() > 0) {
|
||||
myFileFilter.setSelectedItem(myModel.getFileFilter());
|
||||
myFileFilter.setEnabled(true);
|
||||
useFileFilter.setSelected(true);
|
||||
myUseFileFilter.setSelected(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+18
-4
@@ -138,7 +138,9 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
myLivePreviewAlarm.cancelAllRequests();
|
||||
if (findModel == null) return;
|
||||
final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode();
|
||||
final FindModel copy = (FindModel)findModel.clone();
|
||||
final FindModel copy = new FindModel();
|
||||
copy.copyFrom(findModel);
|
||||
|
||||
final ModalityState modalityState = ModalityState.current();
|
||||
Runnable request = new Runnable() {
|
||||
@Override
|
||||
@@ -219,9 +221,21 @@ public class LivePreviewControllerBase implements LivePreview.Delegate, FindUtil
|
||||
public void performReplaceAll(Editor e) {
|
||||
if (!Utils.ensureOkToWrite(e)) return;
|
||||
if (mySearchResults.getFindModel() != null) {
|
||||
FindUtil.replace(e.getProject(), e,
|
||||
mySearchResults.getFindModel().isGlobal() ? 0 : mySearchResults.getEditor().getSelectionModel().getSelectionStart(),
|
||||
mySearchResults.getFindModel(), this);
|
||||
final FindModel copy = new FindModel();
|
||||
copy.copyFrom(mySearchResults.getFindModel());
|
||||
|
||||
final SelectionModel selectionModel = mySearchResults.getEditor().getSelectionModel();
|
||||
|
||||
int offset;
|
||||
if (selectionModel.getSelectedText() != null) {
|
||||
offset = selectionModel.getSelectionStart();
|
||||
} else {
|
||||
offset = 0;
|
||||
copy.setGlobal(true);
|
||||
}
|
||||
|
||||
FindUtil.replace(e.getProject(), e, offset, copy, this);
|
||||
|
||||
if (myReplaceListener != null) {
|
||||
myReplaceListener.replaceAllPerformed(e);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user