| /******************************************************************************* |
| * Copyright (c) 2000, 2017 IBM Corporation and others. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.internal.debug.ui; |
| |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.debug.core.DebugException; |
| import org.eclipse.debug.core.model.IVariable; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.dltk.core.ICodeAssist; |
| import org.eclipse.dltk.core.IField; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.dbgp.IDbgpProperty; |
| import org.eclipse.dltk.dbgp.commands.IDbgpPropertyCommands; |
| import org.eclipse.dltk.debug.core.model.IScriptStackFrame; |
| import org.eclipse.dltk.debug.core.model.IScriptValue; |
| import org.eclipse.dltk.debug.ui.DLTKDebugUIPlugin; |
| import org.eclipse.dltk.debug.ui.ScriptDebugModelPresentation; |
| import org.eclipse.dltk.internal.debug.core.model.ScriptValue; |
| import org.eclipse.dltk.internal.ui.text.HTMLTextPresenter; |
| import org.eclipse.dltk.internal.ui.text.ScriptWordFinder; |
| import org.eclipse.dltk.ui.DLTKUIPlugin; |
| import org.eclipse.dltk.ui.text.hover.IScriptEditorTextHover; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.text.DefaultInformationControl; |
| 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.swt.SWT; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.editors.text.EditorsUI; |
| |
| public abstract class ScriptDebugHover |
| implements IScriptEditorTextHover, ITextHoverExtension { |
| |
| private IEditorPart editor; |
| |
| @Override |
| public void setEditor(IEditorPart editor) { |
| this.editor = editor; |
| } |
| |
| @Override |
| public IRegion getHoverRegion(final ITextViewer textViewer, int offset) { |
| return ScriptWordFinder.findWord(textViewer.getDocument(), offset); |
| } |
| |
| /** |
| * Returns the stack frame in which to search for variables, or |
| * <code>null</code> if none. |
| * |
| * @return the stack frame in which to search for variables, or |
| * <code>null</code> if none |
| */ |
| protected IScriptStackFrame getFrame() { |
| IAdaptable adaptable = DebugUITools.getDebugContext(); |
| if (adaptable != null) { |
| return adaptable.getAdapter(IScriptStackFrame.class); |
| } |
| return null; |
| } |
| |
| @Override |
| public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { |
| IScriptStackFrame frame = getFrame(); |
| if (frame == null || editor == null) |
| return null; |
| |
| IEditorInput input = editor.getEditorInput(); |
| Object element = DLTKUIPlugin.getDefault().getWorkingCopyManager() |
| .getWorkingCopy(input); |
| |
| if (!(element instanceof ICodeAssist)) |
| return null; |
| |
| ICodeAssist codeAssist = (ICodeAssist) element; |
| IModelElement[] resolve = null; |
| try { |
| resolve = codeAssist.codeSelect(hoverRegion.getOffset(), |
| hoverRegion.getLength()); |
| |
| IDbgpPropertyCommands propCmds = frame.getScriptThread() |
| .getDbgpSession().getCoreCommands(); |
| |
| for (int i = 0; i < resolve.length; i++) { |
| IModelElement scriptElement = resolve[i]; |
| if (scriptElement instanceof IField) { |
| IField field = (IField) scriptElement; |
| String snippet = getFieldProperty(field); |
| try { |
| IDbgpProperty property = propCmds.getProperty(snippet); |
| return getResultText(snippet, |
| ScriptValue.createValue(frame, property)); |
| } catch (DebugException e) { |
| } |
| } |
| } |
| } catch (Exception e) { |
| } |
| return null; |
| } |
| |
| protected String getFieldProperty(IField field) { |
| String snippet = field.getElementName(); |
| return snippet; |
| } |
| |
| protected String getResultText(String snippet, IScriptValue value) |
| throws DebugException { |
| String str = getModelPresentation().getText(value); |
| return prepareHtml(snippet + " = " + str); //$NON-NLS-1$ |
| } |
| |
| protected String getVariableText(IVariable variable) throws DebugException { |
| return prepareHtml(getModelPresentation().getText(variable)); |
| } |
| |
| protected String prepareHtml(String text) { |
| StringBuffer buffer = new StringBuffer(); |
| buffer.append("<p><pre>"); //$NON-NLS-1$ |
| buffer.append(replaceHTMLChars(text)); |
| buffer.append("</pre></p>"); //$NON-NLS-1$ |
| if (buffer.length() > 0) { |
| return buffer.toString(); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Replaces reserved HTML characters in the given string with their escaped |
| * equivalents. This is to ensure that variable values containing reserved |
| * characters are correctly displayed. |
| */ |
| private static String replaceHTMLChars(String variableText) { |
| StringBuffer buffer = new StringBuffer(variableText.length()); |
| char[] characters = variableText.toCharArray(); |
| for (int i = 0; i < characters.length; i++) { |
| char character = characters[i]; |
| switch (character) { |
| 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(character); |
| } |
| } |
| return buffer.toString(); |
| } |
| |
| /** |
| * Returns the value of this filters preference (on/off) for the given view. |
| * |
| * @param part |
| * @return boolean |
| */ |
| public static boolean getBooleanPreferenceValue(String id, |
| String preference) { |
| String compositeKey = id + "." + preference; //$NON-NLS-1$ |
| IPreferenceStore store = DLTKDebugUIPlugin.getDefault() |
| .getPreferenceStore(); |
| boolean value = false; |
| if (store.contains(compositeKey)) { |
| value = store.getBoolean(compositeKey); |
| } else { |
| value = store.getBoolean(preference); |
| } |
| return value; |
| } |
| |
| @Override |
| public IInformationControlCreator getHoverControlCreator() { |
| return parent -> new DefaultInformationControl(parent, SWT.NONE, |
| new HTMLTextPresenter(true), |
| EditorsUI.getTooltipAffordanceString()); |
| } |
| |
| /** |
| * Returns a configured model presentation for use displaying variables. |
| */ |
| protected abstract ScriptDebugModelPresentation getModelPresentation(); |
| } |