mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +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-Name: %pluginName
|
||||
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-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
|
@ -23,6 +23,7 @@ Export-Package:
|
|||
org.eclipse.cdt.debug.ui.breakpointactions,
|
||||
org.eclipse.cdt.debug.ui.breakpoints,
|
||||
org.eclipse.cdt.debug.ui.disassembly,
|
||||
org.eclipse.cdt.debug.ui.editors,
|
||||
org.eclipse.cdt.debug.ui.importexecutable,
|
||||
org.eclipse.cdt.debug.ui.sourcelookup
|
||||
Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)",
|
||||
|
|
|
@ -7,181 +7,47 @@
|
|||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Nokia - Refactored into CDI specific implementation of AbstractDebugTextHover
|
||||
|
||||
*******************************************************************************/
|
||||
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.internal.ui.CDebugUIUtils;
|
||||
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover;
|
||||
import org.eclipse.cdt.debug.ui.editors.AbstractDebugTextHover;
|
||||
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.
|
||||
*/
|
||||
|
||||
public class DebugTextHover implements ICEditorTextHover, ITextHoverExtension,
|
||||
ISelectionListener, IPartListener {
|
||||
|
||||
static final private int MAX_HOVER_INFO_SIZE = 100;
|
||||
|
||||
protected ISelection fSelection = null;
|
||||
|
||||
protected IEditorPart fEditor;
|
||||
public class DebugTextHover extends AbstractDebugTextHover {
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
super();
|
||||
protected ICStackFrame getFrame() {
|
||||
IAdaptable adaptable = getSelectionAdaptable();
|
||||
if (adaptable != null) {
|
||||
return (ICStackFrame) adaptable.getAdapter(ICStackFrame.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer,
|
||||
* org.eclipse.jface.text.IRegion)
|
||||
*/
|
||||
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
||||
@Override
|
||||
protected boolean canEvaluate() {
|
||||
ICStackFrame frame = getFrame();
|
||||
if (frame != null && frame.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();
|
||||
if (frame != null)
|
||||
return frame.canEvaluate();
|
||||
|
||||
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(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;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @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) {
|
||||
@Override
|
||||
protected String evaluateExpression(String expression) {
|
||||
ICStackFrame frame = getFrame();
|
||||
String result = null;
|
||||
try {
|
||||
result = frame.evaluateExpressionToString(expression);
|
||||
|
@ -190,149 +56,4 @@ public class DebugTextHover implements ICEditorTextHover, ITextHoverExtension,
|
|||
}
|
||||
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.sourceLookup.name=Source
|
||||
launchTab.common.name=Common
|
||||
|
||||
editorTextHover.label=GDB Debugger
|
||||
editorTextHover.description=Shows formatted value in debugger hover
|
|
@ -715,4 +715,14 @@
|
|||
</toggleTargetFactory>
|
||||
</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>
|
||||
|
|
|
@ -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.core;bundle-version="5.1.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.ui.editors;bundle-version="3.4.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