java-xbreakpoints: language selection support in condition and log expression

This commit is contained in:
Egor.Ushakov
2014-02-27 20:54:52 +04:00
parent c7b3ad387d
commit d3a084dd9b
8 changed files with 293 additions and 51 deletions
@@ -69,7 +69,10 @@ public final class TextWithImportsImpl implements TextWithImports{
}
private static Trinity<String, String, FileType> parseExternalForm(String s) {
String[] split = s.split(String.valueOf(DebuggerEditorImpl.SEPARATOR));
// when serialized into a tag special symbols are now kept as is
// so our separator \r may be converted to \n or \r\n
s = StringUtil.convertLineSeparators(s);
String[] split = s.split(String.valueOf('\n'));
return Trinity.create(split[0], split.length > 1 ? split[1] : "", split.length > 2 ? FileTypeManager.getInstance().getStdFileType(split[2]) : null);
}
@@ -244,12 +244,12 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
buf.append(getEventMessage(event));
buf.append("\n");
}
final TextWithImports expressionToEvaluate = getLogMessage();
if (myXBreakpoint.getLogExpression() != null && !expressionToEvaluate.getText().isEmpty()) {
if (isLogExpressionEnabled()) {
if(!debugProcess.isAttached()) {
return;
}
final TextWithImports expressionToEvaluate = getLogMessage();
try {
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(getProject(), new EvaluatingComputable<ExpressionEvaluator>() {
@Override
@@ -479,7 +479,11 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
}
protected boolean isLogExpressionEnabled() {
return myXBreakpoint.getLogExpression() != null;
String expression = myXBreakpoint.getLogExpression();
if (expression == null || expression.isEmpty()) {
return false;
}
return !getLogMessage().isEmpty();
}
@Override
@@ -588,7 +592,11 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
}
protected boolean isConditionEnabled() {
return myXBreakpoint.getCondition() != null && !myXBreakpoint.getCondition().isEmpty();
String condition = myXBreakpoint.getCondition();
if (condition == null || condition.isEmpty()) {
return false;
}
return !getCondition().isEmpty();
}
public void setCondition(String condition) {
@@ -1,16 +1,28 @@
package org.jetbrains.java.debugger;
import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
import com.intellij.debugger.engine.evaluation.TextWithImports;
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaCodeFragmentFactory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProviderBase;
import com.intellij.xdebugger.impl.breakpoints.ui.XDebuggerComboBoxProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
import javax.swing.*;
public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase implements XDebuggerComboBoxProvider {
@NotNull
@Override
public FileType getFileType() {
@@ -21,4 +33,72 @@ public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
protected PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical) {
return JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment(text, context, null, isPhysical);
}
@Override
public XBreakpointCustomPropertiesPanel<XBreakpoint<?>> createConditionComboBoxPanel(Project project,
XDebuggerEditorsProvider debuggerEditorsProvider,
String historyId,
XSourcePosition sourcePosition) {
return new ExpressionComboBoxPanel(project, historyId, sourcePosition) {
@Override
public void saveTo(@NotNull XBreakpoint<?> breakpoint) {
TextWithImports text = myComboBox.getText();
final String condition = StringUtil.nullize(text.toExternalForm(), true);
breakpoint.setCondition(condition);
if (condition != null) {
myComboBox.addRecent(text);
}
}
@Override
public void loadFrom(@NotNull XBreakpoint<?> breakpoint) {
myComboBox.setText(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, StringUtil.notNullize(breakpoint.getCondition())));
}
};
}
@Override
public XBreakpointCustomPropertiesPanel<XBreakpoint<?>> createLogExpressionComboBoxPanel(Project project,
XDebuggerEditorsProvider debuggerEditorsProvider,
String historyId,
XSourcePosition sourcePosition) {
return new ExpressionComboBoxPanel(project, historyId, sourcePosition) {
@Override
public void saveTo(@NotNull XBreakpoint<?> breakpoint) {
TextWithImports text = myComboBox.isEnabled() ? myComboBox.getText() : null;
breakpoint.setLogExpression(text != null ? text.toExternalForm() : null);
if (text != null) {
myComboBox.addRecent(text);
}
}
@Override
public void loadFrom(@NotNull XBreakpoint<?> breakpoint) {
myComboBox.setText(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, StringUtil.notNullize(breakpoint.getLogExpression())));
}
};
}
private abstract class ExpressionComboBoxPanel extends XBreakpointCustomPropertiesPanel<XBreakpoint<?>> {
protected final DebuggerExpressionComboBox myComboBox;
private ExpressionComboBoxPanel(Project project,
String historyId,
XSourcePosition sourcePosition) {
myComboBox = new DebuggerExpressionComboBox(project, historyId);
if (sourcePosition != null) {
PsiElement element = getContextElement(sourcePosition.getFile(), sourcePosition.getOffset(), project);
myComboBox.setContext(element);
}
else {
myComboBox.setContext(null);
}
}
@NotNull
@Override
public JComponent getComponent() {
return myComboBox;
}
}
}
@@ -0,0 +1,61 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.ui.XDebuggerExpressionComboBox;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @author egor
*/
public class DefaultConditionComboBoxPanel<B extends XBreakpoint<?>> extends XBreakpointCustomPropertiesPanel<B> {
private XDebuggerExpressionComboBox myConditionComboBox;
public DefaultConditionComboBoxPanel(Project project,
XDebuggerEditorsProvider debuggerEditorsProvider,
String historyId,
XSourcePosition sourcePosition) {
myConditionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, historyId, sourcePosition);
}
@NotNull
@Override
public JComponent getComponent() {
return myConditionComboBox.getComponent();
}
@Override
public void saveTo(@NotNull B breakpoint) {
final String condition = StringUtil.nullize(myConditionComboBox.getText(), true);
breakpoint.setCondition(condition);
if (condition != null) {
myConditionComboBox.saveTextInHistory();
}
}
@Override
public void loadFrom(@NotNull B breakpoint) {
myConditionComboBox.setText(StringUtil.notNullize(breakpoint.getCondition()));
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.ui.XDebuggerExpressionComboBox;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @author egor
*/
public class DefaultLogExpressionComboBoxPanel<B extends XBreakpoint<?>> extends XBreakpointCustomPropertiesPanel<B> {
private XDebuggerExpressionComboBox myLogExpressionComboBox;
public DefaultLogExpressionComboBoxPanel(Project project,
XDebuggerEditorsProvider debuggerEditorsProvider,
String historyId,
XSourcePosition sourcePosition) {
myLogExpressionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, historyId, sourcePosition);
}
@NotNull
@Override
public JComponent getComponent() {
return myLogExpressionComboBox.getComponent();
}
@Override
public void saveTo(@NotNull B breakpoint) {
String logExpression = myLogExpressionComboBox.getComponent().isEnabled() ? myLogExpressionComboBox.getText() : null;
breakpoint.setLogExpression(logExpression);
myLogExpressionComboBox.saveTextInHistory();
}
@Override
public void loadFrom(@NotNull B breakpoint) {
String logExpression = breakpoint.getLogExpression();
myLogExpressionComboBox.setText(logExpression != null ? logExpression : "");
}
}
@@ -19,9 +19,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.XDebuggerExpressionComboBox;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,7 +44,7 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
private JPanel myContentPane;
private JPanel myMainPanel;
private JCheckBox myTemporaryCheckBox;
private XDebuggerExpressionComboBox myLogExpressionComboBox;
XBreakpointCustomPropertiesPanel<B> logExpressionPanel;
public void init(Project project, XBreakpointManager breakpointManager, @NotNull B breakpoint, @Nullable XDebuggerEditorsProvider debuggerEditorsProvider) {
init(project, breakpointManager, breakpoint);
@@ -55,10 +55,18 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
}
};
myLogExpressionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, "breakpointLogExpression", myBreakpoint.getSourcePosition());
JComponent logExpressionComponent = myLogExpressionComboBox.getComponent();
if (debuggerEditorsProvider instanceof XDebuggerComboBoxProvider) {
logExpressionPanel = ((XDebuggerComboBoxProvider<B>)debuggerEditorsProvider).createLogExpressionComboBoxPanel(
project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
}
else {
logExpressionPanel =
new DefaultLogExpressionComboBoxPanel<B>(project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
}
JComponent logExpressionComponent = logExpressionPanel.getComponent();
myLogExpressionPanel.add(logExpressionComponent, BorderLayout.CENTER);
myLogExpressionComboBox.setEnabled(false);
logExpressionComponent.setEnabled(false);
myTemporaryCheckBox.setVisible(breakpoint instanceof XLineBreakpoint);
myLogExpressionCheckBox.addActionListener(listener);
DebuggerUIUtil.focusEditorOnCheck(myLogExpressionCheckBox, logExpressionComponent);
@@ -81,8 +89,8 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
}
private void onCheckboxChanged() {
if (myLogExpressionComboBox != null) {
myLogExpressionComboBox.setEnabled(myLogExpressionCheckBox.isSelected());
if (logExpressionPanel != null) {
logExpressionPanel.getComponent().setEnabled(myLogExpressionCheckBox.isSelected());
}
}
@@ -94,10 +102,9 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
myTemporaryCheckBox.setSelected(((XLineBreakpoint)myBreakpoint).isTemporary());
}
if (myLogExpressionComboBox != null) {
String logExpression = myBreakpoint.getLogExpression();
myLogExpressionCheckBox.setSelected(logExpression != null);
myLogExpressionComboBox.setText(logExpression != null ? logExpression : "");
if (logExpressionPanel != null) {
myLogExpressionCheckBox.setSelected(myBreakpoint.getLogExpression() != null);
logExpressionPanel.loadFrom(myBreakpoint);
}
onCheckboxChanged();
}
@@ -110,11 +117,8 @@ public class XBreakpointActionsPanel<B extends XBreakpoint<?>> extends XBreakpoi
((XLineBreakpoint)myBreakpoint).setTemporary(myTemporaryCheckBox.isSelected());
}
if (myLogExpressionComboBox != null) {
String logExpression = myLogExpressionCheckBox.isSelected() ? myLogExpressionComboBox.getText() : null;
myBreakpoint.setLogExpression(logExpression);
myLogExpressionComboBox.saveTextInHistory();
if (logExpressionPanel != null) {
logExpressionPanel.saveTo(myBreakpoint);
}
}
}
@@ -0,0 +1,37 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.project.Project;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
/**
* @author egor
*/
public interface XDebuggerComboBoxProvider<B extends XBreakpoint<?>> {
XBreakpointCustomPropertiesPanel<B> createConditionComboBoxPanel(Project project,
XDebuggerEditorsProvider debuggerEditorsProvider,
String historyId,
XSourcePosition sourcePosition);
XBreakpointCustomPropertiesPanel<B> createLogExpressionComboBoxPanel(Project project,
XDebuggerEditorsProvider debuggerEditorsProvider,
String historyId,
XSourcePosition sourcePosition);
}
@@ -16,7 +16,6 @@
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.popup.util.DetailView;
import com.intellij.xdebugger.breakpoints.XBreakpoint;
@@ -26,7 +25,6 @@ import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil;
import com.intellij.xdebugger.impl.ui.XDebuggerExpressionComboBox;
import javax.swing.*;
import java.awt.*;
@@ -83,8 +81,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
private List<XBreakpointPropertiesSubPanel<B>> mySubPanels = new ArrayList<XBreakpointPropertiesSubPanel<B>>();
private XDebuggerExpressionComboBox myConditionComboBox;
private B myBreakpoint;
public void setDetailView(DetailView detailView) {
@@ -106,10 +102,25 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
myActionsPanel.init(project, breakpointManager, breakpoint, debuggerEditorsProvider);
mySubPanels.add(myActionsPanel);
myCustomPanels = new ArrayList<XBreakpointCustomPropertiesPanel<B>>();
if (debuggerEditorsProvider != null) {
myConditionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
JComponent conditionComponent = myConditionComboBox.getComponent();
myConditionExpressionPanel.add(conditionComponent, BorderLayout.CENTER);
final XBreakpointCustomPropertiesPanel<B> conditionPanel;
if (debuggerEditorsProvider instanceof XDebuggerComboBoxProvider) {
conditionPanel = ((XDebuggerComboBoxProvider<B>)debuggerEditorsProvider).createConditionComboBoxPanel(
project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
}
else {
conditionPanel =
new DefaultConditionComboBoxPanel<B>(project, debuggerEditorsProvider, "breakpointCondition", myBreakpoint.getSourcePosition());
}
myConditionExpressionPanel.add(conditionPanel.getComponent(), BorderLayout.CENTER);
myCustomPanels.add(conditionPanel);
myMainPanel.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent event) {
IdeFocusManager.findInstance().requestFocus(conditionPanel.getComponent(), false);
}
});
} else {
myConditionPanel.setVisible(false);
}
@@ -121,7 +132,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
}
}
myCustomPanels = new ArrayList<XBreakpointCustomPropertiesPanel<B>>();
XBreakpointCustomPropertiesPanel<B> customPropertiesPanel = breakpointType.createCustomPropertiesPanel();
if (customPropertiesPanel != null) {
myCustomPropertiesPanelWrapper.add(customPropertiesPanel.getComponent(), BorderLayout.CENTER);
@@ -140,14 +150,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
myCustomPanels.add(customRightConditionPanel);
}
myMainPanel.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent event) {
if (myConditionComboBox != null) {
IdeFocusManager.findInstance().requestFocus(myConditionComboBox.getComponent(), false);
}
}
});
myEnabledCheckbox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
@@ -161,14 +163,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
panel.saveProperties();
}
if (myConditionComboBox != null) {
final String condition = StringUtil.nullize(myConditionComboBox.getText(), true);
myBreakpoint.setCondition(condition);
if (condition != null) {
myConditionComboBox.saveTextInHistory();
}
}
for (XBreakpointCustomPropertiesPanel<B> customPanel : myCustomPanels) {
customPanel.saveTo(myBreakpoint);
}
@@ -183,10 +177,6 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
panel.loadProperties();
}
if (myConditionComboBox != null) {
myConditionComboBox.setText(StringUtil.notNullize(myBreakpoint.getCondition()));
}
for (XBreakpointCustomPropertiesPanel<B> customPanel : myCustomPanels) {
customPanel.loadFrom(myBreakpoint);
}