mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-30 11:43:33 +02:00
Bug 294351 - Add debug hover support for DSF
This commit is contained in:
parent
f6f269dcf3
commit
695c6aab00
8 changed files with 472 additions and 303 deletions
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: %pluginName
|
Bundle-Name: %pluginName
|
||||||
Bundle-SymbolicName: org.eclipse.cdt.debug.ui; singleton:=true
|
Bundle-SymbolicName: org.eclipse.cdt.debug.ui; singleton:=true
|
||||||
Bundle-Version: 6.0.0.qualifier
|
Bundle-Version: 6.1.0.qualifier
|
||||||
Bundle-Activator: org.eclipse.cdt.debug.ui.CDebugUIPlugin
|
Bundle-Activator: org.eclipse.cdt.debug.ui.CDebugUIPlugin
|
||||||
Bundle-Vendor: %providerName
|
Bundle-Vendor: %providerName
|
||||||
Bundle-Localization: plugin
|
Bundle-Localization: plugin
|
||||||
|
@ -23,6 +23,7 @@ Export-Package:
|
||||||
org.eclipse.cdt.debug.ui.breakpointactions,
|
org.eclipse.cdt.debug.ui.breakpointactions,
|
||||||
org.eclipse.cdt.debug.ui.breakpoints,
|
org.eclipse.cdt.debug.ui.breakpoints,
|
||||||
org.eclipse.cdt.debug.ui.disassembly,
|
org.eclipse.cdt.debug.ui.disassembly,
|
||||||
|
org.eclipse.cdt.debug.ui.editors,
|
||||||
org.eclipse.cdt.debug.ui.importexecutable,
|
org.eclipse.cdt.debug.ui.importexecutable,
|
||||||
org.eclipse.cdt.debug.ui.sourcelookup
|
org.eclipse.cdt.debug.ui.sourcelookup
|
||||||
Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)",
|
Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)",
|
||||||
|
|
|
@ -7,181 +7,47 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
* Nokia - Refactored into CDI specific implementation of AbstractDebugTextHover
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.debug.internal.ui.editors;
|
package org.eclipse.cdt.debug.internal.ui.editors;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.debug.core.model.ICStackFrame;
|
import org.eclipse.cdt.debug.core.model.ICStackFrame;
|
||||||
import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils;
|
import org.eclipse.cdt.debug.ui.editors.AbstractDebugTextHover;
|
||||||
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
|
|
||||||
import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover;
|
|
||||||
import org.eclipse.core.runtime.IAdaptable;
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
import org.eclipse.debug.core.DebugException;
|
import org.eclipse.debug.core.DebugException;
|
||||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
|
||||||
import org.eclipse.jface.text.IDocument;
|
|
||||||
import org.eclipse.jface.text.IInformationControlCreator;
|
|
||||||
import org.eclipse.jface.text.IRegion;
|
|
||||||
import org.eclipse.jface.text.ITextHoverExtension;
|
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
|
||||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
|
||||||
import org.eclipse.ui.IEditorPart;
|
|
||||||
import org.eclipse.ui.IPartListener;
|
|
||||||
import org.eclipse.ui.ISelectionListener;
|
|
||||||
import org.eclipse.ui.IWorkbenchPage;
|
|
||||||
import org.eclipse.ui.IWorkbenchPart;
|
|
||||||
|
|
||||||
/* The class LanguageOperators protects some language specific
|
|
||||||
* operator information used by the DebugTextHover class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class LanguageOperators {
|
|
||||||
public String getAssignmentOperator() {
|
|
||||||
return "="; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getGreaterThanEqualToOperator() {
|
|
||||||
return ">="; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEqualToOperator() {
|
|
||||||
return "=="; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNotEqualToOperator() {
|
|
||||||
return "!="; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLessThenEqualToOperator() {
|
|
||||||
return "<="; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValueChangeOperatorsRegex() {
|
|
||||||
return "(\\+\\+)|(\\-\\-)|(\\+\\=)|" //$NON-NLS-1$
|
|
||||||
+ "(\\-\\=)|(\\*\\=)|(/\\=)|(\\&\\=)" //$NON-NLS-1$
|
|
||||||
+ "(\\%\\=)|(\\^\\=)|(\\|\\=)|(\\<\\<\\=)|(\\>\\>\\=)"; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getEqualToOperatorsRegex() {
|
|
||||||
return "\\=\\=|\\<\\=|\\>\\=|!\\="; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIdentifierRegex() {
|
|
||||||
return "[_A-Za-z][_A-Za-z0-9]*"; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text hovering support for C/C++ debugger.
|
* The text hovering support for C/C++ debugger.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class DebugTextHover implements ICEditorTextHover, ITextHoverExtension,
|
public class DebugTextHover extends AbstractDebugTextHover {
|
||||||
ISelectionListener, IPartListener {
|
|
||||||
|
|
||||||
static final private int MAX_HOVER_INFO_SIZE = 100;
|
|
||||||
|
|
||||||
protected ISelection fSelection = null;
|
|
||||||
|
|
||||||
protected IEditorPart fEditor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for DebugTextHover.
|
* Returns the evaluation stack frame, or <code>null</code> if none.
|
||||||
|
*
|
||||||
|
* @return the evaluation stack frame, or <code>null</code> if none
|
||||||
*/
|
*/
|
||||||
public DebugTextHover() {
|
protected ICStackFrame getFrame() {
|
||||||
super();
|
IAdaptable adaptable = getSelectionAdaptable();
|
||||||
|
if (adaptable != null) {
|
||||||
|
return (ICStackFrame) adaptable.getAdapter(ICStackFrame.class);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
@Override
|
||||||
* (non-Javadoc)
|
protected boolean canEvaluate() {
|
||||||
*
|
|
||||||
* @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer,
|
|
||||||
* org.eclipse.jface.text.IRegion)
|
|
||||||
*/
|
|
||||||
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
|
||||||
ICStackFrame frame = getFrame();
|
ICStackFrame frame = getFrame();
|
||||||
if (frame != null && frame.canEvaluate()) {
|
if (frame != null)
|
||||||
try {
|
return frame.canEvaluate();
|
||||||
IDocument document = textViewer.getDocument();
|
|
||||||
if (document == null)
|
|
||||||
return null;
|
|
||||||
String expression = document.get(hoverRegion.getOffset(),
|
|
||||||
hoverRegion.getLength());
|
|
||||||
if (expression == null)
|
|
||||||
return null;
|
|
||||||
expression = expression.trim();
|
|
||||||
if (expression.length() == 0)
|
|
||||||
return null;
|
|
||||||
LanguageOperators operatorsObj = new LanguageOperators();
|
|
||||||
|
|
||||||
Pattern pattern = Pattern.compile(operatorsObj
|
return false;
|
||||||
.getValueChangeOperatorsRegex());
|
|
||||||
Matcher matcher = pattern.matcher(expression);
|
|
||||||
|
|
||||||
boolean match_found = matcher.find();
|
|
||||||
// Get matching string
|
|
||||||
// If the expression has some operators which can change the
|
|
||||||
// value of a variable, that expresssion should not be
|
|
||||||
// evaluated.
|
|
||||||
if (match_found) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
pattern = Pattern.compile(operatorsObj
|
|
||||||
.getEqualToOperatorsRegex());
|
|
||||||
String[] tokens = pattern.split(expression);
|
|
||||||
for (int i = 0; i < tokens.length; i++) {
|
|
||||||
//If the expression contains assignment operator that
|
|
||||||
// can change the value of a variable, the expression
|
|
||||||
// should not be evaluated.
|
|
||||||
if (tokens[i].indexOf(operatorsObj
|
|
||||||
.getAssignmentOperator()) != -1)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
//Supressing function calls from evaluation.
|
|
||||||
String functionCallRegex = operatorsObj.getIdentifierRegex() + "\\s*\\("; //$NON-NLS-1$
|
|
||||||
pattern = Pattern.compile(functionCallRegex);
|
|
||||||
matcher = pattern.matcher(expression);
|
|
||||||
match_found = matcher.find();
|
|
||||||
if (match_found) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
String result = evaluateExpression(frame, expression);
|
|
||||||
if (result == null)
|
|
||||||
return null;
|
|
||||||
try {
|
|
||||||
appendVariable(buffer, makeHTMLSafe(expression), makeHTMLSafe(result.trim()));
|
|
||||||
} catch (DebugException x) {
|
|
||||||
CDebugUIPlugin.log(x);
|
|
||||||
}
|
|
||||||
if (buffer.length() > 0) {
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
} catch (BadLocationException x) {
|
|
||||||
CDebugUIPlugin.log(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
@Override
|
||||||
* (non-Javadoc)
|
protected String evaluateExpression(String expression) {
|
||||||
*
|
ICStackFrame frame = getFrame();
|
||||||
* @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
|
|
||||||
*/
|
|
||||||
public IRegion getHoverRegion(ITextViewer viewer, int offset) {
|
|
||||||
/*
|
|
||||||
* Point selectedRange = viewer.getSelectedRange(); if ( selectedRange.x >= 0 && selectedRange.y > 0 && offset >= selectedRange.x && offset <=
|
|
||||||
* selectedRange.x + selectedRange.y ) return new Region( selectedRange.x, selectedRange.y );
|
|
||||||
*/
|
|
||||||
if (viewer != null)
|
|
||||||
return CDebugUIUtils.findWord(viewer.getDocument(), offset);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String evaluateExpression(ICStackFrame frame, String expression) {
|
|
||||||
String result = null;
|
String result = null;
|
||||||
try {
|
try {
|
||||||
result = frame.evaluateExpressionToString(expression);
|
result = frame.evaluateExpressionToString(expression);
|
||||||
|
@ -190,149 +56,4 @@ public class DebugTextHover implements ICEditorTextHover, ITextHoverExtension,
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Append HTML for the given variable to the given buffer
|
|
||||||
*/
|
|
||||||
private static void appendVariable(StringBuffer buffer, String expression, String value) throws DebugException {
|
|
||||||
if (value.length() > MAX_HOVER_INFO_SIZE)
|
|
||||||
value = value.substring(0, MAX_HOVER_INFO_SIZE) + " ..."; //$NON-NLS-1$
|
|
||||||
buffer.append("<p>"); //$NON-NLS-1$
|
|
||||||
buffer.append("<pre>").append(expression).append("</pre>"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
buffer.append(" = "); //$NON-NLS-1$
|
|
||||||
buffer.append("<b><pre>").append(value).append("</pre></b>"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
buffer.append("</p>"); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover#setEditor(org.eclipse.ui.IEditorPart)
|
|
||||||
*/
|
|
||||||
public void setEditor(IEditorPart editor) {
|
|
||||||
if (editor != null) {
|
|
||||||
fEditor = editor;
|
|
||||||
final IWorkbenchPage page = editor.getSite().getPage();
|
|
||||||
page.addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
|
|
||||||
page.addPartListener(this);
|
|
||||||
// initialize selection
|
|
||||||
Runnable r = new Runnable() {
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
fSelection = page
|
|
||||||
.getSelection(IDebugUIConstants.ID_DEBUG_VIEW);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
CDebugUIPlugin.getStandardDisplay().asyncExec(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
|
|
||||||
*/
|
|
||||||
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
|
|
||||||
fSelection = selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart)
|
|
||||||
*/
|
|
||||||
public void partActivated(IWorkbenchPart part) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.ui.IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart)
|
|
||||||
*/
|
|
||||||
public void partBroughtToTop(IWorkbenchPart part) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
|
|
||||||
*/
|
|
||||||
public void partClosed(IWorkbenchPart part) {
|
|
||||||
if (part.equals(fEditor)) {
|
|
||||||
IWorkbenchPage page = fEditor.getSite().getPage();
|
|
||||||
page.removeSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
|
|
||||||
page.removePartListener(this);
|
|
||||||
fSelection = null;
|
|
||||||
fEditor = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart)
|
|
||||||
*/
|
|
||||||
public void partDeactivated(IWorkbenchPart part) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
|
|
||||||
*/
|
|
||||||
public void partOpened(IWorkbenchPart part) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the evaluation stack frame, or <code>null</code> if none.
|
|
||||||
*
|
|
||||||
* @return the evaluation stack frame, or <code>null</code> if none
|
|
||||||
*/
|
|
||||||
protected ICStackFrame getFrame() {
|
|
||||||
if (fSelection instanceof IStructuredSelection) {
|
|
||||||
IStructuredSelection selection = (IStructuredSelection) fSelection;
|
|
||||||
if (selection.size() == 1) {
|
|
||||||
Object el = selection.getFirstElement();
|
|
||||||
if (el instanceof IAdaptable) {
|
|
||||||
return (ICStackFrame) ((IAdaptable) el)
|
|
||||||
.getAdapter(ICStackFrame.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
|
|
||||||
*/
|
|
||||||
public IInformationControlCreator getHoverControlCreator() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace any characters in the given String that would confuse an HTML parser with their escape sequences.
|
|
||||||
*/
|
|
||||||
private static String makeHTMLSafe(String string) {
|
|
||||||
StringBuffer buffer = new StringBuffer(string.length());
|
|
||||||
for (int i = 0; i != string.length(); i++) {
|
|
||||||
char ch = string.charAt(i);
|
|
||||||
switch (ch) {
|
|
||||||
case '&':
|
|
||||||
buffer.append("&"); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
buffer.append("<"); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
buffer.append(">"); //$NON-NLS-1$
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
buffer.append(ch);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,279 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2007 QNX Software 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
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
* Nokia - Refactored from DebugTextHover to remove CDI dependency
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.debug.ui.editors;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils;
|
||||||
|
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover;
|
||||||
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
|
import org.eclipse.debug.core.DebugException;
|
||||||
|
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IInformationControlCreator;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextHoverExtension;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
|
import org.eclipse.ui.IPartListener;
|
||||||
|
import org.eclipse.ui.ISelectionListener;
|
||||||
|
import org.eclipse.ui.IWorkbenchPage;
|
||||||
|
import org.eclipse.ui.IWorkbenchPart;
|
||||||
|
|
||||||
|
/* The class LanguageOperators protects some language specific
|
||||||
|
* operator information used by the DebugTextHover class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class LanguageOperators {
|
||||||
|
public String getAssignmentOperator() {
|
||||||
|
return "="; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGreaterThanEqualToOperator() {
|
||||||
|
return ">="; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEqualToOperator() {
|
||||||
|
return "=="; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNotEqualToOperator() {
|
||||||
|
return "!="; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLessThenEqualToOperator() {
|
||||||
|
return "<="; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValueChangeOperatorsRegex() {
|
||||||
|
return "(\\+\\+)|(\\-\\-)|(\\+\\=)|" //$NON-NLS-1$
|
||||||
|
+ "(\\-\\=)|(\\*\\=)|(/\\=)|(\\&\\=)" //$NON-NLS-1$
|
||||||
|
+ "(\\%\\=)|(\\^\\=)|(\\|\\=)|(\\<\\<\\=)|(\\>\\>\\=)"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEqualToOperatorsRegex() {
|
||||||
|
return "\\=\\=|\\<\\=|\\>\\=|!\\="; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIdentifierRegex() {
|
||||||
|
return "[_A-Za-z][_A-Za-z0-9]*"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The text hovering support for C/C++ debugger.
|
||||||
|
*
|
||||||
|
* @since 6.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class AbstractDebugTextHover implements ICEditorTextHover, ITextHoverExtension,
|
||||||
|
ISelectionListener, IPartListener {
|
||||||
|
|
||||||
|
static final private int MAX_HOVER_INFO_SIZE = 100;
|
||||||
|
|
||||||
|
private ISelection fSelection = null;
|
||||||
|
|
||||||
|
private IEditorPart fEditor;
|
||||||
|
|
||||||
|
protected abstract boolean canEvaluate();
|
||||||
|
|
||||||
|
protected abstract String evaluateExpression(String expression);
|
||||||
|
|
||||||
|
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
||||||
|
if (canEvaluate()) {
|
||||||
|
try {
|
||||||
|
IDocument document = textViewer.getDocument();
|
||||||
|
if (document == null)
|
||||||
|
return null;
|
||||||
|
String expression = document.get(hoverRegion.getOffset(),
|
||||||
|
hoverRegion.getLength());
|
||||||
|
if (expression == null)
|
||||||
|
return null;
|
||||||
|
expression = expression.trim();
|
||||||
|
if (expression.length() == 0)
|
||||||
|
return null;
|
||||||
|
LanguageOperators operatorsObj = new LanguageOperators();
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile(operatorsObj
|
||||||
|
.getValueChangeOperatorsRegex());
|
||||||
|
Matcher matcher = pattern.matcher(expression);
|
||||||
|
|
||||||
|
boolean match_found = matcher.find();
|
||||||
|
// Get matching string
|
||||||
|
// If the expression has some operators which can change the
|
||||||
|
// value of a variable, that expresssion should not be
|
||||||
|
// evaluated.
|
||||||
|
if (match_found) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
pattern = Pattern.compile(operatorsObj
|
||||||
|
.getEqualToOperatorsRegex());
|
||||||
|
String[] tokens = pattern.split(expression);
|
||||||
|
for (int i = 0; i < tokens.length; i++) {
|
||||||
|
//If the expression contains assignment operator that
|
||||||
|
// can change the value of a variable, the expression
|
||||||
|
// should not be evaluated.
|
||||||
|
if (tokens[i].indexOf(operatorsObj
|
||||||
|
.getAssignmentOperator()) != -1)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//Supressing function calls from evaluation.
|
||||||
|
String functionCallRegex = operatorsObj.getIdentifierRegex() + "\\s*\\("; //$NON-NLS-1$
|
||||||
|
pattern = Pattern.compile(functionCallRegex);
|
||||||
|
matcher = pattern.matcher(expression);
|
||||||
|
match_found = matcher.find();
|
||||||
|
if (match_found) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
String result = evaluateExpression(expression);
|
||||||
|
if (result == null)
|
||||||
|
return null;
|
||||||
|
try {
|
||||||
|
appendVariable(buffer, makeHTMLSafe(expression), makeHTMLSafe(result.trim()));
|
||||||
|
} catch (DebugException x) {
|
||||||
|
CDebugUIPlugin.log(x);
|
||||||
|
}
|
||||||
|
if (buffer.length() > 0) {
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
} catch (BadLocationException x) {
|
||||||
|
CDebugUIPlugin.log(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRegion getHoverRegion(ITextViewer viewer, int offset) {
|
||||||
|
/*
|
||||||
|
* Point selectedRange = viewer.getSelectedRange(); if ( selectedRange.x >= 0 && selectedRange.y > 0 && offset >= selectedRange.x && offset <=
|
||||||
|
* selectedRange.x + selectedRange.y ) return new Region( selectedRange.x, selectedRange.y );
|
||||||
|
*/
|
||||||
|
if (viewer != null)
|
||||||
|
return CDebugUIUtils.findWord(viewer.getDocument(), offset);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append HTML for the given variable to the given buffer
|
||||||
|
*/
|
||||||
|
private static void appendVariable(StringBuffer buffer, String expression, String value) throws DebugException {
|
||||||
|
if (value.length() > MAX_HOVER_INFO_SIZE)
|
||||||
|
value = value.substring(0, MAX_HOVER_INFO_SIZE) + " ..."; //$NON-NLS-1$
|
||||||
|
buffer.append("<p>"); //$NON-NLS-1$
|
||||||
|
buffer.append("<pre>").append(expression).append("</pre>"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
buffer.append(" = "); //$NON-NLS-1$
|
||||||
|
buffer.append("<b><pre>").append(value).append("</pre></b>"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
buffer.append("</p>"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEditor(IEditorPart editor) {
|
||||||
|
if (editor != null) {
|
||||||
|
fEditor = editor;
|
||||||
|
final IWorkbenchPage page = editor.getSite().getPage();
|
||||||
|
page.addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
|
||||||
|
page.addPartListener(this);
|
||||||
|
// initialize selection
|
||||||
|
Runnable r = new Runnable() {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
fSelection = page
|
||||||
|
.getSelection(IDebugUIConstants.ID_DEBUG_VIEW);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
CDebugUIPlugin.getStandardDisplay().asyncExec(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
|
||||||
|
fSelection = selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void partActivated(IWorkbenchPart part) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void partBroughtToTop(IWorkbenchPart part) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void partClosed(IWorkbenchPart part) {
|
||||||
|
if (part.equals(fEditor)) {
|
||||||
|
IWorkbenchPage page = fEditor.getSite().getPage();
|
||||||
|
page.removeSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
|
||||||
|
page.removePartListener(this);
|
||||||
|
fSelection = null;
|
||||||
|
fEditor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void partDeactivated(IWorkbenchPart part) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void partOpened(IWorkbenchPart part) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public IInformationControlCreator getHoverControlCreator() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ISelection getSelection() {
|
||||||
|
return fSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IAdaptable getSelectionAdaptable() {
|
||||||
|
if (fSelection instanceof IStructuredSelection) {
|
||||||
|
IStructuredSelection selection = (IStructuredSelection) fSelection;
|
||||||
|
if (selection.size() == 1) {
|
||||||
|
Object element = selection.getFirstElement();
|
||||||
|
if (element instanceof IAdaptable) {
|
||||||
|
return (IAdaptable) element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected IEditorPart getEditor() {
|
||||||
|
return fEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace any characters in the given String that would confuse an HTML parser with their escape sequences.
|
||||||
|
*/
|
||||||
|
private static String makeHTMLSafe(String string) {
|
||||||
|
StringBuffer buffer = new StringBuffer(string.length());
|
||||||
|
for (int i = 0; i != string.length(); i++) {
|
||||||
|
char ch = string.charAt(i);
|
||||||
|
switch (ch) {
|
||||||
|
case '&':
|
||||||
|
buffer.append("&"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
buffer.append("<"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
buffer.append(">"); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buffer.append(ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,3 +44,6 @@ launchTab.arguments.name=Arguments
|
||||||
launchTab.debugger.name=Debugger
|
launchTab.debugger.name=Debugger
|
||||||
launchTab.sourceLookup.name=Source
|
launchTab.sourceLookup.name=Source
|
||||||
launchTab.common.name=Common
|
launchTab.common.name=Common
|
||||||
|
|
||||||
|
editorTextHover.label=GDB Debugger
|
||||||
|
editorTextHover.description=Shows formatted value in debugger hover
|
|
@ -715,4 +715,14 @@
|
||||||
</toggleTargetFactory>
|
</toggleTargetFactory>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.cdt.ui.textHovers">
|
||||||
|
<hover
|
||||||
|
label="%editorTextHover.description"
|
||||||
|
description="%editorTextHover.description"
|
||||||
|
class="org.eclipse.cdt.dsf.gdb.internal.ui.GdbDebugTextHover"
|
||||||
|
id="org.eclipse.cdt.dsf.gdb.internal.ui.GdbDebugTextHover">
|
||||||
|
</hover>
|
||||||
|
</extension>
|
||||||
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.dsf.gdb.internal.ui;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.dsf.debug.ui.AbstractDsfDebugTextHover;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunchDelegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug editor text hover for GDB.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public class GdbDebugTextHover extends AbstractDsfDebugTextHover {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getModelId() {
|
||||||
|
return GdbLaunchDelegate.GDB_DEBUG_MODEL_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.5.0",
|
||||||
org.eclipse.cdt.dsf;bundle-version="2.0.0",
|
org.eclipse.cdt.dsf;bundle-version="2.0.0",
|
||||||
org.eclipse.cdt.core;bundle-version="5.1.0",
|
org.eclipse.cdt.core;bundle-version="5.1.0",
|
||||||
org.eclipse.cdt.debug.core;bundle-version="6.0.0",
|
org.eclipse.cdt.debug.core;bundle-version="6.0.0",
|
||||||
org.eclipse.cdt.debug.ui;bundle-version="6.0.0",
|
org.eclipse.cdt.debug.ui;bundle-version="6.1.0",
|
||||||
org.eclipse.jface.text;bundle-version="3.4.0",
|
org.eclipse.jface.text;bundle-version="3.4.0",
|
||||||
org.eclipse.ui.editors;bundle-version="3.4.0",
|
org.eclipse.ui.editors;bundle-version="3.4.0",
|
||||||
org.eclipse.ui.ide;bundle-version="3.5.0",
|
org.eclipse.ui.ide;bundle-version="3.5.0",
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
* All rights reserved.
|
||||||
|
* This component and the accompanying materials are made available
|
||||||
|
* under the terms of the License "Eclipse Public License v1.0"
|
||||||
|
* which accompanies this distribution, and is available
|
||||||
|
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
||||||
|
*
|
||||||
|
* Initial Contributors:
|
||||||
|
* Nokia Corporation - initial contribution.
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.dsf.debug.ui;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.debug.ui.editors.AbstractDebugTextHover;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.Query;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||||
|
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.core.runtime.IAdaptable;
|
||||||
|
import org.eclipse.debug.core.model.IDebugModelProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of AbstractDebugTextHover using DSF services
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
abstract public class AbstractDsfDebugTextHover extends AbstractDebugTextHover {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the debug model ID of that this debug text hover is to be used for.
|
||||||
|
*/
|
||||||
|
abstract protected String getModelId();
|
||||||
|
|
||||||
|
private static class GetExpressionValueQuery extends Query<FormattedValueDMData> {
|
||||||
|
private final IFrameDMContext frame;
|
||||||
|
private final String expression;
|
||||||
|
private DsfServicesTracker dsfServicesTracker;
|
||||||
|
|
||||||
|
public GetExpressionValueQuery(IFrameDMContext frame, String expression, DsfServicesTracker dsfServicesTracker) {
|
||||||
|
this.frame = frame;
|
||||||
|
this.expression = expression;
|
||||||
|
this.dsfServicesTracker = dsfServicesTracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void execute(final DataRequestMonitor<FormattedValueDMData> rm) {
|
||||||
|
DsfSession session = DsfSession.getSession(frame.getSessionId());
|
||||||
|
IExpressions expressions = dsfServicesTracker.getService(IExpressions.class);
|
||||||
|
IExpressionDMContext expressionDMC = expressions.createExpression(frame, expression);
|
||||||
|
FormattedValueDMContext formattedValueContext = expressions.getFormattedValueContext(expressionDMC, IFormattedValues.NATURAL_FORMAT);
|
||||||
|
expressions.getFormattedExpressionValue(formattedValueContext,
|
||||||
|
new DataRequestMonitor<FormattedValueDMData>(session.getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
rm.setData(getData());
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleFailure() {
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IFrameDMContext getFrame() {
|
||||||
|
IAdaptable adaptable = getSelectionAdaptable();
|
||||||
|
if (adaptable != null) {
|
||||||
|
return (IFrameDMContext) adaptable.getAdapter(IFrameDMContext.class);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canEvaluate() {
|
||||||
|
if (getFrame() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IAdaptable adaptable = getSelectionAdaptable();
|
||||||
|
if (adaptable != null) {
|
||||||
|
IDebugModelProvider modelProvider = (IDebugModelProvider)adaptable.getAdapter(IDebugModelProvider.class);
|
||||||
|
if (modelProvider != null) {
|
||||||
|
String[] models = modelProvider.getModelIdentifiers();
|
||||||
|
String myModel = getModelId();
|
||||||
|
for (int i = 0; i < models.length; i++) {
|
||||||
|
if (models[i].equals(myModel)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String evaluateExpression(String expression) {
|
||||||
|
IFrameDMContext frame = getFrame();
|
||||||
|
String sessionId = frame.getSessionId();
|
||||||
|
DsfServicesTracker dsfServicesTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), sessionId);
|
||||||
|
GetExpressionValueQuery query = new GetExpressionValueQuery(frame, expression, dsfServicesTracker);
|
||||||
|
DsfSession session = DsfSession.getSession(sessionId);
|
||||||
|
session.getExecutor().execute(query);
|
||||||
|
try {
|
||||||
|
FormattedValueDMData data = query.get();
|
||||||
|
if (data != null)
|
||||||
|
return data.getFormattedValue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue