Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraleon2013-04-30 15:59:16 +0000
committerMarc-Andre Laperle2013-04-30 18:26:00 +0000
commitbb755a01befd30c031965681aa8af8575bce52c5 (patch)
treef5b597f7cf5696b15c8e6481d8aa9586610a0605 /dsf/org.eclipse.cdt.dsf.ui/src
parentcf3acef3f302dfc538ac0895ab90e421bc23df2c (diff)
downloadorg.eclipse.cdt-bb755a01befd30c031965681aa8af8575bce52c5.tar.gz
org.eclipse.cdt-bb755a01befd30c031965681aa8af8575bce52c5.tar.xz
org.eclipse.cdt-bb755a01befd30c031965681aa8af8575bce52c5.zip
Bug 244865 – Support for Step Into Selection
First Implementation: * Non-stop as well as All-stop debugging * Function / Method name validation, arguments size validation (no arguments signature yet) * Ctrl-F5 as short key (consistent with JDT) * Hyper link support with Ctrl-Shift click * Junit Test (Services part) Change-Id: I58903b4b6b7f9fd39a827f5297ad23ac3f96186d Reviewed-on: https://git.eclipse.org/r/11305 Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com> IP-Clean: Marc-Andre Laperle <marc-andre.laperle@ericsson.com> Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Diffstat (limited to 'dsf/org.eclipse.cdt.dsf.ui/src')
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.java4
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.properties5
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/sourcelookup/DsfSourceSelectionResolver.java226
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/DsfStepIntoSelectionCommand.java195
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/DsfStepIntoSelectionHyperlinkDetector.java239
-rw-r--r--dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/IDsfStepIntoSelection.java36
6 files changed, 703 insertions, 2 deletions
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.java
index f28a4ab53a5..0761ffcf449 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.java
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2010 Wind River Systems, Inc. and others.
+ * Copyright (c) 2009, 2013 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* Wind River Systems - initial API and implementation
* Patrick Chuong (Texas Instruments) - Bug 315446: Invalid event breakpoint type (group) name
+ * Alvaro Sanchez-Leon (Ericsson AB) - Support for Step into selection (bug 244865)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui;
@@ -16,6 +17,7 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
public static String ToggleBreakpointsTargetFactory_description;
public static String ToggleBreakpointsTargetFactory_name;
+ public static String DsfUIStepIntoEditorSelection;
static {
// initialize resource bundle
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.properties b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.properties
index 1faea82e179..37451dbd583 100644
--- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.properties
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/Messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2009, 2010 Wind River Systems and others.
+# Copyright (c) 2009, 2013 Wind River Systems and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
@@ -8,7 +8,10 @@
# Contributors:
# Wind River Systems - initial API and implementation
# Ericsson - added Tracepoint support
+# Ericsson - added Step into selection support
###############################################################################
ToggleBreakpointsTargetFactory_description=Standard C/C++ breakpoint type.
ToggleBreakpointsTargetFactory_name=C/C++ Breakpoints
+
+DsfUIStepIntoEditorSelection=Step Into
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/sourcelookup/DsfSourceSelectionResolver.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/sourcelookup/DsfSourceSelectionResolver.java
new file mode 100644
index 00000000000..aa1f5ab0657
--- /dev/null
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/sourcelookup/DsfSourceSelectionResolver.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Ericsson AB and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alvaro Sanchez-Leon (Ericsson AB) - Support for Step into selection (bug 244865)
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.debug.internal.ui.sourcelookup;
+
+import org.eclipse.cdt.core.model.IFunctionDeclaration;
+import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils;
+import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
+import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.internal.ui.editor.SelectionToDeclarationJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class DsfSourceSelectionResolver implements Runnable {
+ private ITextEditor fEditorPage = null;
+ private ITextSelection fSelection = null;
+ private LineLocation fLineLocation = new LineLocation();
+ private IFunctionDeclaration fFunction = null;
+ private boolean fSuccessful = false;
+
+ public class LineLocation {
+ private String fileName = null;
+ private int lineNumber = 0;
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ public void setLineNumber(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+ }
+
+ private interface ResolveEditorRunnable extends Runnable {
+ TextEditor getEditor();
+ }
+
+ public DsfSourceSelectionResolver() {
+
+ }
+
+ public DsfSourceSelectionResolver(ITextEditor editor, ITextSelection selection) {
+ fEditorPage = editor;
+ fSelection = selection;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.dsf.debug.internal.ui.sourcelookup.IDsfSourceSelectionResolver#run()
+ */
+ @Override
+ public void run() {
+ fEditorPage = resolveEditor();
+ if (fEditorPage != null) {
+ ITextSelection selection = resolveSelection();
+ if (selection != null) {
+ IFunctionDeclaration[] selectedFunctions = resolveSelectedFunction(selection);
+
+ IFunctionDeclaration selFunction = null;
+ if (selectedFunctions == null || selectedFunctions.length != 1 || selectedFunctions[0] == null) {
+ //Unable to resolve selection to a function
+ return;
+ } else {
+ // Continue as expected
+ selFunction = selectedFunctions[0];
+ }
+
+ LineLocation selectedLine = resolveSelectedLine();
+ if (selectedLine == null) {
+ // Unable to resolve the selected line
+ return;
+ }
+
+ fLineLocation = selectedLine;
+ fFunction = selFunction;
+ fSuccessful = true;
+ }
+ }
+ }
+
+ public ITextEditor resolveEditor() {
+ if (fEditorPage != null) {
+ return fEditorPage;
+ }
+
+ final IWorkbench wb = DsfUIPlugin.getDefault().getWorkbench();
+ // Run in UI thread to access UI resources
+ ResolveEditorRunnable reditorRunnable = new ResolveEditorRunnable() {
+ TextEditor result = null;
+
+ @Override
+ public void run() {
+ IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
+ if (win == null || win.getActivePage() == null || win.getActivePage().getActiveEditor() == null) {
+ result = null;
+ } else {
+ IEditorPart editorPart = win.getActivePage().getActiveEditor();
+ if (editorPart instanceof CEditor) {
+ result = (TextEditor) win.getActivePage().getActiveEditor();
+ }
+ }
+ }
+
+ @Override
+ public TextEditor getEditor() {
+ return result;
+ }
+ };
+
+ Display.getDefault().syncExec(reditorRunnable);
+ return reditorRunnable.getEditor();
+ }
+
+ private LineLocation resolveSelectedLine() {
+ String errorMessage = ""; //$NON-NLS-1$
+ IEditorInput input = fEditorPage.getEditorInput();
+ if (input == null) {
+ errorMessage = "Invalid Editor input on selection"; //$NON-NLS-1$
+ } else {
+ IDocument document = fEditorPage.getDocumentProvider().getDocument(input);
+ if (document == null) {
+ errorMessage = "Invalid Editor Document input on selection"; //$NON-NLS-1$
+ } else {
+ ITextSelection selection = resolveSelection();
+ if (selection == null) {
+ errorMessage = "Invalid selection. Only textual selections are supported"; //$NON-NLS-1$
+ } else {
+ String fileName = null;
+ try {
+ fileName = CDebugUIUtils.getEditorFilePath(input);
+ } catch (CoreException e) {
+ // unable to resolve the path
+ DsfUIPlugin.log(e);
+ return null;
+ }
+
+ if (fileName == null) {
+ errorMessage = "Unable to resolve fileName from selection"; //$NON-NLS-1$
+ DsfUIPlugin.logErrorMessage(errorMessage);
+ } else {
+ // Resolve the values
+ LineLocation lineLocation = new LineLocation();
+
+ lineLocation.setFileName(fileName);
+ lineLocation.setLineNumber(selection.getStartLine() + 1);
+ return lineLocation;
+ }
+ }
+ }
+ }
+
+ DsfUIPlugin.logErrorMessage(errorMessage);
+ return null;
+ }
+
+ public ITextSelection resolveSelection() {
+ if (fSelection != null) {
+ //Value received at construction time
+ return fSelection;
+ }
+
+ ISelection selection = fEditorPage.getEditorSite().getSelectionProvider().getSelection();
+ if (selection instanceof ITextSelection) {
+ return (ITextSelection) selection;
+ }
+
+ return null;
+ }
+
+ private IFunctionDeclaration[] resolveSelectedFunction(ITextSelection textSelection) {
+ if (textSelection != null) {
+ SelectionToDeclarationJob job;
+ try {
+ job = new SelectionToDeclarationJob(fEditorPage, textSelection);
+ job.schedule();
+ job.join();
+ } catch (CoreException e1) {
+ DsfUIPlugin.log(e1);
+ return null;
+ } catch (InterruptedException e) {
+ DsfUIPlugin.log(e);
+ return null;
+ }
+
+ //fetch the result
+ return job.getSelectedFunctions();
+ }
+
+ return null;
+ }
+
+ public LineLocation getLineLocation() {
+ return fLineLocation;
+ }
+
+ public IFunctionDeclaration getFunction() {
+ return fFunction;
+ }
+
+ public boolean isSuccessful() {
+ return fSuccessful;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/DsfStepIntoSelectionCommand.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/DsfStepIntoSelectionCommand.java
new file mode 100644
index 00000000000..7ec6ce2e0bb
--- /dev/null
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/DsfStepIntoSelectionCommand.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Ericsson AB and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alvaro Sanchez-Leon (Ericsson AB) - Support for Step into selection (bug 244865)
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.debug.ui.actions;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.eclipse.cdt.core.model.IFunctionDeclaration;
+import org.eclipse.cdt.debug.core.model.IStepIntoSelectionHandler;
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
+import org.eclipse.cdt.dsf.concurrent.Query;
+import org.eclipse.cdt.dsf.datamodel.DMContexts;
+import org.eclipse.cdt.dsf.debug.internal.ui.sourcelookup.DsfSourceSelectionResolver;
+import org.eclipse.cdt.dsf.debug.internal.ui.sourcelookup.DsfSourceSelectionResolver.LineLocation;
+import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.cdt.dsf.debug.service.IRunControl3;
+import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
+import org.eclipse.cdt.dsf.service.DsfServicesTracker;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.IRequest;
+import org.eclipse.debug.core.commands.AbstractDebugCommand;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @since 2.4
+ */
+public class DsfStepIntoSelectionCommand extends AbstractDebugCommand implements IStepIntoSelectionHandler, IDsfStepIntoSelection {
+ private final DsfServicesTracker fTracker;
+ public DsfStepIntoSelectionCommand(DsfSession session) {
+ fTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
+ }
+
+ public void dispose() {
+ fTracker.dispose();
+ }
+
+ @Override
+ protected void doExecute(Object[] targets, IProgressMonitor monitor, IRequest request) throws CoreException {
+ // No multiple selections allowed for Step into selection
+ if (targets.length != 1) {
+ return;
+ }
+
+ final IExecutionDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext) targets[0]).getDMContext(), IExecutionDMContext.class);
+ if (dmc == null) {
+ return;
+ }
+
+ DsfSourceSelectionResolver resolveSelection = new DsfSourceSelectionResolver();
+ // Resolve UI selection from the the UI thread
+ Display.getDefault().syncExec(resolveSelection);
+ if (resolveSelection.isSuccessful()) {
+ LineLocation location = resolveSelection.getLineLocation();
+ runToSelection(location.getFileName(), location.getLineNumber(), resolveSelection.getFunction(), dmc);
+ } else {
+ DsfUIPlugin.debug("DSfStepIntoSelectionCommand: Unable to resolve a selected function"); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ protected boolean isExecutable(Object[] targets, IProgressMonitor monitor, IEnabledStateRequest request) throws CoreException {
+ // No multiple selections allowed for Step into selection
+ if (targets.length != 1) {
+ return false;
+ }
+
+ final IExecutionDMContext dmc = DMContexts.getAncestorOfType(((IDMVMContext) targets[0]).getDMContext(), IExecutionDMContext.class);
+ if (dmc == null) {
+ return false;
+ }
+
+ return isExecutable(dmc, fTracker);
+ }
+
+ private boolean isExecutable(final IExecutionDMContext dmc, final DsfServicesTracker tracker) {
+ final DsfSession session = DsfSession.getSession(dmc.getSessionId());
+ if (session != null && session.isActive()) {
+ try {
+ Query<Boolean> query = new Query<Boolean>() {
+ @Override
+ protected void execute(DataRequestMonitor<Boolean> rm) {
+ IRunControl3 runControl = tracker.getService(IRunControl3.class);
+ if (runControl != null) {
+ // The selection may not be up to date, this is indicated with
+ // the selectedFunction being set to null
+ runControl.canStepIntoSelection(dmc, null, 0, null, rm);
+ } else {
+ rm.setData(false);
+ rm.done();
+ }
+ }
+ };
+
+ session.getExecutor().execute(query);
+ return query.get();
+ } catch (InterruptedException e) {
+ } catch (ExecutionException e) {
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ protected Object getTarget(Object element) {
+ if (element instanceof IDMVMContext) {
+ return element;
+ }
+ return null;
+ }
+
+ @Override
+ protected boolean isRemainEnabled(IDebugCommandRequest request) {
+ return true;
+ }
+
+ @Override
+ public boolean isExecutable(final IExecutionDMContext dmc) {
+ if (dmc == null) {
+ return false;
+ }
+
+ DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), dmc.getSessionId());
+ boolean result = isExecutable(dmc, tracker);
+ tracker.dispose();
+ return result;
+ }
+
+ @Override
+ public void runToSelection(final String fileName, final int lineLocation, final IFunctionDeclaration selectedFunction, final IExecutionDMContext dmc) {
+ final DsfSession session = DsfSession.getSession(dmc.getSessionId());
+ if (session != null && session.isActive()) {
+ Throwable exception = null;
+ try {
+ Query<Object> query = new Query<Object>() {
+ @Override
+ protected void execute(final DataRequestMonitor<Object> rm) {
+ DsfServicesTracker tracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId());
+
+ boolean skipBreakpoints = DebugUITools.getPreferenceStore().getBoolean(IDebugUIConstants.PREF_SKIP_BREAKPOINTS_DURING_RUN_TO_LINE);
+
+ IRunControl3 runControl = tracker.getService(IRunControl3.class);
+ tracker.dispose();
+ StringBuilder eMessage = null;
+ if (runControl != null) {
+ runControl.stepIntoSelection(dmc, fileName, lineLocation, skipBreakpoints, selectedFunction, rm);
+ return;
+ } else {
+ eMessage = new StringBuilder("IRunControl3 service not available"); //$NON-NLS-1$
+ }
+
+ // Either runControl is null or an Exception has occurred
+ rm.setStatus(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, IDsfStatusConstants.NOT_SUPPORTED, eMessage.toString(), null));
+ rm.done();
+ }
+ };
+
+ session.getExecutor().execute(query);
+ query.get();
+ } catch (RejectedExecutionException e) {
+ exception = e;
+ } catch (InterruptedException e) {
+ exception = e;
+ } catch (ExecutionException e) {
+ exception = e;
+ }
+
+ if (exception != null) {
+ DsfUIPlugin.log(new DebugException(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Failed executing Step into Selection", exception)));//$NON-NLS-1$
+ }
+ } else {
+ DsfUIPlugin.log(new DebugException(new Status(IStatus.ERROR, DsfUIPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Debug session is not active", null))); //$NON-NLS-1$
+ }
+ }
+
+}
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/DsfStepIntoSelectionHyperlinkDetector.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/DsfStepIntoSelectionHyperlinkDetector.java
new file mode 100644
index 00000000000..5c2a5a09d03
--- /dev/null
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/DsfStepIntoSelectionHyperlinkDetector.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Ericsson AB and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alvaro Sanchez-Leon (Ericsson AB) - Support for Step into selection (bug 244865)
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.debug.ui.actions;
+
+import org.eclipse.cdt.core.model.ICLanguageKeywords;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.IWorkingCopy;
+import org.eclipse.cdt.dsf.datamodel.DMContexts;
+import org.eclipse.cdt.dsf.datamodel.IDMContext;
+import org.eclipse.cdt.dsf.debug.internal.ui.Messages;
+import org.eclipse.cdt.dsf.debug.internal.ui.sourcelookup.DsfSourceSelectionResolver;
+import org.eclipse.cdt.dsf.debug.internal.ui.sourcelookup.DsfSourceSelectionResolver.LineLocation;
+import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
+import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
+import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.internal.ui.text.CWordFinder;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.text.ICPartitions;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextSelection;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
+import org.eclipse.jface.text.hyperlink.IHyperlink;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * @since 2.4
+ *
+ */
+public class DsfStepIntoSelectionHyperlinkDetector extends AbstractHyperlinkDetector {
+ private class DsfStepIntoSelectionHyperlink implements IHyperlink {
+
+ private ITextSelection fSelection = null;
+ private IDsfStepIntoSelection fStepIntoSelectionCommand = null;
+ private DsfSourceSelectionResolver fSelectionResolver = null;
+
+ /**
+ * Constructor
+ *
+ * @param stepIntoSelectionCommand
+ * @param region
+ */
+ public DsfStepIntoSelectionHyperlink(DsfSourceSelectionResolver selectionResolver, IDsfStepIntoSelection stepIntoSelectionCommand) {
+ fSelection = selectionResolver.resolveSelection();
+ fStepIntoSelectionCommand = stepIntoSelectionCommand;
+ fSelectionResolver = selectionResolver;
+ }
+
+ /**
+ * @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkRegion()
+ */
+ @Override
+ public IRegion getHyperlinkRegion() {
+ return new Region(fSelection.getOffset(), fSelection.getLength());
+ }
+
+ /**
+ * @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkText()
+ */
+ @Override
+ public String getHyperlinkText() {
+ return Messages.DsfUIStepIntoEditorSelection;
+ }
+
+ /**
+ * @see org.eclipse.jface.text.hyperlink.IHyperlink#getTypeLabel()
+ */
+ @Override
+ public String getTypeLabel() {
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.jface.text.hyperlink.IHyperlink#open()
+ */
+ @Override
+ public void open() {
+ // Resolve the debug context
+ final IExecutionDMContext dmc = resolveDebugContext();
+ if (fSelectionResolver.isSuccessful() && dmc != null) {
+ LineLocation location = fSelectionResolver.getLineLocation();
+ fStepIntoSelectionCommand.runToSelection(location.getFileName(), location.getLineNumber(), fSelectionResolver.getFunction(), dmc);
+ } else {
+ String message = null;
+ if (dmc == null) {
+ message = "DSfStepIntoSelection: Unable to resolve the debug context"; //$NON-NLS-1$
+ } else {
+ message = "DSfStepIntoSelection: Unable to resolve a selected function"; //$NON-NLS-1$
+ }
+ DsfUIPlugin.debug(message);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion, boolean)
+ */
+ @Override
+ public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion region, boolean canShowMultipleHyperlinks) {
+ // Only valid in the context of a selection within the CEditor
+ ITextEditor editor = (ITextEditor) getAdapter(ITextEditor.class);
+ if (editor == null || region == null || !(editor instanceof CEditor))
+ return null;
+
+ ITextSelection selection = resolveSelection(editor, region);
+ if (selection == null) {
+ return null;
+ }
+
+ // Shall only enable hyper link step into selection within a cdt debug execution context
+ IExecutionDMContext dmc = resolveDebugContext();
+ if (dmc == null) {
+ return null;
+ }
+
+ final DsfSession session = DsfSession.getSession(dmc.getSessionId());
+ if (session == null || !session.isActive()) {
+ return null;
+ }
+
+ IDsfStepIntoSelection stepIntoSelectionCommand = (IDsfStepIntoSelection) session.getModelAdapter(IDsfStepIntoSelection.class);
+ if (stepIntoSelectionCommand == null) {
+ return null;
+ }
+
+ if (!stepIntoSelectionCommand.isExecutable(dmc)) {
+ return null;
+ }
+
+ DsfSourceSelectionResolver functionResolver = new DsfSourceSelectionResolver(editor, selection);
+ functionResolver.run();
+ // Resolve to a selected function
+ if (!functionResolver.isSuccessful()) {
+ // We are not pointing to a valid function
+ return null;
+ }
+
+ return new IHyperlink[] { new DsfStepIntoSelectionHyperlink(functionResolver, stepIntoSelectionCommand) };
+ }
+
+ private ITextSelection resolveSelection(ITextEditor editor, IRegion region) {
+ ITextSelection selection = null;
+ if (editor != null) {
+ IDocument document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
+ final IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
+
+ if (document != null && workingCopy != null) {
+ // Check partition type.
+ String partitionType;
+ try {
+ partitionType = TextUtilities.getContentType(document, ICPartitions.C_PARTITIONING, region.getOffset(), false);
+ if (IDocument.DEFAULT_CONTENT_TYPE.equals(partitionType)) {
+ // Regular code i.e. Not a Preprocessor directive.
+ IRegion wregion = getIdentifier(document, region.getOffset(), workingCopy.getLanguage());
+ if (wregion != null) {
+ selection = new TextSelection(document, wregion.getOffset(), wregion.getLength());
+ }
+ }
+ } catch (BadLocationException e) {
+ // Ignore to return null
+ } catch (CoreException e) {
+ // Ignore to return null
+ }
+ }
+ }
+
+ return selection;
+ }
+
+ /**
+ * Returns the identifier at the given offset, or {@code null} if the there is no identifier at the offset.
+ */
+ private static IRegion getIdentifier(IDocument document, int offset, ILanguage language) throws BadLocationException {
+ @SuppressWarnings("restriction")
+ IRegion wordRegion = CWordFinder.findWord(document, offset);
+ if (wordRegion != null && wordRegion.getLength() > 0) {
+ String word = document.get(wordRegion.getOffset(), wordRegion.getLength());
+ if (!Character.isDigit(word.charAt(0)) && !isLanguageKeyword(language, word)) {
+ return wordRegion;
+ }
+ }
+ return null;
+ }
+
+ private static boolean isLanguageKeyword(ILanguage lang, String word) {
+ ICLanguageKeywords keywords = (ICLanguageKeywords) lang.getAdapter(ICLanguageKeywords.class);
+ if (keywords != null) {
+ for (String keyword : keywords.getKeywords()) {
+ if (keyword.equals(word))
+ return true;
+ }
+ for (String type : keywords.getBuiltinTypes()) {
+ if (type.equals(word))
+ return true;
+ }
+ for (String keyword : keywords.getPreprocessorKeywords()) {
+ if (keyword.charAt(0) == '#' && keyword.length() == word.length() + 1 && keyword.regionMatches(1, word, 0, word.length())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private IExecutionDMContext resolveDebugContext() {
+ IExecutionDMContext execContext = null;
+ IAdaptable adaptableContext = DebugUITools.getDebugContext();
+ IDMContext debugContext = null;
+ if (adaptableContext instanceof IDMVMContext) {
+ debugContext = ((IDMVMContext) adaptableContext).getDMContext();
+ }
+
+ if (debugContext != null) {
+ execContext = DMContexts.getAncestorOfType(debugContext, IExecutionDMContext.class);
+ }
+
+ return execContext;
+ }
+}
diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/IDsfStepIntoSelection.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/IDsfStepIntoSelection.java
new file mode 100644
index 00000000000..43ca6cd11c3
--- /dev/null
+++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/actions/IDsfStepIntoSelection.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2013 Ericsson AB and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alvaro Sanchez-Leon (Ericsson AB) - Support for Step into selection (bug 244865)
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.debug.ui.actions;
+
+import org.eclipse.cdt.core.model.IFunctionDeclaration;
+import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
+
+/**
+ * @since 2.4
+ */
+public interface IDsfStepIntoSelection {
+
+ /**
+ * Checks if within a state to perform step into selection
+ * @param dmc
+ * @return
+ */
+ public boolean isExecutable(final IExecutionDMContext dmc);
+
+ /**
+ * Carries out the actual step into selection action to the specified function location
+ * @param fileName
+ * @param lineLocation
+ * @param selectedFunction
+ * @param context
+ */
+ public void runToSelection(final String fileName, final int lineLocation, final IFunctionDeclaration selectedFunction, final IExecutionDMContext context);
+}

Back to the top