/******************************************************************************* * Copyright (c) 2005, 2012 eBay Inc. * 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 * *******************************************************************************/ package org.eclipse.vjet.eclipse.internal.debug.ui; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IStorage; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.ILineBreakpoint; import org.eclipse.dltk.mod.compiler.env.ISourceModule; import org.eclipse.dltk.mod.core.Flags; import org.eclipse.dltk.mod.core.ICodeAssist; import org.eclipse.dltk.mod.core.IMember; import org.eclipse.dltk.mod.core.IMethod; import org.eclipse.dltk.mod.core.IModelElement; import org.eclipse.dltk.mod.core.IType; import org.eclipse.dltk.mod.core.ModelException; import org.eclipse.dltk.mod.debug.core.DLTKDebugPlugin; import org.eclipse.dltk.mod.debug.core.model.IScriptLineBreakpoint; import org.eclipse.dltk.mod.debug.core.model.IScriptMethodEntryBreakpoint; import org.eclipse.dltk.mod.debug.ui.breakpoints.BreakpointUtils; import org.eclipse.dltk.mod.debug.ui.breakpoints.ScriptToggleBreakpointAdapter; import org.eclipse.dltk.mod.internal.debug.core.model.AbstractScriptBreakpoint; import org.eclipse.dltk.mod.internal.debug.core.model.ScriptDebugModel; import org.eclipse.dltk.mod.internal.ui.editor.ExternalStorageEditorInput; import org.eclipse.dltk.mod.internal.ui.editor.ScriptEditor; import org.eclipse.dltk.mod.internal.ui.editor.WorkingCopyManager; import org.eclipse.dltk.mod.ui.DLTKUIPlugin; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.vjet.eclipse.debug.ui.VjetDebugUIPlugin; import org.eclipse.vjet.eclipse.internal.debug.VjetDebugConstants; import org.eclipse.vjet.eclipse.internal.launching.VjoDBGPSourceModule; public class VjetToggleBreakpointAdapter extends ScriptToggleBreakpointAdapter { private DBGPScriptCacheManager m_cacheManger = DBGPScriptCacheManager .getDefault(); @Override protected String getDebugModelId() { return VjetDebugConstants.DEBUG_MODEL_ID; } public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) { return true; } public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException { if (selection instanceof ITextSelection) { ITextEditor textEditor = getTextEditor(part); ITextSelection textSelection = (ITextSelection) selection; int lineNumber = textSelection.getStartLine() + 1; // one based ILineBreakpoint breakpoint = BreakpointUtils.findLineBreakpoint( textEditor, lineNumber); if (breakpoint != null) { breakpoint.delete(); return; } if (textEditor instanceof ScriptEditor) { ScriptEditor scriptEditor = (ScriptEditor) textEditor; try { IDocument doc = scriptEditor.getScriptSourceViewer() .getDocument(); IRegion region = doc.getLineInformation(lineNumber - 1); String string = doc.get(region.getOffset(), region .getLength()); int index = string.indexOf("function"); if (index != -1) { string = string.substring(index + "function".length()) .trim(); int apos = string.indexOf('('); if (apos >= 0) { string = string.substring(0, apos).trim(); } // createMethodEntryBreakpoint(textEditor, lineNumber, // string); // return; } } catch (BadLocationException e) { DLTKDebugPlugin.log(e); return; } } // else createLineBreakpoint(textEditor, lineNumber); } } public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) { if (isRemote(part, selection)) { return false; } if (selection instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) selection; return getMethods(ss).length > 0; } return (selection instanceof ITextSelection) && isMethod((ITextSelection) selection, part); } /** * Returns the methods from the selection, or an empty array * * @param selection * the selection to get the methods from * @return an array of the methods from the selection or an empty array */ protected IMethod[] getMethods(IStructuredSelection selection) { if (selection.isEmpty()) { return new IMethod[0]; } List methods = new ArrayList(selection.size()); Iterator iterator = selection.iterator(); while (iterator.hasNext()) { Object thing = iterator.next(); try { if (thing instanceof IMethod) { IMethod method = (IMethod) thing; if (!Flags.isAbstract(method.getFlags())) { methods.add(method); } } } catch (ModelException e) { } } return (IMethod[]) methods.toArray(new IMethod[methods.size()]); } /** * Returns if the text selection is a valid method or not * * @param selection * the text selection * @param part * the associated workbench part * @return true if the selection is a valid method, false otherwise */ private boolean isMethod(ITextSelection selection, IWorkbenchPart part) { ITextEditor editor = getTextEditor(part); if (editor != null) { IModelElement element = getJavaElement(editor.getEditorInput()); if (element != null) { try { if (element instanceof ISourceModule) { IModelElement[] elements = ((ICodeAssist) ((ISourceModule) element)) .codeSelect(selection.getOffset(), selection .getLength()); if(elements!=null){ element = elements.length > 0 ? elements[0] : null; } } // else if(element instanceof IClassFile) { // element = ((IClassFile) // element).getElementAt(selection.getOffset()); // } return element != null && element.getElementType() == IModelElement.METHOD; } catch (ModelException e) { return false; } } } return false; } /** * gets the <code>IModelElement</code> from the editor input * * @param input * the current editor input * @return the corresponding <code>IModelElement</code> * @since 3.3 */ private IModelElement getJavaElement(IEditorInput input) { IModelElement je = DLTKUIPlugin.getEditorInputModelElement(input); if (je != null) { return je; } // try to get from the working copy manager return ((WorkingCopyManager) DLTKUIPlugin.getDefault() .getWorkingCopyManager()).getWorkingCopy(input, false); // return DebugWorkingCopyManager.getWorkingCopy(input, false); } public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) { if (selection instanceof ITextSelection) { final ITextSelection textSelection = (ITextSelection) selection; final String text = textSelection.getText(); if (part instanceof ScriptEditor) { ScriptEditor scriptEditor = (ScriptEditor) part; try { IDocument doc = scriptEditor.getScriptSourceViewer() .getDocument(); IRegion region = doc.getLineInformation(textSelection .getStartLine()); String string = doc.get(region.getOffset(), region .getLength()); return string.indexOf('=') != -1 || string.trim().startsWith("var "); } catch (BadLocationException e) { DLTKUIPlugin.log(e); } } return text.indexOf("=") != -1; } return true; } /* * (non-Javadoc) * * @see * org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleMethodBreakpoints * (org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection) */ public void toggleMethodBreakpoints(final IWorkbenchPart part, final ISelection finalSelection) throws CoreException { if (!this.canToggleMethodBreakpoints(part, finalSelection)) return; IMethod[] methods = getMethods((IStructuredSelection) finalSelection); for (int i = 0; i < methods.length; i++) { try { ITextEditor textEditor = this.getTextEditor(methods[i]); /** * work out the script line number. To JFace, the first line has * line number 0; while to Script, the first line has line * number 1. */ IDocumentProvider documentProvider = (textEditor) .getDocumentProvider(); IDocument document = documentProvider.getDocument(textEditor .getEditorInput()); int methodSourceOffset = methods[i].getSourceRange() .getOffset(); int documentLineNumber = document .getLineOfOffset(methodSourceOffset); int scriptLineNumber = documentLineNumber + 1; // if already have line breakpoints, skip ILineBreakpoint breakpoint = BreakpointUtils .findLineBreakpoint(textEditor, scriptLineNumber); if (breakpoint != null) { breakpoint.delete(); continue; } else { createMethodEntryBreakpoint(textEditor, scriptLineNumber, ""); } } catch (Exception e) { VjetDebugUIPlugin.error(e.getLocalizedMessage(), e); } } } /** * fetch the corresponding text editor by the given method. * * @param method * @return */ private ITextEditor getTextEditor(IMethod method) { try { IResource resource = method.getResource(); IWorkbenchPage workbenchPage = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getActivePage(); return (ITextEditor) IDE .openEditor(workbenchPage, (IFile) resource); } catch (Exception e) { e.printStackTrace(); return null; } } /** * Returns if the structured selection is itself or is part of an interface * * @param selection * the current selection * @return true if the selection is part of an interface, false otherwise * @since 3.2 */ private boolean isInterface(ISelection selection, IWorkbenchPart part) { try { ISelection sel = selection; if (!(sel instanceof IStructuredSelection)) { sel = translateToMembers(part, selection); } if (sel instanceof IStructuredSelection) { Object obj = ((IStructuredSelection) sel).getFirstElement(); if (obj instanceof IMember) { IMember member = (IMember) ((IStructuredSelection) sel) .getFirstElement(); if (member.getElementType() == IModelElement.TYPE) { return Flags.isInterface(((IType) member).getFlags()); } return Flags.isInterface(member.getDeclaringType() .getFlags()); } // else if(obj instanceof i) { // IJavaFieldVariable var = (ijavafieldvariable) obj; // IType type = // JavaDebugUtils.resolveType(var.getDeclaringType()); // return type != null && type.isInterface(); // } } } catch (CoreException e1) { } return false; } public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException { toggleLineBreakpoints(part, selection); } private void createMethodEntryBreakpoint(ITextEditor textEditor, int lineNumber, String methodName) throws CoreException { IEditorInput editorInput = textEditor.getEditorInput(); IDocument document = textEditor.getDocumentProvider().getDocument( editorInput); IResource resource = BreakpointUtils.getBreakpointResource(textEditor); if (resource != null) { try { IRegion line = document.getLineInformation(lineNumber - 1); int start = line.getOffset(); int end = start + line.getLength() - 1; IPath path = resource.getLocation(); IScriptMethodEntryBreakpoint methodEntryBreakpoint = ScriptDebugModel .createMethodEntryBreakpoint(getDebugModelId(), resource, path, lineNumber, start, end, false, null, methodName); methodEntryBreakpoint.setBreakOnEntry(true); ((AbstractScriptBreakpoint) methodEntryBreakpoint) .register(true); if (needCache(editorInput)) { add2Cache(editorInput, methodEntryBreakpoint); } } catch (BadLocationException e) { VjetDebugUIPlugin.error(e.getLocalizedMessage(), e); } } } private void createLineBreakpoint(ITextEditor textEditor, int lineNumber) throws CoreException { IEditorInput editorInput = textEditor.getEditorInput(); IDocument document = textEditor.getDocumentProvider().getDocument( editorInput); IResource resource = BreakpointUtils.getBreakpointResource(textEditor); try { IRegion line = document.getLineInformation(lineNumber - 1); int start = line.getOffset(); int end = start + line.getLength(); IPath location = BreakpointUtils .getBreakpointResourceLocation(textEditor); IScriptLineBreakpoint breakpoint = ScriptDebugModel .createLineBreakpoint(getDebugModelId(), resource, location, lineNumber, start, end, true, null); // if editor input's storage is VjoDBGPSourceModule, add to cache. if (needCache(editorInput)) { add2Cache(editorInput, breakpoint); } } catch (BadLocationException e) { VjetDebugUIPlugin.error(e.getLocalizedMessage(), e); } } private void add2Cache(IEditorInput editorInput, IBreakpoint breakpoint) throws CoreException { m_cacheManger.add(breakpoint, getVjoDBGPSourceModule(editorInput)); } private boolean needCache(IEditorInput editorInput) { return getVjoDBGPSourceModule(editorInput) != null; } private VjoDBGPSourceModule getVjoDBGPSourceModule(IEditorInput editorInput) { if (editorInput instanceof ExternalStorageEditorInput) { IStorage storage = ((ExternalStorageEditorInput) editorInput) .getStorage(); if (storage instanceof VjoDBGPSourceModule) { return (VjoDBGPSourceModule) storage; } } return null; } }