Skip to content

Commit

Permalink
[NETBEANS-2843] PHP debugger - support for resolved breakpoints
Browse files Browse the repository at this point in the history
https://issues.apache.org/jira/browse/NETBEANS-2843

- Adds PHP debugger option to enable/disable support of resolved breakpoints in Xdebug.
- Adds new Xdebug feature 'resolved_breakpoints'.
- Requests use of resolved breakpoints during debug session initialization.
- Supported by XDebug 2.8 or newer.
  • Loading branch information
KacerCZ committed Jan 17, 2021
1 parent 4d92aa6 commit 5ded696
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 52 deletions.
2 changes: 1 addition & 1 deletion php/php.dbgp/manifest.mf
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ AutoUpdate-Show-In-Client: false
OpenIDE-Module: org.netbeans.modules.php.dbgp
OpenIDE-Module-Layer: org/netbeans/modules/php/dbgp/resources/layer.xml
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/php/dbgp/resources/Bundle.properties
OpenIDE-Module-Specification-Version: 1.52
OpenIDE-Module-Specification-Version: 1.53

2 changes: 1 addition & 1 deletion php/php.dbgp/nbproject/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>2.87</specification-version>
<specification-version>2.149</specification-version>
</run-dependency>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* @author Radek Matous
*/
public class DebuggerOptions {

private static final DebuggerOptions GLOBAL_INSTANCE = new DefaultGlobal();
int port = -1;
int maxData = -2;
Expand Down Expand Up @@ -53,11 +54,11 @@ public Pair<String, Integer> getDebugProxy() {
}

public int getPort() {
return (port != -1) ? port : getGlobalInstance().getPort();
return (port != -1) ? port : getGlobalInstance().getPort();
}

public int getMaxData() {
return (maxData != -2) ? maxData : getGlobalInstance().getMaxData();
return (maxData != -2) ? maxData : getGlobalInstance().getMaxData();
}

public int getMaxChildren() {
Expand All @@ -79,6 +80,11 @@ public boolean showRequestedUrls() {
public boolean showDebuggerConsole() {
return getGlobalInstance().showDebuggerConsole();
}

public boolean resolveBreakpoints() {
return getGlobalInstance().resolveBreakpoints();
}

public boolean isDebuggerStoppedAtTheFirstLine() {
return getGlobalInstance().isDebuggerStoppedAtTheFirstLine();
}
Expand All @@ -92,6 +98,7 @@ public String getProjectEncoding() {
}

private static class DefaultGlobal extends DebuggerOptions {

public DefaultGlobal() {
}

Expand Down Expand Up @@ -130,6 +137,11 @@ public boolean showDebuggerConsole() {
return PhpOptions.getInstance().isDebuggerShowDebuggerConsole();
}

@Override
public boolean resolveBreakpoints() {
return PhpOptions.getInstance().isDebuggerResolveBreakpoints();
}

@Override
public boolean isDebuggerStoppedAtTheFirstLine() {
return PhpOptions.getInstance().isDebuggerStoppedAtTheFirstLine();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*
*/
public class FeatureGetCommand extends DbgpCommand {

public enum Feature {
LANGUAGE_SUPPORTS_THREADS,
LANGUAGE_NAME,
Expand All @@ -42,6 +43,7 @@ public enum Feature {
SUPPORTS_POSTMORTEM,
SHOW_HIDDEN,
NOTIFY_OK,
RESOLVED_BREAKPOINTS,
/*
* additional commands that could be supported
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
*
*/
public class InitMessage extends DbgpMessage {

private static final String IDEKEY = "idekey"; // NOI18N
private static final String FILE = "fileuri"; // NOI18N

Expand All @@ -53,6 +54,7 @@ public String getFileUri() {
public void process(DebugSession session, DbgpCommand command) {
setId(session);
setShowHidden(session);
setBreakpointResolution(session);
setMaxDepth(session);
setMaxChildren(session);
setMaxDataSize(session);
Expand Down Expand Up @@ -80,6 +82,12 @@ private void setShowHidden(DebugSession session) {
setFeature(session, Feature.SHOW_HIDDEN, "1"); //NOI18N
}

private void setBreakpointResolution(DebugSession session) {
if (DebuggerOptions.getGlobalInstance().resolveBreakpoints()) {
setFeature(session, Feature.RESOLVED_BREAKPOINTS, "1"); // NOI18N
}
}

private void setMaxDepth(DebugSession session) {
setFeature(session, Feature.MAX_DEPTH, String.valueOf(DebuggerOptions.getGlobalInstance().getMaxStructuresDepth()));
}
Expand Down
2 changes: 1 addition & 1 deletion php/php.project/manifest.mf
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
AutoUpdate-Show-In-Client: false
OpenIDE-Module-Specification-Version: 2.148
OpenIDE-Module-Specification-Version: 2.149
OpenIDE-Module: org.netbeans.modules.php.project
OpenIDE-Module-Layer: org/netbeans/modules/php/project/resources/layer.xml
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/php/project/resources/Bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public final class PhpOptions {
public static final String PROP_PHP_DEBUGGER_MAX_CHILDREN = "propPhpDebuggerMaxChildren"; // NOI18N
public static final String PROP_PHP_DEBUGGER_SHOW_URLS = "propPhpDebuggerShowUrls"; // NOI18N
public static final String PROP_PHP_DEBUGGER_SHOW_CONSOLE = "propPhpDebuggerShowConsole"; // NOI18N
public static final String PROP_PHP_DEBUGGER_RESOLVE_BREAKPOINTS = "propPhpDebuggerResolveBreakpoints"; // NOI18N
public static final String PROP_PHP_GLOBAL_INCLUDE_PATH = "propPhpGlobalIncludePath"; // NOI18N

private static final PhpOptions INSTANCE = new PhpOptions();
Expand Down Expand Up @@ -75,6 +76,8 @@ public void preferenceChange(PreferenceChangeEvent evt) {
propertyChangeSupport.firePropertyChange(PROP_PHP_DEBUGGER_SHOW_URLS, null, Boolean.valueOf(newValue));
} else if (PHP_DEBUGGER_SHOW_CONSOLE.equals(key)) {
propertyChangeSupport.firePropertyChange(PROP_PHP_DEBUGGER_SHOW_CONSOLE, null, Boolean.valueOf(newValue));
} else if (PHP_DEBUGGER_RESOLVE_BREAKPOINTS.equals(key)) {
propertyChangeSupport.firePropertyChange(PROP_PHP_DEBUGGER_RESOLVE_BREAKPOINTS, null, Boolean.valueOf(newValue));
} else if (PHP_GLOBAL_INCLUDE_PATH.equals(key)) {
propertyChangeSupport.firePropertyChange(PROP_PHP_GLOBAL_INCLUDE_PATH, null, newValue);
}
Expand Down Expand Up @@ -185,6 +188,16 @@ public boolean isDebuggerShowDebuggerConsole() {
return getPhpOptions().isDebuggerShowConsole();
}

/**
* Check whether debugger requests breakpoint resolution. The default value is
* <code>{@value org.netbeans.modules.php.project.ui.options.PhpOptions#DEFAULT_DEBUGGER_RESOLVE_BREAKPOINTS}</code>.
* @return <code>true</code> if the debugger requests breakpoint resolution, <code>false</code> otherwise.
* @since 2.149
*/
public boolean isDebuggerResolveBreakpoints() {
return getPhpOptions().isDebuggerResolveBreakpoints();
}

/**
* Get the global PHP include path.
* @return the global PHP include path or an empty String if no folders are defined.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,5 @@ PhpDebuggerOptions.requestedUrlsCheckBox.AccessibleContext.accessibleName=Show R
PhpDebuggerPanel.sessionIdTextField.AccessibleContext.accessibleName=Debugger Session ID
PhpDebuggerPanel.maxStructuresDepthTextField.AccessibleContext.accessibleName=Maximum depth of structures
PhpDebuggerPanel.maxChildrenTextField.AccessibleContext.accessibleName=Maximum number of children
PhpDebuggerPanel.resolveBreakpointsCheckBox.text=&Resolve breakpoints
PhpDebuggerPanel.resolveBreakpointsInfoLabel.text=<html>With breakpoint resolution Xdebug tries to find the line with executable code to stop on.<br>\nThis feature is available in Xdebug version 2.8 or newer.</html>
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@
<Component id="requestedUrlsCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="debuggerConsoleCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="errorLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="portLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="sessionIdLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="maxDataLengthLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="portTextField" linkSize="2" min="-2" pref="50" max="-2" attributes="0"/>
<Component id="sessionIdTextField" min="-2" pref="176" max="-2" attributes="0"/>
<Component id="maxDataLengthTextField" linkSize="2" alignment="0" min="-2" pref="50" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="resolveBreakpointsCheckBox" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<EmptySpace min="21" pref="21" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
Expand All @@ -67,22 +81,7 @@
<Component id="maxStructuresDepthTextField" linkSize="2" alignment="0" min="-2" pref="50" max="-2" attributes="1"/>
</Group>
</Group>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="portLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="sessionIdLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="maxDataLengthLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="portTextField" linkSize="2" min="-2" pref="50" max="-2" attributes="0"/>
<Component id="sessionIdTextField" min="-2" pref="176" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="maxDataLengthTextField" linkSize="2" min="-2" pref="50" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="97" max="-2" attributes="0"/>
</Group>
<Component id="resolveBreakpointsInfoLabel" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
Expand Down Expand Up @@ -127,6 +126,10 @@
<Component id="debuggerConsoleCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="debuggerConsoleInfoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="resolveBreakpointsCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="resolveBreakpointsInfoLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="errorLabel" min="-2" max="-2" attributes="0"/>
</Group>
Expand Down Expand Up @@ -349,5 +352,19 @@
</Property>
</AccessibilityProperties>
</Component>
<Component class="javax.swing.JCheckBox" name="resolveBreakpointsCheckBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/netbeans/modules/php/project/ui/options/Bundle.properties" key="PhpDebuggerPanel.resolveBreakpointsCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="resolveBreakpointsInfoLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/netbeans/modules/php/project/ui/options/Bundle.properties" key="PhpDebuggerPanel.resolveBreakpointsInfoLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
@OptionsPanelController.Keywords(keywords={"php", "debugger", "debugging", "xdebug", "#KW_DebuggerOptions"}, location=UiUtils.OPTIONS_PATH, tabTitle= "#LBL_DebuggerOptions")
public class PhpDebuggerPanel extends JPanel {

private static final long serialVersionUID = 165768454654687L;
private static final long serialVersionUID = -6341327437203454463L;

private final ChangeSupport changeSupport = new ChangeSupport(this);
private final WatchesAndEvalListener watchesAndEvalListener;
Expand Down Expand Up @@ -149,6 +149,14 @@ public void setShowConsole(boolean showConsole) {
debuggerConsoleCheckBox.setSelected(showConsole);
}

public boolean isResolveBreakpoints() {
return resolveBreakpointsCheckBox.isSelected();
}

public void setResolveBreakpoints(boolean resolveBreakpoints) {
resolveBreakpointsCheckBox.setSelected(resolveBreakpoints);
}

public void setError(String message) {
errorLabel.setText(" "); // NOI18N
errorLabel.setForeground(UIManager.getColor("nb.errorForeground")); // NOI18N
Expand Down Expand Up @@ -198,6 +206,8 @@ private void initComponents() {
debuggerConsoleCheckBox = new JCheckBox();
debuggerConsoleInfoLabel = new JLabel();
errorLabel = new JLabel();
resolveBreakpointsCheckBox = new JCheckBox();
resolveBreakpointsInfoLabel = new JLabel();

portLabel.setLabelFor(portTextField);
Mnemonics.setLocalizedText(portLabel, NbBundle.getMessage(PhpDebuggerPanel.class, "PhpDebuggerPanel.portLabel.text")); // NOI18N
Expand Down Expand Up @@ -227,17 +237,31 @@ private void initComponents() {
errorLabel.setLabelFor(debuggerConsoleCheckBox);
Mnemonics.setLocalizedText(errorLabel, "ERROR"); // NOI18N

Mnemonics.setLocalizedText(resolveBreakpointsCheckBox, NbBundle.getMessage(PhpDebuggerPanel.class, "PhpDebuggerPanel.resolveBreakpointsCheckBox.text")); // NOI18N

Mnemonics.setLocalizedText(resolveBreakpointsInfoLabel, NbBundle.getMessage(PhpDebuggerPanel.class, "PhpDebuggerPanel.resolveBreakpointsInfoLabel.text")); // NOI18N

GroupLayout layout = new GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(Alignment.LEADING)
layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(stopAtTheFirstLineCheckBox)
.addComponent(watchesAndEvalCheckBox)
.addComponent(requestedUrlsCheckBox)
.addComponent(debuggerConsoleCheckBox)
.addComponent(errorLabel)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(portLabel)
.addComponent(sessionIdLabel)
.addComponent(maxDataLengthLabel))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(Alignment.LEADING, false)
.addComponent(portTextField, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE)
.addComponent(sessionIdTextField, GroupLayout.PREFERRED_SIZE, 176, GroupLayout.PREFERRED_SIZE)
.addComponent(maxDataLengthTextField, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE)))
.addComponent(resolveBreakpointsCheckBox)
.addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21)
.addGroup(layout.createParallelGroup(Alignment.LEADING)
Expand All @@ -249,26 +273,14 @@ private void initComponents() {
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(Alignment.LEADING, false)
.addComponent(maxChildrenTextField)
.addComponent(maxStructuresDepthTextField, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE)))))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(portLabel)
.addComponent(sessionIdLabel)
.addComponent(maxDataLengthLabel))
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(Alignment.LEADING, false)
.addComponent(portTextField, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE)
.addComponent(sessionIdTextField, GroupLayout.PREFERRED_SIZE, 176, GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createSequentialGroup()
.addComponent(maxDataLengthTextField, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE)
.addGap(97, 97, 97)))))
.addComponent(maxStructuresDepthTextField, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE)))
.addComponent(resolveBreakpointsInfoLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))))
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

layout.linkSize(SwingConstants.HORIZONTAL, new Component[] {maxChildrenTextField, maxDataLengthTextField, maxStructuresDepthTextField, portTextField});

layout.setVerticalGroup(
layout.createParallelGroup(Alignment.LEADING)
layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.BASELINE)
.addComponent(portLabel)
Expand Down Expand Up @@ -299,6 +311,10 @@ private void initComponents() {
.addComponent(debuggerConsoleCheckBox)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(debuggerConsoleInfoLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(resolveBreakpointsCheckBox)
.addPreferredGap(ComponentPlacement.RELATED)
.addComponent(resolveBreakpointsInfoLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(errorLabel))
);
Expand Down Expand Up @@ -349,6 +365,8 @@ private void initComponents() {
private JLabel portLabel;
private JTextField portTextField;
private JCheckBox requestedUrlsCheckBox;
private JCheckBox resolveBreakpointsCheckBox;
private JLabel resolveBreakpointsInfoLabel;
private JLabel sessionIdLabel;
private JTextField sessionIdTextField;
private JCheckBox stopAtTheFirstLineCheckBox;
Expand Down
Loading

0 comments on commit 5ded696

Please sign in to comment.