| /******************************************************************************* |
| * Copyright (c) 2011, 2012 Sierra Wireless 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: |
| * Sierra Wireless - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ldt.debug.ui.internal; |
| |
| import java.net.URI; |
| import java.text.MessageFormat; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.debug.core.DebugException; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.model.ISourceLocator; |
| import org.eclipse.debug.core.model.IVariable; |
| import org.eclipse.dltk.debug.core.DLTKDebugConstants; |
| import org.eclipse.dltk.debug.core.model.IScriptStackFrame; |
| import org.eclipse.dltk.debug.core.model.IScriptThread; |
| import org.eclipse.dltk.debug.core.model.IScriptVariable; |
| import org.eclipse.dltk.debug.ui.ScriptDebugModelPresentation; |
| import org.eclipse.dltk.internal.debug.core.model.ScriptVariableWrapper; |
| import org.eclipse.dltk.ui.DLTKUIPlugin; |
| import org.eclipse.jface.resource.ImageRegistry; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.ldt.debug.core.internal.LuaCoroutine; |
| import org.eclipse.ldt.debug.core.internal.LuaDebugConstants; |
| import org.eclipse.ldt.debug.core.internal.LuaModuleURIUtil; |
| import org.eclipse.ldt.debug.core.internal.UnreachableStackFrame; |
| import org.eclipse.ldt.ui.internal.editor.LuaEditor; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.part.FileEditorInput; |
| import org.eclipse.ui.texteditor.IDocumentProvider; |
| |
| public class LuaDebugModelPresentation extends ScriptDebugModelPresentation { |
| |
| /** |
| * @see org.eclipse.dltk.debug.ui.ScriptDebugModelPresentation#getEditorId(org.eclipse.ui.IEditorInput, java.lang.Object) |
| */ |
| @Override |
| public String getEditorId(IEditorInput input, Object element) { |
| return LuaEditor.EDITOR_ID; |
| } |
| |
| /** |
| * @see org.eclipse.dltk.debug.ui.ScriptDebugModelPresentation#getStackFrameImage(org.eclipse.dltk.debug.core.model.IScriptStackFrame) |
| */ |
| @Override |
| protected Image getStackFrameImage(IScriptStackFrame stackFrame) { |
| UnreachableStackFrame uStackFrame = UnreachableStackFrame.checkReachable(stackFrame); |
| if (uStackFrame != null) { |
| ImageRegistry reg = Activator.getDefault().getImageRegistry(); |
| if (uStackFrame.getReason().equals(UnreachableStackFrame.CCODE_SCHEME)) { |
| return reg.get(ImageConstants.LUA_DEBUG_CCODE_STACK_FRAME); |
| } |
| return reg.get(ImageConstants.LUA_DEBUG_UNREACHABLE_STACK_FRAME); |
| } |
| return super.getStackFrameImage(stackFrame); |
| } |
| |
| @Override |
| protected String getStackFrameText(IScriptStackFrame stackFrame) { |
| String sourceLine = getSourceLine(stackFrame); |
| String sourceLocation = getSourceLocation(stackFrame); |
| return MessageFormat.format("{0} [ {1} ]", sourceLine, sourceLocation); //$NON-NLS-1$ |
| } |
| |
| /** |
| * @param stackFrame |
| * @return |
| */ |
| private String getSourceLocation(IScriptStackFrame stackFrame) { |
| URI sourceURI = stackFrame.getSourceURI(); |
| |
| // get location |
| String location; |
| if (DLTKDebugConstants.FILE_SCHEME.equalsIgnoreCase(sourceURI.getScheme())) { |
| IPath path; |
| try { |
| // TODO not the good way to found the relative path |
| path = getStackFrameRelativePath(stackFrame); |
| } catch (CoreException e) { |
| Activator.logWarning("unable to extract relative path", e); //$NON-NLS-1$ |
| path = new Path(sourceURI.getPath()); |
| } |
| location = path.toString(); |
| } else if (LuaModuleURIUtil.isModuleURI(sourceURI)) { |
| location = LuaModuleURIUtil.getModuleName(sourceURI); |
| } else if (UnreachableStackFrame.CCODE_SCHEME.equalsIgnoreCase(sourceURI.getScheme())) { |
| location = Messages.LuaDebugModelPresentation_ccode; |
| } else if (UnreachableStackFrame.TAIL_RETURN_SCHEME.equalsIgnoreCase(sourceURI.getScheme())) { |
| location = Messages.LuaDebugModelPresentation_tail_return; |
| } else if (DLTKDebugConstants.UNKNOWN_SCHEME.equalsIgnoreCase(sourceURI.getScheme())) { |
| location = Messages.LuaDebugModelPresentation_unknown; |
| } else { |
| location = Messages.LuaDebugModelPresentation_unknown; |
| Activator.logWarning("unsupported uri :" + sourceURI); //$NON-NLS-1$ |
| } |
| |
| // get line number |
| int lineNumber = -1; |
| try { |
| lineNumber = stackFrame.getLineNumber(); |
| } catch (DebugException e) { |
| Activator.logWarning("could not acces to stackframe line number for + sourceURI"); //$NON-NLS-1$ |
| } |
| |
| if (lineNumber > 0) |
| return MessageFormat.format("{0}:{1}", location, lineNumber); //$NON-NLS-1$ |
| else |
| return location; |
| } |
| |
| private String getSourceLine(IScriptStackFrame stackFrame) { |
| // get source line from debug model (so debug client) |
| String sourceLine = stackFrame.getSourceLine(); |
| |
| // if not found, try to found in source file. |
| if (sourceLine == null || sourceLine.length() == 0) { |
| final ILaunch launch = stackFrame.getLaunch(); |
| final ISourceLocator sourceLocator = launch.getSourceLocator(); |
| if (sourceLocator != null) { |
| final Object object = sourceLocator.getSourceElement(stackFrame); |
| |
| if (object instanceof IFile) { |
| final IDocumentProvider provider = DLTKUIPlugin.getDocumentProvider(); |
| |
| final IDocument document = provider.getDocument(new FileEditorInput((IFile) object)); |
| |
| if (document != null) { |
| try { |
| sourceLine = retrieveStackFrameLine(stackFrame, document); |
| } catch (BadLocationException e) { |
| Activator.logWarning("unnable to retrieve stack frame line", e); //$NON-NLS-1$ |
| } catch (DebugException e) { |
| Activator.logWarning("unnable to retrieve stack frame line", e); //$NON-NLS-1$ |
| } |
| } |
| } |
| } |
| } |
| |
| // if not found, display just the stack level |
| if (sourceLine == null || sourceLine.length() == 0) { |
| final int level = stackFrame.getStack().size() - stackFrame.getLevel() - 1; |
| sourceLine = NLS.bind("Stack frame #{0}", Integer.valueOf(level)); //$NON-NLS-1$ |
| } |
| |
| if (sourceLine == null || sourceLine.length() == 0) |
| return ""; //$NON-NLS-1$ |
| else |
| return sourceLine; |
| |
| } |
| |
| private static String retrieveStackFrameLine(IScriptStackFrame frame, final IDocument document) throws BadLocationException, DebugException { |
| if (frame.getBeginLine() > 0 && frame.getEndLine() > 0) { |
| final IRegion region = document.getLineInformation(frame.getBeginLine() - 1); |
| final int start = region.getOffset() + frame.getBeginColumn(); |
| final int len; |
| if (frame.getBeginLine() == frame.getEndLine()) { |
| len = frame.getEndColumn() - frame.getBeginColumn() + 1; |
| } else { |
| len = region.getLength() - frame.getBeginColumn(); |
| } |
| return document.get(start, len).trim(); |
| } |
| final IRegion region = document.getLineInformation(frame.getLineNumber() - 1); |
| return document.get(region.getOffset(), region.getLength()).trim(); |
| } |
| |
| /** |
| * @see org.eclipse.dltk.debug.ui.ScriptDebugModelPresentation#getVariableName(org.eclipse.debug.core.model.IVariable) |
| */ |
| @Override |
| public String getVariableName(IVariable variable) throws DebugException { |
| // FIXME this is the only possible way to change a context name in DLTK |
| if (variable instanceof ScriptVariableWrapper |
| && variable.getName().equals(org.eclipse.dltk.internal.debug.core.model.Messages.ScriptStackFrame_classVariables)) { |
| return Messages.LuaDebugModelPresentation_upvalues; |
| } |
| return super.getVariableName(variable); |
| } |
| |
| /** |
| * @see org.eclipse.dltk.debug.ui.ScriptDebugModelPresentation#getVariableImage(org.eclipse.dltk.debug.core.model.IScriptVariable) |
| */ |
| @Override |
| protected Image getVariableImage(IScriptVariable variable) { |
| try { |
| if (variable.getReferenceTypeName().equals(LuaDebugConstants.TYPE_SPECIAL)) { |
| return Activator.getDefault().getImageRegistry().get(ImageConstants.LUA_DEBUG_SPECIAL_VAR); |
| } |
| // CHECKSTYLE:OFF |
| } catch (DebugException e) { |
| // do nothing and so return variable image |
| // CHECKSTYLE:ON |
| } |
| return super.getVariableImage(variable); |
| } |
| |
| /** |
| * @see org.eclipse.dltk.debug.ui.ScriptDebugModelPresentation#getThreadText(org.eclipse.dltk.debug.core.model.IScriptThread) |
| */ |
| @Override |
| protected String getThreadText(IScriptThread thread) { |
| if (thread instanceof LuaCoroutine) { |
| try { |
| return NLS.bind(Messages.LuaDebugModelPresentation_pause_coroutine, thread.getName()); |
| } catch (DebugException e) { |
| Activator.logError("Cannot get name of coroutine", e); //$NON-NLS-1$ |
| } |
| } |
| return NLS.bind(Messages.LuaDebugModelPresentation_running_coroutine, (thread.isSuspended() ? SUSPENDED_LABEL : RUNNING_LABEL)); |
| } |
| } |