mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +02:00
Bug 200418 - Mouse over struct/class member always fails
This commit is contained in:
parent
f3955789de
commit
450bef3a2c
2 changed files with 318 additions and 280 deletions
|
@ -1,5 +1,5 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Copyright (c) 2003, 2007 QNX Software Systems and others.
|
# Copyright (c) 2003, 2009 QNX Software Systems and others.
|
||||||
# All rights reserved. This program and the accompanying materials
|
# All rights reserved. This program and the accompanying materials
|
||||||
# are made available under the terms of the Eclipse Public License v1.0
|
# are made available under the terms of the Eclipse Public License v1.0
|
||||||
# which accompanies this distribution, and is available at
|
# which accompanies this distribution, and is available at
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
# QNX Software Systems - initial API and implementation
|
# QNX Software Systems - initial API and implementation
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
AbstractDebugTextHover.jobName=Computing hover expression
|
||||||
CDebugModelPresentation.unknown_1=unknown
|
CDebugModelPresentation.unknown_1=unknown
|
||||||
CDebugImageDescriptorRegistry.0=Allocating image for wrong display.
|
CDebugImageDescriptorRegistry.0=Allocating image for wrong display.
|
||||||
CDebugModelPresentation.not_available_1=<not available>
|
CDebugModelPresentation.not_available_1=<not available>
|
||||||
|
|
|
@ -1,279 +1,316 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2007 QNX Software Systems and others.
|
* Copyright (c) 2000, 2009 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
* Nokia - Refactored from DebugTextHover to remove CDI dependency
|
* Nokia - Refactored from DebugTextHover to remove CDI dependency
|
||||||
*
|
* Wind River Systems - Bug 200418
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.debug.ui.editors;
|
package org.eclipse.cdt.debug.ui.editors;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import java.util.regex.Pattern;
|
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.core.runtime.IAdaptable;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.debug.core.DebugException;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
import org.eclipse.jface.text.IInformationControlCreator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||||
import org.eclipse.jface.text.IRegion;
|
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
|
||||||
import org.eclipse.jface.text.ITextHoverExtension;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
import org.eclipse.cdt.debug.internal.ui.CDebugUIMessages;
|
||||||
import org.eclipse.ui.IEditorPart;
|
import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils;
|
||||||
import org.eclipse.ui.IPartListener;
|
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
|
||||||
import org.eclipse.ui.ISelectionListener;
|
import org.eclipse.cdt.ui.CDTUITools;
|
||||||
import org.eclipse.ui.IWorkbenchPage;
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
import org.eclipse.ui.IWorkbenchPart;
|
import org.eclipse.cdt.ui.text.SharedASTJob;
|
||||||
|
import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover;
|
||||||
/* The class LanguageOperators protects some language specific
|
import org.eclipse.core.runtime.CoreException;
|
||||||
* operator information used by the DebugTextHover class.
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
*/
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
class LanguageOperators {
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
public String getAssignmentOperator() {
|
import org.eclipse.debug.core.DebugException;
|
||||||
return "="; //$NON-NLS-1$
|
import org.eclipse.debug.ui.DebugUITools;
|
||||||
}
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
public String getGreaterThanEqualToOperator() {
|
import org.eclipse.jface.text.IInformationControlCreator;
|
||||||
return ">="; //$NON-NLS-1$
|
import org.eclipse.jface.text.IRegion;
|
||||||
}
|
import org.eclipse.jface.text.ITextHoverExtension;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
public String getEqualToOperator() {
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
return "=="; //$NON-NLS-1$
|
import org.eclipse.jface.text.Position;
|
||||||
}
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
public String getNotEqualToOperator() {
|
|
||||||
return "!="; //$NON-NLS-1$
|
/**
|
||||||
}
|
* The text hovering support for C/C++ debugger.
|
||||||
|
*
|
||||||
public String getLessThenEqualToOperator() {
|
* @since 6.1
|
||||||
return "<="; //$NON-NLS-1$
|
*/
|
||||||
}
|
public abstract class AbstractDebugTextHover implements ICEditorTextHover, ITextHoverExtension {
|
||||||
|
|
||||||
public String getValueChangeOperatorsRegex() {
|
/**
|
||||||
return "(\\+\\+)|(\\-\\-)|(\\+\\=)|" //$NON-NLS-1$
|
* ASTVisitor checking for side-effect expressions.
|
||||||
+ "(\\-\\=)|(\\*\\=)|(/\\=)|(\\&\\=)" //$NON-NLS-1$
|
*/
|
||||||
+ "(\\%\\=)|(\\^\\=)|(\\|\\=)|(\\<\\<\\=)|(\\>\\>\\=)"; //$NON-NLS-1$
|
private static class ExpressionChecker extends ASTVisitor {
|
||||||
}
|
private boolean fValid;
|
||||||
|
private ExpressionChecker() {
|
||||||
public String getEqualToOperatorsRegex() {
|
shouldVisitExpressions = true;
|
||||||
return "\\=\\=|\\<\\=|\\>\\=|!\\="; //$NON-NLS-1$
|
}
|
||||||
}
|
private boolean check(IASTNode node) {
|
||||||
|
fValid = true;
|
||||||
public String getIdentifierRegex() {
|
node.accept(this);
|
||||||
return "[_A-Za-z][_A-Za-z0-9]*"; //$NON-NLS-1$
|
return fValid;
|
||||||
}
|
};
|
||||||
}
|
@Override
|
||||||
|
public int visit(IASTExpression expression) {
|
||||||
/**
|
if (expression instanceof IASTFunctionCallExpression) {
|
||||||
* The text hovering support for C/C++ debugger.
|
fValid = false;
|
||||||
*
|
} else if (expression instanceof IASTUnaryExpression) {
|
||||||
* @since 6.1
|
IASTUnaryExpression unaryExpression = (IASTUnaryExpression) expression;
|
||||||
*/
|
switch (unaryExpression.getOperator()) {
|
||||||
|
case IASTUnaryExpression.op_postFixDecr:
|
||||||
public abstract class AbstractDebugTextHover implements ICEditorTextHover, ITextHoverExtension,
|
case IASTUnaryExpression.op_postFixIncr:
|
||||||
ISelectionListener, IPartListener {
|
case IASTUnaryExpression.op_prefixIncr:
|
||||||
|
case IASTUnaryExpression.op_prefixDecr:
|
||||||
static final private int MAX_HOVER_INFO_SIZE = 100;
|
fValid = false;
|
||||||
|
break;
|
||||||
private ISelection fSelection = null;
|
}
|
||||||
|
} else if (expression instanceof IASTBinaryExpression) {
|
||||||
private IEditorPart fEditor;
|
IASTBinaryExpression binaryExpression = (IASTBinaryExpression) expression;
|
||||||
|
switch (binaryExpression.getOperator()) {
|
||||||
protected abstract boolean canEvaluate();
|
case IASTBinaryExpression.op_binaryAndAssign:
|
||||||
|
case IASTBinaryExpression.op_binaryOrAssign:
|
||||||
protected abstract String evaluateExpression(String expression);
|
case IASTBinaryExpression.op_binaryXorAssign:
|
||||||
|
case IASTBinaryExpression.op_divideAssign:
|
||||||
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
case IASTBinaryExpression.op_minusAssign:
|
||||||
if (canEvaluate()) {
|
case IASTBinaryExpression.op_moduloAssign:
|
||||||
try {
|
case IASTBinaryExpression.op_multiplyAssign:
|
||||||
IDocument document = textViewer.getDocument();
|
case IASTBinaryExpression.op_plusAssign:
|
||||||
if (document == null)
|
case IASTBinaryExpression.op_shiftLeftAssign:
|
||||||
return null;
|
case IASTBinaryExpression.op_shiftRightAssign:
|
||||||
String expression = document.get(hoverRegion.getOffset(),
|
fValid = false;
|
||||||
hoverRegion.getLength());
|
break;
|
||||||
if (expression == null)
|
}
|
||||||
return null;
|
} else if (expression instanceof ICPPASTNewExpression) {
|
||||||
expression = expression.trim();
|
fValid = false;
|
||||||
if (expression.length() == 0)
|
} else if (expression instanceof ICPPASTDeleteExpression) {
|
||||||
return null;
|
fValid = false;
|
||||||
LanguageOperators operatorsObj = new LanguageOperators();
|
} else if (expression instanceof IGNUASTCompoundStatementExpression) {
|
||||||
|
fValid = false;
|
||||||
Pattern pattern = Pattern.compile(operatorsObj
|
}
|
||||||
.getValueChangeOperatorsRegex());
|
if (!fValid)
|
||||||
Matcher matcher = pattern.matcher(expression);
|
return PROCESS_ABORT;
|
||||||
|
return PROCESS_CONTINUE;
|
||||||
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
|
static final private int MAX_HOVER_INFO_SIZE = 100;
|
||||||
// evaluated.
|
|
||||||
if (match_found) {
|
private IEditorPart fEditor;
|
||||||
return null;
|
|
||||||
}
|
/**
|
||||||
pattern = Pattern.compile(operatorsObj
|
* @return <code>true</code> if this hover can evaluate an expression
|
||||||
.getEqualToOperatorsRegex());
|
*/
|
||||||
String[] tokens = pattern.split(expression);
|
protected abstract boolean canEvaluate();
|
||||||
for (int i = 0; i < tokens.length; i++) {
|
|
||||||
//If the expression contains assignment operator that
|
/**
|
||||||
// can change the value of a variable, the expression
|
* Compute a value for given expression.
|
||||||
// should not be evaluated.
|
*
|
||||||
if (tokens[i].indexOf(operatorsObj
|
* @param expression
|
||||||
.getAssignmentOperator()) != -1)
|
* @return a result string or <code>null</code> if the expression could not be evaluated
|
||||||
return null;
|
*/
|
||||||
}
|
protected abstract String evaluateExpression(String expression);
|
||||||
//Supressing function calls from evaluation.
|
|
||||||
String functionCallRegex = operatorsObj.getIdentifierRegex() + "\\s*\\("; //$NON-NLS-1$
|
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
||||||
pattern = Pattern.compile(functionCallRegex);
|
if (canEvaluate()) {
|
||||||
matcher = pattern.matcher(expression);
|
String expression = getExpressionText(textViewer, hoverRegion);
|
||||||
match_found = matcher.find();
|
if (expression != null) {
|
||||||
if (match_found) {
|
String result = evaluateExpression(expression);
|
||||||
return null;
|
if (result == null)
|
||||||
}
|
return null;
|
||||||
StringBuffer buffer = new StringBuffer();
|
try {
|
||||||
String result = evaluateExpression(expression);
|
StringBuilder buffer = new StringBuilder();
|
||||||
if (result == null)
|
appendVariable(buffer, makeHTMLSafe(expression), makeHTMLSafe(result.trim()));
|
||||||
return null;
|
if (buffer.length() > 0) {
|
||||||
try {
|
return buffer.toString();
|
||||||
appendVariable(buffer, makeHTMLSafe(expression), makeHTMLSafe(result.trim()));
|
}
|
||||||
} catch (DebugException x) {
|
} catch (DebugException x) {
|
||||||
CDebugUIPlugin.log(x);
|
CDebugUIPlugin.log(x);
|
||||||
}
|
}
|
||||||
if (buffer.length() > 0) {
|
}
|
||||||
return buffer.toString();
|
}
|
||||||
}
|
return null;
|
||||||
} catch (BadLocationException x) {
|
}
|
||||||
CDebugUIPlugin.log(x);
|
public IRegion getHoverRegion(ITextViewer viewer, int offset) {
|
||||||
}
|
/*
|
||||||
}
|
* Point selectedRange = viewer.getSelectedRange(); if ( selectedRange.x >= 0 && selectedRange.y > 0 && offset >= selectedRange.x && offset <=
|
||||||
return null;
|
* selectedRange.x + selectedRange.y ) return new Region( selectedRange.x, selectedRange.y );
|
||||||
}
|
*/
|
||||||
|
if (viewer != null)
|
||||||
public IRegion getHoverRegion(ITextViewer viewer, int offset) {
|
return CDebugUIUtils.findWord(viewer.getDocument(), offset);
|
||||||
/*
|
return null;
|
||||||
* 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 );
|
|
||||||
*/
|
public final void setEditor(IEditorPart editor) {
|
||||||
if (viewer != null)
|
if (editor != null) {
|
||||||
return CDebugUIUtils.findWord(viewer.getDocument(), offset);
|
fEditor = editor;
|
||||||
return null;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public IInformationControlCreator getHoverControlCreator() {
|
||||||
* Append HTML for the given variable to the given buffer
|
return null;
|
||||||
*/
|
}
|
||||||
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$
|
* Compute the expression text to be evaluated by the debugger.
|
||||||
buffer.append("<pre>").append(expression).append("</pre>"); //$NON-NLS-1$ //$NON-NLS-2$
|
* <p>
|
||||||
buffer.append(" = "); //$NON-NLS-1$
|
* The default implementation uses an AST to compute a valid, side-effect free
|
||||||
buffer.append("<b><pre>").append(value).append("</pre></b>"); //$NON-NLS-1$ //$NON-NLS-2$
|
* expression.
|
||||||
buffer.append("</p>"); //$NON-NLS-1$
|
* </p>
|
||||||
}
|
*
|
||||||
|
* @param textViewer the underlying text viewer
|
||||||
public void setEditor(IEditorPart editor) {
|
* @param hoverRegion the hover region as returned by {@link #getHoverRegion(ITextViewer, int)}
|
||||||
if (editor != null) {
|
* @return an expression string or <code>null</code> if no valid expression could be computed
|
||||||
fEditor = editor;
|
*/
|
||||||
final IWorkbenchPage page = editor.getSite().getPage();
|
protected String getExpressionText(ITextViewer textViewer, final IRegion hoverRegion) {
|
||||||
page.addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
|
IDocument document = textViewer.getDocument();
|
||||||
page.addPartListener(this);
|
if (document == null)
|
||||||
// initialize selection
|
return null;
|
||||||
Runnable r = new Runnable() {
|
ICElement cElement = CDTUITools.getEditorInputCElement(getEditor().getEditorInput());
|
||||||
|
if (cElement instanceof ITranslationUnit) {
|
||||||
public void run() {
|
final Position expressionPosition = new Position(0);
|
||||||
fSelection = page
|
SharedASTJob job = new SharedASTJob(CDebugUIMessages.getString("AbstractDebugTextHover.jobName"), (ITranslationUnit) cElement) { //$NON-NLS-1$
|
||||||
.getSelection(IDebugUIConstants.ID_DEBUG_VIEW);
|
@Override
|
||||||
}
|
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
|
||||||
};
|
if (ast != null) {
|
||||||
CDebugUIPlugin.getStandardDisplay().asyncExec(r);
|
int offset = hoverRegion.getOffset();
|
||||||
}
|
int length = hoverRegion.getLength();
|
||||||
}
|
IASTName name= ast.getNodeSelector(null).findEnclosingName(offset, length);
|
||||||
|
if (name != null) {
|
||||||
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
|
computeExpressionExtent(name, expressionPosition);
|
||||||
fSelection = selection;
|
}
|
||||||
}
|
}
|
||||||
|
return Status.OK_STATUS;
|
||||||
public void partActivated(IWorkbenchPart part) {
|
}
|
||||||
}
|
private void computeExpressionExtent(IASTName name, Position pos) {
|
||||||
|
IASTNode node = name;
|
||||||
public void partBroughtToTop(IWorkbenchPart part) {
|
while (node != null && !(node instanceof IASTExpression) && !(node instanceof IASTDeclaration)) {
|
||||||
}
|
node = node.getParent();
|
||||||
|
}
|
||||||
public void partClosed(IWorkbenchPart part) {
|
if (node instanceof IASTExpression) {
|
||||||
if (part.equals(fEditor)) {
|
ExpressionChecker checker = new ExpressionChecker();
|
||||||
IWorkbenchPage page = fEditor.getSite().getPage();
|
if (checker.check(node)) {
|
||||||
page.removeSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
|
IASTNodeLocation loc = node.getFileLocation();
|
||||||
page.removePartListener(this);
|
pos.offset = loc.getNodeOffset();
|
||||||
fSelection = null;
|
pos.length = loc.getNodeLength();
|
||||||
fEditor = null;
|
}
|
||||||
}
|
} else {
|
||||||
}
|
// fallback: use simple name
|
||||||
|
IASTNodeLocation loc = name.getFileLocation();
|
||||||
public void partDeactivated(IWorkbenchPart part) {
|
pos.offset = loc.getNodeOffset();
|
||||||
}
|
pos.length = loc.getNodeLength();
|
||||||
|
}
|
||||||
public void partOpened(IWorkbenchPart part) {
|
}
|
||||||
}
|
};
|
||||||
|
job.setPriority(Job.DECORATE);
|
||||||
public IInformationControlCreator getHoverControlCreator() {
|
job.setSystem(true);
|
||||||
return null;
|
job.schedule();
|
||||||
}
|
try {
|
||||||
|
job.join();
|
||||||
protected ISelection getSelection() {
|
} catch (InterruptedException exc) {
|
||||||
return fSelection;
|
job.cancel();
|
||||||
}
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
protected IAdaptable getSelectionAdaptable() {
|
if (expressionPosition.getLength() > 0) {
|
||||||
if (fSelection instanceof IStructuredSelection) {
|
try {
|
||||||
IStructuredSelection selection = (IStructuredSelection) fSelection;
|
// Get expression text removing comments, obsolete whitespace, etc.
|
||||||
if (selection.size() == 1) {
|
StringBuilder result = new StringBuilder();
|
||||||
Object element = selection.getFirstElement();
|
ITypedRegion[] partitions = TextUtilities.computePartitioning(document, ICPartitions.C_PARTITIONING,
|
||||||
if (element instanceof IAdaptable) {
|
expressionPosition.offset, expressionPosition.length, false);
|
||||||
return (IAdaptable) element;
|
for (ITypedRegion partition : partitions) {
|
||||||
}
|
if (IDocument.DEFAULT_CONTENT_TYPE.equals(partition.getType())
|
||||||
}
|
|| ICPartitions.C_CHARACTER.equals(partition.getType())
|
||||||
}
|
|| ICPartitions.C_STRING.equals(partition.getType())) {
|
||||||
return null;
|
result.append(document.get(partition.getOffset(), partition.getLength()));
|
||||||
}
|
} else {
|
||||||
|
result.append(' ');
|
||||||
|
}
|
||||||
protected IEditorPart getEditor() {
|
}
|
||||||
return fEditor;
|
String text = result.toString().replaceAll("(\\r\\n|\\n|\t| )+", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
}
|
return text;
|
||||||
|
} catch (BadLocationException exc) {
|
||||||
/**
|
}
|
||||||
* Replace any characters in the given String that would confuse an HTML parser with their escape sequences.
|
}
|
||||||
*/
|
}
|
||||||
private static String makeHTMLSafe(String string) {
|
return null;
|
||||||
StringBuffer buffer = new StringBuffer(string.length());
|
}
|
||||||
for (int i = 0; i != string.length(); i++) {
|
|
||||||
char ch = string.charAt(i);
|
/**
|
||||||
switch (ch) {
|
* Returns the debug context the expression should be evaluated against.
|
||||||
case '&':
|
* The default implementation returns {@link DebugUITools#getDebugContext()}.
|
||||||
buffer.append("&"); //$NON-NLS-1$
|
*/
|
||||||
break;
|
protected IAdaptable getSelectionAdaptable() {
|
||||||
case '<':
|
return DebugUITools.getDebugContext();
|
||||||
buffer.append("<"); //$NON-NLS-1$
|
}
|
||||||
break;
|
|
||||||
case '>':
|
/**
|
||||||
buffer.append(">"); //$NON-NLS-1$
|
* Returns the editor this hover is associated with.
|
||||||
break;
|
*/
|
||||||
default:
|
protected final IEditorPart getEditor() {
|
||||||
buffer.append(ch);
|
return fEditor;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
/**
|
||||||
return buffer.toString();
|
* Append HTML for the given variable to the given buffer
|
||||||
}
|
*/
|
||||||
}
|
private static void appendVariable(StringBuilder 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$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace any characters in the given String that would confuse an HTML parser with their escape sequences.
|
||||||
|
*/
|
||||||
|
private static String makeHTMLSafe(String string) {
|
||||||
|
StringBuilder buffer = new StringBuilder(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;
|
||||||
|
case '"':
|
||||||
|
buffer.append("""); //$NON-NLS-1$
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buffer.append(ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue