diff options
author | Andrew Ferrazzutti | 2014-03-14 21:23:19 +0000 |
---|---|---|
committer | Sami Wagiaalla | 2014-04-24 14:27:56 +0000 |
commit | 57cfd3eb8ed44ca50e13b6607e6d2c1f69ed5cdc (patch) | |
tree | 1b2be2468bc0b163e7bdd3d65881922629eba78f /systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal | |
parent | 13141ef0f3db97139f92900952d3484be3cce30c (diff) | |
download | org.eclipse.linuxtools-57cfd3eb8ed44ca50e13b6607e6d2c1f69ed5cdc.tar.gz org.eclipse.linuxtools-57cfd3eb8ed44ca50e13b6607e6d2c1f69ed5cdc.tar.xz org.eclipse.linuxtools-57cfd3eb8ed44ca50e13b6607e6d2c1f69ed5cdc.zip |
Systemtap: More Probe & Function view fixes.
-Obtain static probes with a call to "stap --dump-probe-types" rather
than with a configuration file.
-Improve layout & organization of entries in the Probe Alias View.
-Correct the way probe groups are added to scripts (EBZ#431260).
-Create SharedParser to share stap -vp1 dumps among Probe & Function
parsers.
-Restore "View Definition" feature for Probe Alias view.
-Clean & improve "View Definition"'s means of searching for script
contents.
-Replace DefinitionAction with DefinitionHandler, and migrate plugin
implementation from Actions to Commands.
-Resolve EBZ #432768.
-Format .systemtap.ui.ide/plugin.xml.
-Update code completion for probes & its associated tests.
Change-Id: I24a8c89ea9fdd372efdff13f18d8bcebf5957d0b
Signed-off-by: Andrew Ferrazzutti <aferrazz@redhat.com>
Reviewed-on: https://git.eclipse.org/r/23878
Reviewed-by: Sami Wagiaalla <swagiaal@redhat.com>
Tested-by: Sami Wagiaalla <swagiaal@redhat.com>
Diffstat (limited to 'systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal')
31 files changed, 1073 insertions, 745 deletions
diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java index 21d538b399..5eb76a78a8 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/CommentRemover.java @@ -17,6 +17,7 @@ import java.io.IOException; /** * A helper class for removing comments from a SystemTap script. + * Note: if an entire line is a comment, it is replaced with a blank line. */ public final class CommentRemover { @@ -34,20 +35,29 @@ public final class CommentRemover { while ((line = br.readLine()) != null) { buffer.append(line.concat("\n")); //$NON-NLS-1$ } - return exec(buffer.toString()); + // No need to format line breaks, since this did it already with newlines. + return exec(buffer.toString(), false); } catch (IOException e) { return ""; //$NON-NLS-1$ } } + /** - * Remove comments from a .stp script. + * Remove comments from a .stp script. Also, line breaks will be formatted to newlines. * @param contents A complete .stp script. * @return A copy of the script with comments removed. */ public static String exec(String contents) { + return exec(contents, true); + } + + private static String exec(String contents, boolean standardizeLineBreaks) { if (contents == null || contents.isEmpty()) { return ""; //$NON-NLS-1$ } + if (standardizeLineBreaks) { + contents = doStandardizeLineBreaks(contents); + } char curchar, nxtchar; boolean inQuotes = false; @@ -64,18 +74,22 @@ public final class CommentRemover { if (!inQuotes) { if (!inComment) { if (curchar == '#' || (curchar == '/' && nxtchar == '/')) { - inQuotes = false; - c = contents.indexOf('\n', c + 1); + buffer.append('\n'); // Replace the rest of this line with a newline. + c = contents.indexOf('\n', c); // Skip past the next newline, if one exists. + if (c == -1) { + break; + } + c++; // Skip the newline character on the next character scan. continue; } if (curchar == '/' && nxtchar == '*') { inComment = true; - c++; //Skip the * on the next character scan. + c++; // Skip the * on the next character scan. continue; } } else if (curchar == '*' && nxtchar == '/') { inComment = false; - c++; //Skip the / on the next character scan. + c++; // Skip the / on the next character scan. continue; } } @@ -85,15 +99,22 @@ public final class CommentRemover { if (curchar == '\"') { inQuotes = !inQuotes; } - else if (curchar == '\n') { + else if (curchar == '\n' && inQuotes) { inQuotes = false; } - + buffer.append(curchar); + } + else if (curchar == '\n') { + // Print the line breaks of multiline comments. buffer.append(curchar); } - } while (c != -1 && c < contents.length()); + } while (c < contents.length()); return buffer.toString(); } + + private static String doStandardizeLineBreaks(String contents) { + return contents.replaceAll("(\\r\\n)|(\\n)", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + } }
\ No newline at end of file diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/BrowserViewAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/BrowserViewAction.java new file mode 100644 index 0000000000..098f110d9b --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/BrowserViewAction.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.views.BrowserView; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; + +public abstract class BrowserViewAction extends Action implements ISelectionListener, IDoubleClickListener { + private final IWorkbenchWindow window; + private final BrowserView viewer; + private IStructuredSelection selection; + private TreeExpandCollapseAction expandAction; + + /** + * The Default Constructor. Takes the <code>IWorkbenchWindow</code> that it effects + * as well as the <code>BrowserView</code> that will fire this action. + * @param window window effected by this event + * @param browser browser that fires this action + */ + public BrowserViewAction(IWorkbenchWindow window, BrowserView browser) { + this.window = window; + window.getSelectionService().addSelectionListener(this); + viewer = browser; + expandAction = new TreeExpandCollapseAction(viewer); + } + + public void dispose() { + window.getSelectionService().removeSelectionListener(this); + selection = null; + expandAction.dispose(); + expandAction = null; + } + + /** + * Updates <code>selection</code> with the current selection whenever the user changes + * the current selection. + */ + @Override + public void selectionChanged(IWorkbenchPart part, ISelection incoming) { + if (incoming instanceof IStructuredSelection) { + selection = (IStructuredSelection) incoming; + setEnabled(selection.size() == 1); + } else { + // Other selections, for example containing text or of other kinds. + setEnabled(false); + } + } + + @Override + public void doubleClick(DoubleClickEvent event) { + run(); + } + + protected IWorkbenchWindow getWindow() { + return window; + } + + protected Object getSelectedElement() { + return ((IStructuredSelection) viewer.getViewer().getSelection()).getFirstElement(); + } + + protected void runExpandAction() { + expandAction.run(); + } +}
\ No newline at end of file diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/DefinitionAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/DefinitionAction.java deleted file mode 100644 index 16ccf23a08..0000000000 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/DefinitionAction.java +++ /dev/null @@ -1,145 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 IBM Corporation. - * 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: - * IBM Corporation - Jeff Briggs, Henry Hughes, Ryan Morse - *******************************************************************************/ - -package org.eclipse.linuxtools.internal.systemtap.ui.ide.actions; - -import java.io.File; - -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; -import org.eclipse.linuxtools.systemtap.structures.FunctionNodeData; -import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; -import org.eclipse.linuxtools.systemtap.ui.editor.actions.file.OpenFileAction; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IObjectActionDelegate; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkbenchWindowActionDelegate; -import org.eclipse.ui.PlatformUI; - - - -/** - * This <code>Action</code> is used when the user right clicks on an item in the Tapset Browsers. - * Right-clicking on items in the browsers causes a menu item called "Go to definition" to appear, - * which fires this action upon selection. The result is that the file containing the definition - * for the entity that the user selected is opened in an <code>STPEditor</code> in the current window. - * @author Ryan Morse - * @see org.eclipse.jface.action.Action - * @see org.eclipse.linuxtools.internal.systemtap.ui.ide.views.TapsetBrowserView - */ -public class DefinitionAction extends Action implements IObjectActionDelegate, IWorkbenchWindowActionDelegate { - private IStructuredSelection selection = null; - - @Override - public void setActivePart(IAction action, IWorkbenchPart targetPart) { - } - - /** - * The main body of the event. This code gets the filename from the selected entry in the viewer, - * then opens a new <code>STPEditor</code> for that file. - */ - @Override - public void run(IAction action) { - if(!isEnabled()) - return; - Object o = selection.getFirstElement(); - if(!(o instanceof TreeDefinitionNode)) - return; - TreeDefinitionNode t = (TreeDefinitionNode)o; - String filename = t.getDefinition(); - File file = new File(filename); - OpenFileAction open = new OpenFileAction(); - open.run(file); - if (open.isSuccessful()) { - IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); - STPEditor editor = (STPEditor)editorPart; - int line; - - if (!(t.getData() instanceof FunctionNodeData)) - line = probeFind(t, editor); - else - line = functionFind(t, editor); - - editor.jumpToLocation(++line, 0); - } - } - - /** - * Tries to find the line of code that corresponds to the provided - * function node within the file open in the provided editor. - * @param t The tree node that we want to look up - * @param editor The STPEditor with the file we are searching in - * @return int representing the line where the node is defined - */ - private int functionFind(TreeDefinitionNode t, STPEditor editor) { - int line = editor.find(t.getData().toString()); - if(line < 0) { - line = editor.findRegex("(?<!\\w)function " + t.toString()); //$NON-NLS-1$ - if(line < 0) { - line = editor.find(t.toString()); - } - } - return Math.max(line, 0); - } - - /** - * Tries to find the line of code that corresponds to the provided - * probe node within the file open in the provided editor. - * @param t The tree node that we want to look up - * @param editor The STPEditor with the file we are searching in - * @return int representing the line where the node is defined - */ - private int probeFind(TreeDefinitionNode t, STPEditor editor) { - int line = editor.find("probe " + t.toString()); //$NON-NLS-1$ - - if(line < 0) - line = editor.find(t.getData().toString()); - if(line < 0) - line = editor.find(t.getData().toString().replace(" ", "")); //$NON-NLS-1$ //$NON-NLS-2$ - return Math.max(line, 0); - } - - /** - * Updates <code>selection</code> with the current selection whenever the user changes - * the current selection. - */ - @Override - public void selectionChanged(IAction action, ISelection selection) { - if(selection instanceof IStructuredSelection) { - this.selection = (IStructuredSelection)selection; - Object o = this.selection.getFirstElement(); - if(o instanceof TreeDefinitionNode) - { - TreeDefinitionNode t = (TreeDefinitionNode)o; - String s = t.getDefinition(); - if(s != null) - setEnabled(true); - else - setEnabled(false); - } - else - setEnabled(false); - } else { - this.setEnabled(false); - } - } - - @Override - public void init(IWorkbenchWindow window) {} - - @Override - public void dispose() {} - -} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java index 6503cef94d..256b91dcf5 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/FunctionBrowserAction.java @@ -11,11 +11,6 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.actions; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.linuxtools.internal.systemtap.ui.ide.Localization; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; import org.eclipse.linuxtools.internal.systemtap.ui.ide.views.FunctionBrowserView; @@ -24,9 +19,7 @@ import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.linuxtools.systemtap.ui.editor.actions.file.NewFileAction; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; @@ -45,51 +38,16 @@ import org.eclipse.ui.PartInitException; * @see org.eclipse.linuxtools.systemtap.ui.editor.SimpleEditor#insertTextAtCurrent(String) * @see org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.TreeExpandCollapseAction */ -public class FunctionBrowserAction extends Action implements ISelectionListener, IDoubleClickListener { - private final IWorkbenchWindow window; - private final FunctionBrowserView viewer; +public class FunctionBrowserAction extends BrowserViewAction { private static final String ID = "org.eclipse.linuxtools.systemtap.ui.ide.FunctionAction"; //$NON-NLS-1$ - private IStructuredSelection selection; - private TreeExpandCollapseAction expandAction; - /** - * The Default Constructor. Takes the <code>IWorkbenchWindow</code> that it effects - * as well as the <code>FunctionBrowserView</code> that will fire this action. - * @param window window effected by this event - * @param browser browser that fires this action - */ public FunctionBrowserAction(IWorkbenchWindow window, FunctionBrowserView browser) { - this.window = window; + super(window, browser); setId(ID); setActionDefinitionId(ID); setText(Localization.getString("FunctionBrowserAction.Insert")); //$NON-NLS-1$ setToolTipText(Localization .getString("FunctionBrowserAction.InsertFunction")); //$NON-NLS-1$ - window.getSelectionService().addSelectionListener(this); - viewer = browser; - expandAction = new TreeExpandCollapseAction(viewer); - } - - public void dispose() { - window.getSelectionService().removeSelectionListener(this); - selection = null; - expandAction.dispose(); - expandAction = null; - } - - /** - * Updates <code>selection</code> with the current selection whenever the user changes - * the current selection. - */ - @Override - public void selectionChanged(IWorkbenchPart part, ISelection incoming) { - if (incoming instanceof IStructuredSelection) { - selection = (IStructuredSelection) incoming; - setEnabled(selection.size() == 1); - } else { - // Other selections, for example containing text or of other kinds. - setEnabled(false); - } } /** @@ -101,10 +59,8 @@ public class FunctionBrowserAction extends Action implements ISelectionListener, */ @Override public void run() { - IWorkbenchPage page = window.getActivePage(); - ISelection incoming = viewer.getViewer().getSelection(); - IStructuredSelection selection = (IStructuredSelection)incoming; - Object o = selection.getFirstElement(); + IWorkbenchPage page = getWindow().getActivePage(); + Object o = getSelectedElement(); if (o instanceof TreeNode) { TreeNode t = (TreeNode) o; if(t.isClickable()) { @@ -134,13 +90,9 @@ public class FunctionBrowserAction extends Action implements ISelectionListener, ExceptionErrorDialog.openError(Localization.getString("FunctionBrowserAction.UnableToInsertFunction"), e); //$NON-NLS-1$ } } else { - expandAction.run(); + runExpandAction(); } } } - @Override - public void doubleClick(DoubleClickEvent event) { - run(); - } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java index cb8cf75916..731c564e66 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ImportTapsetHandler.java @@ -14,17 +14,15 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.actions; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.PreferencesUtil; +import org.eclipse.ui.handlers.HandlerUtil; public class ImportTapsetHandler extends AbstractHandler { @Override public Object execute(ExecutionEvent event) { - Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); String pageID = "org.eclipse.linuxtools.systemtap.prefs.ide.tapsets"; //$NON-NLS-1$ - PreferencesUtil.createPreferenceDialogOn(shell, pageID, new String[]{pageID}, null).open(); + PreferencesUtil.createPreferenceDialogOn(HandlerUtil.getActiveShell(event), pageID, new String[]{pageID}, null).open(); return null; } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java index 2130d1a269..144ea758d9 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/KernelSourceAction.java @@ -12,11 +12,6 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.actions; import org.eclipse.core.filesystem.IFileStore; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDESessionSettings; import org.eclipse.linuxtools.internal.systemtap.ui.ide.Localization; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; @@ -25,9 +20,7 @@ import org.eclipse.linuxtools.systemtap.graphing.ui.widgets.ExceptionErrorDialog import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; @@ -44,13 +37,9 @@ import org.eclipse.ui.ide.FileStoreEditorInput; * @see org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.TreeExpandCollapseAction * @see org.eclipse.linuxtools.internal.systemtap.ui.ide.views.KernelBrowserView */ -public class KernelSourceAction extends Action implements ISelectionListener, IDoubleClickListener { - private static final String CDT_EDITOR_ID = "org.eclipse.cdt.ui.editor.CEditor"; //$NON-NLS-1$ - private final IWorkbenchWindow window; +public class KernelSourceAction extends BrowserViewAction { public final static String ID = "org.eclipse.linuxtools.systemtap.ui.ide.KBAction"; //$NON-NLS-1$ - private KernelBrowserView viewer; - private IStructuredSelection selection; - private TreeExpandCollapseAction expandAction; + private static final String CDT_EDITOR_ID = "org.eclipse.cdt.ui.editor.CEditor"; //$NON-NLS-1$ /** * The default constructor for the <code>KernelSourceAction</code>. Takes the window that it affects @@ -59,34 +48,12 @@ public class KernelSourceAction extends Action implements ISelectionListener, ID * @param browser The <code>KernelBrowserView</code> that fires this action. */ public KernelSourceAction(IWorkbenchWindow window, KernelBrowserView browser) { - this.window = window; + super(window, browser); setId(ID); setActionDefinitionId(ID); setText(Localization.getString("KernelSourceAction.Insert")); //$NON-NLS-1$ setToolTipText(Localization .getString("KernelSourceAction.InsertSelectedFunction")); //$NON-NLS-1$ - window.getSelectionService().addSelectionListener(this); - viewer = browser; - expandAction = new TreeExpandCollapseAction(viewer); - } - - /** - * Updates <code>selection</code> with the current selection whenever the user changes - * the current selection. - */ - @Override - public void selectionChanged(IWorkbenchPart part, ISelection incoming) { - if (incoming instanceof IStructuredSelection) { - selection = (IStructuredSelection) incoming; - setEnabled(selection.size() == 1); - } else { - // Other selections, for example containing text or of other kinds. - setEnabled(false); - } - } - - public void dispose() { - window.getSelectionService().removeSelectionListener(this); } /** @@ -115,9 +82,7 @@ public class KernelSourceAction extends Action implements ISelectionListener, ID @Override public void run() { IWorkbench wb = PlatformUI.getWorkbench(); - ISelection incoming = viewer.getViewer().getSelection(); - IStructuredSelection selection = (IStructuredSelection)incoming; - Object o = selection.getFirstElement(); + Object o = getSelectedElement(); if(o instanceof TreeNode) { TreeNode t = (TreeNode)o; if(t.isClickable()) { @@ -136,16 +101,10 @@ public class KernelSourceAction extends Action implements ISelectionListener, ID } } - else - { - - expandAction.run(); + else { + runExpandAction(); } } } - @Override - public void doubleClick(DoubleClickEvent event) { - run(); - } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java index 0b145684e9..6d3de68a58 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/Messages.java @@ -24,13 +24,6 @@ public class Messages extends NLS { public static String RunScriptAction_alreadyRunningDialogTitle; public static String RunScriptAction_alreadyRunningDialogMessage; public static String RunScriptChartAction_couldNotSwitchToGraphicPerspective; - public static String ProbeAliasAction_SelectEditor; - public static String ProbeAliasAction_DialogTitle; - public static String ProbeAliasAction_AskBeforeAddMessage; - public static String ProbeAliasAction_AskBeforeAddYes; - public static String ProbeAliasAction_AskBeforeAddCancel; - public static String ProbeAliasAction_AskBeforeAddAnother; - public static String ProbeAliasAction_OtherFile; public static String DataSetFileExtension; public static String ExportDataSetAction_DialogTitle; public static String ImportDataSetAction_DialogTitle; diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java index 4a97882598..6b8489893f 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/ProbeAliasAction.java @@ -15,26 +15,21 @@ import java.text.MessageFormat; import java.util.LinkedList; import java.util.List; -import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.linuxtools.internal.systemtap.ui.ide.Localization; import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbeNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbevarNodeData; import org.eclipse.linuxtools.internal.systemtap.ui.ide.views.ProbeAliasBrowserView; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.linuxtools.systemtap.ui.editor.actions.file.NewFileAction; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.dialogs.ListDialog; @@ -50,46 +45,16 @@ import org.eclipse.ui.dialogs.ListDialog; * @see org.eclipse.linuxtools.internal.systemtap.ui.ide.views.ProbeAliasBrowserView * @see org.eclipse.jface.action.Action */ -public class ProbeAliasAction extends Action implements ISelectionListener, IDoubleClickListener { - private final IWorkbenchWindow window; - private final ProbeAliasBrowserView viewer; +public class ProbeAliasAction extends BrowserViewAction { private static final String ID = "org.eclipse.linuxtools.systemtap.ui.ide.ProbeAliasAction"; //$NON-NLS-1$ - private IStructuredSelection selection; - /** - * The Default Constructor. Takes the <code>IWorkbenchWindow</code> that it effects - * as well as the <code>ProbeAliasBrowserView</code> that will fire this action. - * @param window window effected by this event - * @param view browser that fires this action - */ public ProbeAliasAction(IWorkbenchWindow window, ProbeAliasBrowserView view) { - this.window = window; + super(window, view); setId(ID); setActionDefinitionId(ID); setText(Localization.getString("ProbeAliasAction.Insert")); //$NON-NLS-1$ setToolTipText(Localization .getString("ProbeAliasAction.InsertSelectedProbe")); //$NON-NLS-1$ - window.getSelectionService().addSelectionListener(this); - viewer = view; - } - - /** - * Updates <code>selection</code> with the current selection whenever the user changes - * the current selection. - */ - @Override - public void selectionChanged(IWorkbenchPart part, ISelection incoming) { - if (incoming instanceof IStructuredSelection) { - selection = (IStructuredSelection) incoming; - setEnabled(selection.size() == 1); - } else { - // Other selections, for example containing text or of other kinds. - setEnabled(false); - } - } - - public void dispose() { - window.getSelectionService().removeSelectionListener(this); } /** @@ -99,35 +64,34 @@ public class ProbeAliasAction extends Action implements ISelectionListener, IDou */ @Override public void run() { - IWorkbenchPage page = window.getActivePage(); - IEditorPart editor = page.getActiveEditor(); - if (!(editor instanceof STPEditor)) { - editor = findEditor(); - if (null == editor) { - return; + IWorkbenchPage page = getWindow().getActivePage(); + Object o = getSelectedElement(); + if (o instanceof TreeNode) { + TreeNode t = (TreeNode) o; + if (t.isClickable()) { + IEditorPart editor = page.getActiveEditor(); + if (!(editor instanceof STPEditor)) { + editor = findEditor(); + if (null == editor) { + return; + } + } + page.activate(editor); + buildString((STPEditor) editor, (TreeNode) o); + } else { + runExpandAction(); } } - page.activate(editor); - ISelection incoming = viewer.getViewer().getSelection(); - IStructuredSelection selection = (IStructuredSelection)incoming; - Object o = selection.getFirstElement(); - if (o instanceof TreeNode && editor instanceof STPEditor) { - buildString((STPEditor) editor, (TreeNode) o); - } } private void buildString(STPEditor stpeditor, TreeNode t) { //build the string StringBuilder s = new StringBuilder("\nprobe " + t.toString()); //$NON-NLS-1$ - if(!t.isClickable()) { - if(0 <t.getChildCount()) { - s.append(".*"); //$NON-NLS-1$ - } else { - return; - } + if (t.getChildCount() > 0 && t.getChildAt(0).getData() instanceof ProbeNodeData) { + s.append(".*"); //$NON-NLS-1$ } s.append("\n{\n"); //$NON-NLS-1$ - if(t.isClickable() && t.getChildCount() > 0) { + if (t.getChildCount() > 0 && t.getChildAt(0).getData() instanceof ProbevarNodeData) { s.append("\t/*\n\t * " + //$NON-NLS-1$ Localization .getString("ProbeAliasAction.AvailableVariables") + //$NON-NLS-1$ @@ -159,26 +123,26 @@ public class ProbeAliasAction extends Action implements ISelectionListener, IDou return ref.getEditor(false); } - private IEditorPart findEditor() { - final List<IEditorPart> allEditors = new LinkedList<>(); - for (IEditorReference ref : window.getActivePage().getEditorReferences()) { + private STPEditor findEditor() { + final List<STPEditor> allEditors = new LinkedList<>(); + for (IEditorReference ref : getWindow().getActivePage().getEditorReferences()) { IEditorPart editor = getRestoredEditor(ref); if (editor instanceof STPEditor) { - allEditors.add(editor); + allEditors.add((STPEditor) editor); } } switch (allEditors.size()) { // If only one file is found, open it. Give user the option to open another file. case 1: - MessageDialog messageDialog = new MessageDialog(window.getShell(), - Messages.ProbeAliasAction_DialogTitle, null, - MessageFormat.format(Messages.ProbeAliasAction_AskBeforeAddMessage, + MessageDialog messageDialog = new MessageDialog(getWindow().getShell(), + Localization.getString("ProbeAliasAction.DialogTitle"), null, //$NON-NLS-1$ + MessageFormat.format(Localization.getString("ProbeAliasAction.AskBeforeAddMessage"), //$NON-NLS-1$ allEditors.get(0).getEditorInput().getName() ), MessageDialog.QUESTION, - new String[]{Messages.ProbeAliasAction_AskBeforeAddCancel, - Messages.ProbeAliasAction_AskBeforeAddAnother, - Messages.ProbeAliasAction_AskBeforeAddYes}, 2); + new String[]{Localization.getString("ProbeAliasAction.AskBeforeAddCancel"), //$NON-NLS-1$ + Localization.getString("ProbeAliasAction.AskBeforeAddAnother"), //$NON-NLS-1$ + Localization.getString("ProbeAliasAction.AskBeforeAddYes")}, 2); //$NON-NLS-1$ switch (messageDialog.open()) { case 2: @@ -191,19 +155,19 @@ public class ProbeAliasAction extends Action implements ISelectionListener, IDou return null; } - // If no files found, prompt user to open a new file + // If no files found, prompt user to open a new file case 0: return openNewFile(); - // If multiple files found, prompt user to select one of them + // If multiple files found, prompt user to select one of them default: return openNewFileFromMultiple(allEditors); } } - private IEditorPart openNewFileFromMultiple(final List<IEditorPart> allEditors) { - ListDialog listDialog = new ListDialog(window.getShell()); - listDialog.setTitle(Messages.ProbeAliasAction_DialogTitle); + private STPEditor openNewFileFromMultiple(final List<STPEditor> allEditors) { + ListDialog listDialog = new ListDialog(getWindow().getShell()); + listDialog.setTitle(Localization.getString("ProbeAliasAction.DialogTitle")); //$NON-NLS-1$ listDialog.setContentProvider(new ArrayContentProvider()); listDialog.setLabelProvider(new LabelProvider() { @@ -211,7 +175,7 @@ public class ProbeAliasAction extends Action implements ISelectionListener, IDou public String getText(Object element) { int i = (Integer) element; return i != -1 ? allEditors.get(i).getEditorInput().getName() - : Messages.ProbeAliasAction_OtherFile; + : Localization.getString("ProbeAliasAction.OtherFile"); //$NON-NLS-1$ } }); @@ -221,7 +185,7 @@ public class ProbeAliasAction extends Action implements ISelectionListener, IDou } editorIndexes[editorIndexes.length - 1] = -1; listDialog.setInput(editorIndexes); - listDialog.setMessage(Messages.ProbeAliasAction_SelectEditor); + listDialog.setMessage(Localization.getString("ProbeAliasAction.SelectEditor")); //$NON-NLS-1$ if (listDialog.open() == Window.OK) { int result = (Integer) listDialog.getResult()[0]; return result != -1 ? allEditors.get(result) : openNewFile(); @@ -230,17 +194,13 @@ public class ProbeAliasAction extends Action implements ISelectionListener, IDou return null; } - private IEditorPart openNewFile() { + private STPEditor openNewFile() { NewFileAction action = new NewFileAction(); action.run(); if (action.isSuccessful()) { - return window.getActivePage().getActiveEditor(); + return (STPEditor) getWindow().getActivePage().getActiveEditor(); } return null; } - @Override - public void doubleClick(DoubleClickEvent event) { - run(); - } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/messages.properties b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/messages.properties index ac795236a8..cc81c654d6 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/messages.properties +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/actions/messages.properties @@ -17,14 +17,6 @@ RunScriptAction_alreadyRunningDialogTitle=Script Already Running RunScriptAction_alreadyRunningDialogMessage=An instance of {0} is already running, and multiple instances cannot be running at the same time. Would you like to terminate it and start a new run? RunScriptChartAction_couldNotSwitchToGraphicPerspective=Could not open the Graph Selector Editor. -ProbeAliasAction_SelectEditor=Choose which script the selected probe will be added to. -ProbeAliasAction_DialogTitle=Add Probe To Script -ProbeAliasAction_AskBeforeAddMessage=The selected probe will be added to "{0}". Continue? -ProbeAliasAction_AskBeforeAddYes=Yes -ProbeAliasAction_AskBeforeAddCancel=Cancel -ProbeAliasAction_AskBeforeAddAnother=Choose another file -ProbeAliasAction_OtherFile=<Other File...> - DataSetFileExtension=*.set ExportDataSetAction_DialogTitle=Save Data Set of "{0}" ImportDataSetAction_DialogTitle=Import Data Set diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java index 2d29e77311..3d9791b27a 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPCompletionProcessor.java @@ -47,7 +47,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov private STPMetadataSingleton stpMetadataSingleton; - private static class Token implements IRegion{ + private static class Token implements IRegion { String tokenString; int offset; @@ -67,7 +67,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov } } - public STPCompletionProcessor(){ + public STPCompletionProcessor() { this.stpMetadataSingleton = STPMetadataSingleton.getInstance(); } @@ -80,7 +80,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov return computeCompletionProposals(viewer.getDocument(), offset); } - public ICompletionProposal[] computeCompletionProposals(IDocument document, int offset){ + public ICompletionProposal[] computeCompletionProposals(IDocument document, int offset) { ITypedRegion partition = null; boolean useGlobal = false; @@ -114,7 +114,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov Token previousToken = getPrecedingToken(document, offset - prefix.length() - 1); while (previousToken.tokenString.equals("=") || //$NON-NLS-1$ - previousToken.tokenString.equals(",") ){ //$NON-NLS-1$ + previousToken.tokenString.equals(",") ) { //$NON-NLS-1$ previousToken = getPrecedingToken(document, previousToken.offset - 1); previousToken = getPrecedingToken(document, previousToken.offset - 1); } @@ -125,7 +125,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov return NO_COMPLETIONS; } - if (prePrefix.startsWith("probe")){ //$NON-NLS-1$ + if (prePrefix.startsWith("probe")) { //$NON-NLS-1$ return getProbeCompletionList(prefix, offset); } @@ -154,7 +154,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov String[] completionData = stpMetadataSingleton.getFunctionCompletions(prefix); ICompletionProposal[] result = new ICompletionProposal[completionData.length]; int prefixLength = prefix.length(); - for (int i = 0; i < completionData.length; i++){ + for (int i = 0; i < completionData.length; i++) { result[i] = new CompletionProposal( completionData[i].substring(prefixLength) + "()", //$NON-NLS-1$ offset, @@ -169,7 +169,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov return result; } - private ICompletionProposal[] getProbeVariableCompletions(IDocument document, int offset, String prefix){ + private ICompletionProposal[] getProbeVariableCompletions(IDocument document, int offset, String prefix) { try { String probe; probe = getProbe(document, offset); @@ -189,8 +189,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov null, completionData[i] + " - variable", //$NON-NLS-1$ null, - TapsetLibrary - .getAndCacheDocumentation("probe::" + probe + "::" + variableName)); //$NON-NLS-1$ //$NON-NLS-2$ + TapsetLibrary.getAndCacheDocumentation("probe::" + probe + "::" + variableName)); //$NON-NLS-1$ //$NON-NLS-2$ } return result; } catch (BadLocationException e) { @@ -210,7 +209,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov * @throws BadLocationException * @throws BadPartitioningException */ - private String getProbe(IDocument document, int offset) throws BadLocationException, BadPartitioningException{ + private String getProbe(IDocument document, int offset) throws BadLocationException, BadPartitioningException { String probePoint = null; ITypedRegion partition @@ -219,7 +218,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov String probe = document.get(partition.getOffset(), partition.getLength()); // make sure that we are inside a probe - if (probe.startsWith(PROBE_KEYWORD)){ + if (probe.startsWith(PROBE_KEYWORD)) { probePoint = probe.substring(PROBE_KEYWORD.length(), probe.indexOf('{')); probePoint = probePoint.trim(); } @@ -227,16 +226,10 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov return probePoint; } - private ICompletionProposal[] getProbeCompletionList(String prefix, int offset){ + private ICompletionProposal[] getProbeCompletionList(String prefix, int offset) { prefix = canonicalizePrefix(prefix); - String[] completionData = stpMetadataSingleton.getCompletionResults(prefix); - - String manPrefix = "probe::"; //$NON-NLS-1$ - if (prefix.indexOf('.') == -1){ - manPrefix = "tapset::"; //$NON-NLS-1$ - } + String[] completionData = stpMetadataSingleton.getProbeCompletions(prefix); - // Build proposals and submit ICompletionProposal[] result = new ICompletionProposal[completionData.length]; for (int i = 0; i < completionData.length; i++) { result[i] = new CompletionProposal( @@ -247,7 +240,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov null, completionData[i], null, - TapsetLibrary.getAndCacheDocumentation(manPrefix + completionData[i])); + TapsetLibrary.getAndCacheDocumentation("probe::" + completionData[i])); //$NON-NLS-1$ } return result; @@ -256,45 +249,17 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov /** * Returns a standardized version of the given prefix so that completion matching * can be performed. - * For example for process("/some/long/path") this returns process("PATH"); + * For example for process("/some/long/path") this returns process(string); * @param prefix * @return */ private String canonicalizePrefix(String prefix) { - if (prefix.isEmpty()) - { + if (prefix.isEmpty()) { return ""; //$NON-NLS-1$ } - - if(prefix.matches("process\\(\".*\"\\).*")){ //$NON-NLS-1$ - prefix = prefix.replaceAll("process\\(\".*\"\\)", "process\\(\"PATH\"\\)"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - if(prefix.matches("process\\(\\d*\\).*")){ //$NON-NLS-1$ - prefix = prefix.replaceAll("process\\(\\d*\\)", "process\\(PID\\)"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - if(prefix.matches("procfs\\(\".*\"\\).*")){ //$NON-NLS-1$ - prefix = prefix.replaceAll("procfs\\(\".*\"\\)", "procfs\\(\"PATH\"\\)"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - if(prefix.matches(".*function\\(\".*\"\\).*")){ //$NON-NLS-1$ - prefix = prefix.replaceAll("function\\(\".*\"\\)", "function\\(\"PATTERN\"\\)"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - if(prefix.matches(".*module\\(\".*\"\\).*")){ //$NON-NLS-1$ - prefix = prefix.replaceAll("module\\(\".*\"\\)", "module\\(\"MPATTERN\"\\)"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - if(prefix.matches("jiffies\\(\\d*\\).*")){ //$NON-NLS-1$ - prefix = prefix.replaceAll("jiffies\\(\\d*\\)", "jiffies\\(N\\)"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - if(prefix.matches("randomize\\(\\d*\\).*")){ //$NON-NLS-1$ - prefix = prefix.replaceAll("randomize\\(\\d*\\)", "randomize\\(M\\)"); //$NON-NLS-1$ //$NON-NLS-2$ - } - + prefix = prefix.replaceAll("(?s)\\(\\s*\".*\"\\s*\\)", "(string)"); //$NON-NLS-1$ //$NON-NLS-2$ + prefix = prefix.replaceAll("(?s)\\(\\s*\\d*\\s*\\)", "(number)"); //$NON-NLS-1$ //$NON-NLS-2$ return prefix; } @@ -303,7 +268,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov ArrayList<ICompletionProposal> completions = new ArrayList<>(); int prefixLength = prefix.length(); for (String[] keyword : GLOBAL_KEYWORDS) { - if (keyword[0].startsWith(prefix)){ + if (keyword[0].startsWith(prefix)) { CompletionProposal proposal = new CompletionProposal( keyword[0].substring(prefixLength), offset, @@ -327,40 +292,40 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov * @return The preceding token. * @throws BadLocationException */ - private Token getPrecedingToken(IDocument doc, int offset) throws BadLocationException{ + private Token getPrecedingToken(IDocument doc, int offset) throws BadLocationException { // Skip trailing space int n = offset; - while (n >= 0 && Character.isSpaceChar(doc.getChar(n))){ + while (n >= 0 && Character.isSpaceChar(doc.getChar(n))) { n--; } char c = doc.getChar(n); - if(isTokenDelimiter(c)){ + if (isTokenDelimiter(c)) { return new Token(Character.toString(c), n); } int end = n; - while (n >= 0 && !isTokenDelimiter((doc.getChar(n)))){ + while (n >= 0 && !isTokenDelimiter((doc.getChar(n)))) { n--; } return new Token(doc.get(n+1, end-n), n+1); } - private Token getCurrentToken(IDocument doc, int offset) throws BadLocationException{ + private Token getCurrentToken(IDocument doc, int offset) throws BadLocationException { char c = doc.getChar(offset); - if(isDelimiter(c)){ + if (isDelimiter(c)) { return new Token(Character.toString(c), offset); } int start = offset; - while (start >= 0 && !isDelimiter((doc.getChar(start)))){ + while (start >= 0 && !isDelimiter((doc.getChar(start)))) { start--; } int end = offset; - while (end < doc.getLength() && !isDelimiter((doc.getChar(end)))){ + while (end < doc.getLength() && !isDelimiter((doc.getChar(end)))) { end++; } @@ -423,7 +388,7 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov return false; } - public void waitForInitialization(){ + public void waitForInitialization() { this.stpMetadataSingleton.waitForInitialization(); } @@ -476,21 +441,21 @@ public class STPCompletionProcessor implements IContentAssistProcessor, ITextHov String keyword = textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength()); documentation = TapsetLibrary.getDocumentation("function::" + keyword); //$NON-NLS-1$ - if (!documentation.startsWith("No manual entry for")){ //$NON-NLS-1$ + if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$ return documentation; } documentation = TapsetLibrary.getDocumentation("probe::" + keyword); //$NON-NLS-1$ - if (!documentation.startsWith("No manual entry for")){ //$NON-NLS-1$ + if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$ return documentation; } documentation = TapsetLibrary.getDocumentation("tapset::" + keyword); //$NON-NLS-1$ - if (!documentation.startsWith("No manual entry for")){ //$NON-NLS-1$ + if (!documentation.startsWith("No manual entry for")) { //$NON-NLS-1$ return documentation; } - if (keyword.indexOf('.') > 0){ + if (keyword.indexOf('.') > 0) { keyword = keyword.split("\\.")[0]; //$NON-NLS-1$ documentation = TapsetLibrary.getDocumentation("tapset::" + keyword); //$NON-NLS-1$ } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java index 46fbff435e..c91f2d3226 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/editors/stp/STPMetadataSingleton.java @@ -14,6 +14,9 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp; import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary; import org.eclipse.linuxtools.systemtap.structures.TreeNode; @@ -41,53 +44,33 @@ public final class STPMetadataSingleton { return instance; } - public void waitForInitialization(){ + public void waitForInitialization() { TapsetLibrary.waitForInitialization(); } - /** - * Given the parameter return the completion proposals that best match the data. - * - * @param match - completion hint. - * - * @return - completion proposals. - * - */ - public String[] getCompletionResults(String match) { + public String[] getFunctionCompletions(String prefix) { + TreeNode node = TapsetLibrary.getFunctions(); + return getMatchingChildren(node, prefix); + } - // Check to see if the proposal hint included a <tapset>.<partialprobe> - // or just a <probe>. (ie syscall. or syscall.re). - boolean tapsetAndProbeIncluded = match.indexOf('.') >= 0; + public String[] getProbeCompletions(String prefix) { + List<String> matches = new LinkedList<>(); + String groupName = extractProbeGroupName(prefix); - TreeNode node = TapsetLibrary.getProbes(); - if (node == null) { - return NO_MATCHES; - } - - // If the result is a tapset and partial probe, get the tapset, then - // narrow down the list with partial probe matches. - if (tapsetAndProbeIncluded) { - node = node.getChildByName(getTapset(match)); + for (TreeNode node : getEachProbeCategoryNode()) { if (node == null) { - return NO_MATCHES; + continue; } - // Now get the completions. - return getMatchingChildren(node, match); - } + TreeNode groupNode = node.getChildByName(groupName); + if (groupNode != null) { + node = groupNode; + } - // Now get the completions. - return getMatchingChildren(node, match); - } + matches.addAll(Arrays.asList(getMatchingChildren(node, prefix))); + } - /** - * Returns a list of functions that complete the given prefix. - * @param prefix - * @return - */ - public String[] getFunctionCompletions(String prefix) { - TreeNode node = TapsetLibrary.getFunctions(); - return getMatchingChildren(node, prefix); + return !matches.isEmpty() ? matches.toArray(new String[matches.size()]) : NO_MATCHES; } /** @@ -96,14 +79,14 @@ public final class STPMetadataSingleton { * @param prefix The prefix to complete. * @return a list of variables matching the prefix. */ - public String[] getProbeVariableCompletions(String probe, String prefix){ - TreeNode node = TapsetLibrary.getProbes(); + public String[] getProbeVariableCompletions(String probe, String prefix) { + // The only probes that may have avilable variables are non-static ones. + TreeNode node = TapsetLibrary.getProbeAliases(); if (node == null) { return NO_MATCHES; } - // Get the matching leaf node. - node = node.getChildByName(getTapset(probe)); + node = node.getChildByName(extractProbeGroupName(probe)); if (node == null) { return NO_MATCHES; } @@ -113,16 +96,19 @@ public final class STPMetadataSingleton { return NO_MATCHES; } - // Get the completions. return getMatchingChildren(node, prefix); } + private TreeNode[] getEachProbeCategoryNode() { + return new TreeNode[]{TapsetLibrary.getStaticProbes(), TapsetLibrary.getProbeAliases()}; + } + private String[] getMatchingChildren(TreeNode node, String prefix) { ArrayList<String> matches = new ArrayList<>(); int n = node.getChildCount(); for (int i = 0; i < n; i++) { - if (node.getChildAt(i).toString().startsWith(prefix)){ + if (node.getChildAt(i).toString().startsWith(prefix)) { matches.add(node.getChildAt(i).toString()); } } @@ -130,19 +116,19 @@ public final class STPMetadataSingleton { return matches.toArray(new String[0]); } - /** - * Given data, extract <tapset> - * - * @param data - hint data - * @return - */ - private String getTapset(String data) { - int i = data.indexOf('.'); - if (i < 0){ - return data; + private String extractProbeGroupName(String probeName) { + int dotIndex = probeName.indexOf('.'); + int parenIndex = probeName.indexOf('('); + if (dotIndex > 0 && parenIndex > 0) { + return probeName.substring(0, Math.min(dotIndex, parenIndex)); } - - return data.substring(0, data.indexOf('.')); + if (dotIndex > 0) { + return probeName.substring(0, dotIndex); + } + if (parenIndex > 0) { + return probeName.substring(0, parenIndex); + } + return probeName; } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java new file mode 100644 index 0000000000..bf1a52d35c --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionHandler.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.handlers; + +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.CommentRemover; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.editors.stp.STPEditor; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ISearchableNode; +import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; +import org.eclipse.linuxtools.systemtap.ui.editor.actions.file.OpenFileAction; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.handlers.HandlerUtil; + +public class DefinitionHandler extends AbstractHandler { + + @Override + public Object execute(ExecutionEvent event) { + TreeDefinitionNode t = getSelection(event); + if(t == null) { + return null; + } + String filename = t.getDefinition(); + if (filename == null) { + return null; + } + File file = new File(filename); + OpenFileAction open = new OpenFileAction(); + open.run(file); + if (open.isSuccessful() && t.getData() instanceof ISearchableNode) { + IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); + STPEditor editor = (STPEditor)editorPart; + editor.jumpToLocation(findDefinitionLine((ISearchableNode) t.getData(), editor) + 1, 0); + } + return null; + } + + private TreeDefinitionNode getSelection(ExecutionEvent event) { + ISelection selection = HandlerUtil.getCurrentSelection(event); + if (selection instanceof StructuredSelection) { + Object[] selections = ((StructuredSelection) selection).toArray(); + return (selections.length == 1 && selections[0] instanceof TreeDefinitionNode) + ? (TreeDefinitionNode) selections[0] : null; + } + return null; + } + + private int findDefinitionLine(ISearchableNode data, STPEditor editor) { + int locationIndex; + String contents = CommentRemover.exec(editor.getDocumentProvider().getDocument(editor.getEditorInput()).get()); + if (data.isRegexSearch()) { + Pattern pattern = Pattern.compile(data.getSearchToken()); + Matcher matcher = pattern.matcher(contents); + locationIndex = matcher.find() ? matcher.start() : -1; + } else { + locationIndex = contents.indexOf(data.getSearchToken()); + } + if (locationIndex != -1) { + // Get the line of the match by counting newlines. + contents = contents.substring(0, locationIndex); + return contents.length() - contents.replaceAll("\n", "").length(); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + return 0; + } + } + +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionMenuTester.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionMenuTester.java new file mode 100644 index 0000000000..904a982fd0 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/handlers/DefinitionMenuTester.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.handlers; + +import org.eclipse.core.expressions.PropertyTester; +import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; + +public class DefinitionMenuTester extends PropertyTester { + + @Override + public boolean test(Object receiver, String property, Object[] args, + Object expectedValue) { + return receiver instanceof TreeDefinitionNode + ? ((TreeDefinitionNode) receiver).getDefinition() != null + : false; + } + +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/localization.properties b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/localization.properties index bc4662e88b..dab8258343 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/localization.properties +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/localization.properties @@ -15,11 +15,21 @@ KernelSourceAction.InsertSelectedFunction=Insert the Selected Function ProbeAliasAction.Insert=&Insert ProbeAliasAction.InsertSelectedProbe=Insert the Selected Probe ProbeAliasAction.AvailableVariables=available variables on this probe: +ProbeAliasAction.SelectEditor=Choose which script the selected probe will be added to. +ProbeAliasAction.DialogTitle=Add Probe To Script +ProbeAliasAction.AskBeforeAddMessage=The selected probe will be added to "{0}". Continue? +ProbeAliasAction.AskBeforeAddYes=Yes +ProbeAliasAction.AskBeforeAddCancel=Cancel +ProbeAliasAction.AskBeforeAddAnother=Choose another file +ProbeAliasAction.OtherFile=<Other File...> FunctionBrowserAction.Insert=&Insert FunctionBrowserAction.InsertFunction=Insert the Selected Function FunctionBrowserAction.UnableToInsertFunction=Unable To Insert Function +DefinitionHandler.FileIOErrorTitle=File Error +DefinitionHandler.FileIOErrorMessage=Unable to open definition file. + CEditor.ProbeInsertFailed=Probe Insertion Failure CEditor.CanNotProbeLine=Stap cannot insert a probe on this line of code. diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java new file mode 100644 index 0000000000..f6212437dd --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FuncparamNodeData.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; + +import org.eclipse.linuxtools.systemtap.structures.TreeNode; + + +/** + * A structure for containing extra information of SystemTap function parameters. + * @since 3.0 + */ +public class FuncparamNodeData implements ISingleTypedNode { + + private final String line; + private final String type; + + @Override + public String toString() { + return line; + } + + @Override + public String getType() { + return type; + } + + /** + * Create a new instance of function parameter information. (Note that the name of a function + * or parameter is stored in a {@link TreeNode}, not here.) + * @param line The <code>String</code> representation of the entire parameter. + * @param type The <code>String</code> representation of only the parameter's type. + */ + public FuncparamNodeData(String line, String type) { + this.line = line; + this.type = type == null ? FunctionParser.UNKNOWN_TYPE : type; // Parameters can't be void. + } +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java new file mode 100644 index 0000000000..f18ed04680 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionNodeData.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - Initial API and implementation + *******************************************************************************/ +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; + +import org.eclipse.linuxtools.systemtap.structures.TreeNode; + + +/** + * A structure for containing extra information of SystemTap functions. + * @since 3.0 + */ +public class FunctionNodeData implements ISearchableNode, ISingleTypedNode { + private final String line; + private final String type; + + @Override + public boolean isRegexSearch() { + return false; + } + + /** + * @return the text to search a file with for the definition of this function. + */ + @Override + public String getSearchToken() { + return line; + } + + @Override + public String toString() { + return getSearchToken(); + } + + /** + * @return the <code>String</code> representation of the return type of the + * node's function (<code>null</code> for void functions). + */ + @Override + public String getType() { + return type; + } + + /** + * Create a new instance of function node information. (Note that the name of a function + * or parameter is stored in a {@link TreeNode}, not here.) + * @param line Set this to the original script text that defines this function. + * @param type The <code>String</code> representation of the return type of the function. + */ + public FunctionNodeData(String line, String type) { + this.line = line; + this.type = type; + } +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java index 64ec23a96b..904ac20c42 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/FunctionParser.java @@ -12,7 +12,7 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; import java.text.MessageFormat; -import java.util.StringTokenizer; +import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -21,26 +21,32 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.linuxtools.internal.systemtap.ui.ide.CommentRemover; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; -import org.eclipse.linuxtools.systemtap.structures.FunctionNodeData; import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; import org.eclipse.linuxtools.systemtap.structures.TreeNode; /** - * Runs stap -vp1 & stap -up2 in order to get all of the probes/functions - * that are defined in the tapsets. Builds probeAlias and function trees + * Runs stap -vp1 in order to get all of the functions + * that are defined in the tapsets. Builds function trees * with the values obtained from the tapsets. * - * Ugly code is a result of two issues with getting stap output. First, - * many tapsets do not work under stap -up2. Second since the output - * is not a regular language, we can't create a nice lexor/parser combination - * to do everything nicely. * @author Ryan Morse * @since 2.0 */ public class FunctionParser extends TapsetParser { - private TreeNode functions; static FunctionParser parser = null; + private TreeNode functions; + + /** + * The descriptor used for unresolvable types. + */ + public static final String UNKNOWN_TYPE = "unknown"; //$NON-NLS-1$ + + private static final String functionRegex = "(?s)(?<!\\w)function\\s+{0}(?:\\s*:\\s*(\\w+))?\\s*\\(([^)]+?)?\\)"; //$NON-NLS-1$ + private static final Pattern pFunction = Pattern.compile("function (?!_)(\\w+) \\(.*?\\)"); //$NON-NLS-1$ + private static final Pattern pParams = Pattern.compile("(\\w+)(?:\\s*:\\s*(\\w+))?"); //$NON-NLS-1$ + private static final Pattern pAllCaps = Pattern.compile("[A-Z_1-9]*"); //$NON-NLS-1$ + private static final Pattern pReturn = Pattern.compile("\\sreturn\\W"); //$NON-NLS-1$ public static FunctionParser getInstance(){ if (parser != null) { @@ -63,89 +69,97 @@ public class FunctionParser extends TapsetParser { return functions; } + /** + * This method will clean up everything from the run. + */ + public void dispose() { + functions.dispose(); + } + @Override protected IStatus run(IProgressMonitor monitor) { - runPass2Functions(); + boolean cancelled = runPass2Functions(); functions.sortTree(); fireUpdateEvent(); //Inform listeners that everything is done - return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ + return new Status(!cancelled ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ } /** * This method is used to build up the list of functions that were found * during the first pass of stap. Stap is invoked by: $stap -v -p1 -e * 'probe begin{}' and parsing the output. + * + * FunctionTree organized as: + * Root->Functions->Parameters + * + * @return <code>false</code> if a cancellation prevented all probes from being added; + * <code>true</code> otherwise. */ - private void runPass2Functions() { + private boolean runPass2Functions() { + String tapsetContents = SharedParser.getInstance().getTapsetContents(); + if (cancelRequested) { + return false; + } // Create a new function tree each time, so as to not add duplicates functions = new TreeNode("", false); //$NON-NLS-1$ - String script = "probe begin{}"; //$NON-NLS-1$ - String result = runStap(new String[] {"-v", "-p1", "-e"}, script, false); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - if (result == null) { - return; + if (tapsetContents == null) { + // Functions are only drawn from the tapset dump, so exit if it's empty. + return true; } - StringTokenizer st = new StringTokenizer(result, "\n", false); //$NON-NLS-1$ - st.nextToken(); //skip that stap command - String tok = ""; //$NON-NLS-1$ - String filename = null; - String scriptText = null; - - String functionRegex = "(?s)(?<!\\w)function\\s+({0})(?:\\s*:\\s*(\\w+))?\\s*\\(([^)]+?)?\\)"; //$NON-NLS-1$ - // Get functions (with proper typing) directly from the .stp files being used by stap. - Pattern pFilename = Pattern.compile("# file (/.*\\.stp)"); //$NON-NLS-1$ - Pattern pFunction = Pattern.compile("function (?!_)(\\w+) \\(.*?\\)"); //Ignore functions starting with _. //$NON-NLS-1$ - Pattern pParams = Pattern.compile("(\\w+)(?:\\s*:\\s*(\\w+))?"); //$NON-NLS-1$ - Pattern pAllCaps = Pattern.compile("[A-Z_1-9]*"); //$NON-NLS-1$ - Pattern pReturn = Pattern.compile("\\sreturn\\W"); //$NON-NLS-1$ - - while(st.hasMoreTokens()) { - tok = st.nextToken(); - Matcher mFilename = pFilename.matcher(tok); - if(mFilename.matches()) { - filename = mFilename.group(1).toString(); - scriptText = null; - } else if (filename != null) { - Matcher mFunction = pFunction.matcher(tok); - if(mFunction.matches()) { - // Ignore ALL_CAPS functions, since they are not meant for end-user use. - String functionName = mFunction.group(1); - if (pAllCaps.matcher(functionName).matches()) { - continue; - } - if (scriptText == null) { - scriptText = CommentRemover.execWithFile(filename); - } - Matcher mScript = Pattern.compile(MessageFormat.format(functionRegex, functionName)).matcher(scriptText); - while (mScript.find()) { - String functionLine = mScript.group(); - String functionType = mScript.group(2); - // If the function has no return type, look for a "return" statement to check - // if it's really a void function, or if its return type is just unspecified - if (functionType == null && searchForPattern(scriptText, mScript.end(), pReturn)) { - functionType = FunctionNodeData.UNKNOWN_TYPE; + try (Scanner st = new Scanner(tapsetContents)) { + String filename = null; + String scriptText = null; + + SharedParser sparser = SharedParser.getInstance(); + while (st.hasNextLine()) { + if (cancelRequested) { + return false; + } + String tok = st.nextLine(); + Matcher mFilename = sparser.filePattern.matcher(tok); + if (mFilename.matches()) { + filename = mFilename.group(1).toString(); + scriptText = null; + } else if (filename != null) { + Matcher mFunction = pFunction.matcher(tok); + if (mFunction.matches()) { + String functionName = mFunction.group(1); + if (pAllCaps.matcher(functionName).matches()) { + // Ignore ALL_CAPS functions, since they are not meant for end-user use. + continue; } - TreeDefinitionNode function = new TreeDefinitionNode( - new FunctionNodeData(functionLine, functionType), - functionName, filename, true); - functions.add(function); - // Add all function parameters that exist - String params = mScript.group(3); - if (params != null) { - Matcher mParams = pParams.matcher(params); - while (mParams.find()) { - function.add(new TreeNode( - new FunctionNodeData(null, mParams.group(2)), - mParams.group(1), false)); - } + if (scriptText == null) { + // If this is the first time seeing this file, remove its comments. + scriptText = CommentRemover.execWithFile(filename); } + addFunctionFromScript(functionName, scriptText, filename); } } } + return true; + } + } + + private void addFunctionFromScript(String functionName, String scriptText, String scriptFilename) { + String regex = MessageFormat.format(functionRegex, functionName); + Matcher mScript = Pattern.compile(regex).matcher(scriptText); + if (mScript.find()) { + String functionLine = mScript.group(); + String functionType = mScript.group(1); + // If the function has no return type, look for a "return" statement to check + // if it's really a void function, or if its return type is just unspecified + if (functionType == null && getNextBlockContents(scriptText, mScript.end(), pReturn)) { + functionType = UNKNOWN_TYPE; + } + TreeDefinitionNode function = new TreeDefinitionNode( + new FunctionNodeData(functionLine, functionType), + functionName, scriptFilename, true); + functions.add(function); + addParamsFromString(mScript.group(2), function); } - functions.sortTree(); } - private boolean searchForPattern(String scriptText, int start, Pattern p) { + private boolean getNextBlockContents(String scriptText, int start, Pattern p) { int end, bcount = 1; start = scriptText.indexOf('{', start) + 1; for (end = start; end < scriptText.length(); end++) { @@ -159,11 +173,15 @@ public class FunctionParser extends TapsetParser { return p.matcher(scriptText.substring(start, end)).find(); } - /** - * This method will clean up everything from the run. - */ - public void dispose() { - functions.dispose(); + private void addParamsFromString(String params, TreeNode parentFunction) { + if (params != null) { + Matcher mParams = pParams.matcher(params); + while (mParams.find()) { + parentFunction.add(new TreeNode( + new FuncparamNodeData(mParams.group(), mParams.group(2)), + mParams.group(1), false)); + } + } } } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java new file mode 100644 index 0000000000..3f4d38afad --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISearchableNode.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; + +public interface ISearchableNode { + String getSearchToken(); + boolean isRegexSearch(); +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java new file mode 100644 index 0000000000..de90470e71 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ISingleTypedNode.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; + +public interface ISingleTypedNode { + String getType(); +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java index 1946ba0c56..7c1a611396 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/Messages.java @@ -18,6 +18,8 @@ import org.eclipse.osgi.util.NLS; public class Messages extends NLS { private static final String BUNDLE_NAME = "org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.messages"; //$NON-NLS-1$ public static String ProbeParser_errorInitializingStaticProbes; + public static String ProbeParser_staticProbes; + public static String ProbeParser_aliasProbes; public static String TapsetParser_CannotRunStapMessage; public static String TapsetParser_CannotRunStapTitle; public static String TapsetParser_ErrorRunningSystemtap; diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java new file mode 100644 index 0000000000..20e7f050cc --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeNodeData.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; + +import java.text.MessageFormat; + +public class ProbeNodeData implements ISearchableNode { + + private final String name; + + @Override + public boolean isRegexSearch() { + return true; + } + + /** + * @return a regex to search a file with for the definition of this probe. + */ + @Override + public String getSearchToken() { + return MessageFormat.format(ProbeParser.probeRegex, name); + } + + @Override + public String toString() { + return getSearchToken(); + } + + /** + * Create a new instance of probe node information. + * @param line A line of text generated by running "stap -L" which + * provides all information pertaining to a probe point, or at least + * the probe's name. + */ + public ProbeNodeData(String line) { + int spaceIndex = line.indexOf(' '); + name = (spaceIndex != -1 ? line.substring(0, spaceIndex) : line).trim(); + } + +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java index 3ced2b4dd0..1ea2da3701 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbeParser.java @@ -11,38 +11,35 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.net.URL; +import java.text.MessageFormat; +import java.util.Scanner; import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; -import org.eclipse.linuxtools.systemtap.graphing.ui.widgets.ExceptionErrorDialog; import org.eclipse.linuxtools.systemtap.structures.TreeDefinitionNode; import org.eclipse.linuxtools.systemtap.structures.TreeNode; /** - * Runs stap -vp1 & stap -up2 in order to get all of the probes/functions - * that are defined in the tapsets. Builds probeAlias and function trees + * Runs stap -vp1 & stap -L in order to get all of the probes + * that are defined in the tapsets. Builds probeAlias trees * with the values obtained from the tapsets. * - * Ugly code is a result of two issues with getting stap output. First, - * many tapsets do not work under stap -up2. Second since the output - * is not a regular language, we can't create a nice lexor/parser combination - * to do everything nicely. * @author Ryan Morse * @since 2.0 */ public class ProbeParser extends TapsetParser { + static final String probeRegex = "(?s)(?<!\\w)probe\\s+{0}\\s*\\+?="; //$NON-NLS-1$ + private static final String tapsetProbeRegex = "probe {0} \\+?="; //$NON-NLS-1$ + private TreeNode probes; + private TreeNode statics; + private TreeNode aliases; static ProbeParser parser = null; public static ProbeParser getInstance(){ @@ -66,17 +63,41 @@ public class ProbeParser extends TapsetParser { return probes; } + /** + * This method will clean up everything from the run. + */ + public void dispose() { + probes.dispose(); + statics.dispose(); + aliases.dispose(); + } + @Override protected IStatus run(IProgressMonitor monitor) { - String s = collect(null); - s = addStaticProbes(s); + // Create a new function tree each time, so as to not add duplicates. + reset(); + + addStaticProbes(); if (cancelRequested){ - return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ + return new Status(IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ } - parseProbes(s); - probes.sortTree(); + boolean cancelled = addProbeAliases(collect(null)); + constructRootTree(); fireUpdateEvent(); //Inform listeners that everything is done - return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ + return new Status(!cancelled ? IStatus.OK : IStatus.CANCEL, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ + } + + private void reset() { + probes = new TreeNode("", false); //$NON-NLS-1$ + statics = new TreeNode(Messages.ProbeParser_staticProbes, false); + aliases = new TreeNode(Messages.ProbeParser_aliasProbes, false); + } + + private void constructRootTree() { + statics.sortTree(); + aliases.sortTree(); + probes.add(statics); + probes.add(aliases); } /** @@ -104,129 +125,172 @@ public class ProbeParser extends TapsetParser { return s; } + private boolean addStaticProbes() { + String s = runStap(new String[]{"--dump-probe-types"}, null, false); //$NON-NLS-1$ + TreeNode group = null; + try (Scanner st = new Scanner(s)) { + while(st.hasNextLine()) { + if (cancelRequested) { + return false; + } + String tokenString = st.nextLine(); + String probeName = (new StringTokenizer(tokenString)).nextToken(); + group = addOrFindProbeGroup(extractProbeGroupName(probeName), group, statics); + group.add(makeStaticProbeNode(probeName)); + } + return true; + } + } + /** * Parses the output generated from running stap -L. Pulls out all functions - * and probe aliases from the provided string. Populates the probe and function - * trees. + * and probe aliases from the provided string. Populates the probe tree. * * ProbeTree organized as: - * Root->Files->ProbePoints->Variables + * Root->Named Groups->ProbePoints->Variables * - * FunctionTree organized as: - * Root->Files->Functions - * @param s The entire output from running stap -L. + * @param probeDump A list of probe points with the same formatting used by stap -L. + * @return <code>false</code> if a cancellation prevented all probes from being added; + * <code>true</code> otherwise. */ - private void parseProbes(String s) { - // Create a new function tree each time, so as to not add duplicates - probes = new TreeNode("", false); //$NON-NLS-1$ - String token = null; - StringBuilder prev = new StringBuilder(""); //$NON-NLS-1$ - TreeNode currentProbe = null; + private boolean addProbeAliases(String probeDump) { TreeNode group = null; + try (Scanner st = new Scanner(probeDump)) { + while(st.hasNextLine()) { + if (cancelRequested) { + return false; + } + String tokenString = st.nextLine(); + // If the token starts with '_' or '__' it is a private probe so + // skip it. + if (tokenString.startsWith("_")) { //$NON-NLS-1$ + continue; + } - StringTokenizer st = new StringTokenizer(s, "\n", false); //$NON-NLS-1$ - if (st.hasMoreTokens()){ - st.nextToken(); //skip the stap command itself - } - while(st.hasMoreTokens() && !cancelRequested){ - String tokenString = st.nextToken(); + StringTokenizer probeTokenizer = new StringTokenizer(tokenString); + String probeName = probeTokenizer.nextToken(); - // If the token starts with '_' or '__' it is a private probe so - // skip it. - if (tokenString.startsWith("_")) { //$NON-NLS-1$ - continue; - } - - int firstDotIndex = tokenString.indexOf('.'); - String groupName = tokenString; - if (firstDotIndex > 0){ - groupName = tokenString.substring(0, firstDotIndex); + String groupName = extractProbeGroupName(tokenString); + if (!isStaticProbeGroup(groupName)) { + TreeNode probeNode = makeProbeAliasNode(probeName); + group = addOrFindProbeGroup(groupName, group, aliases); + group.add(probeNode); + addAllVarNodesToProbeNode(probeTokenizer, probeNode); + } } + return true; + } + } - // If the current probe belongs to a group other than - // the most recent group. This should rarely be needed because the - // probe list is sorted... mostly. - if(group == null || !group.getData().equals(groupName)){ - group = probes.getChildByName(groupName); - } + /** + * Find the appropriate parent group node for a probe alias to group probes by name. + * If it doesn't yet exist, create it and add it to the view's tree. + * @param probeLine The name of the probe group. + * @param groupNode For optimization, pass an existing group node here, as it will be + * used if the probe belongs in it. Otherwise, or if <code>null</code> is passed, a new one will be created. + * @param category The parent tree node in which to put the group node. + * @return The found or created group node that will be the parent of the probe's entry item in the view. + */ + private TreeNode addOrFindProbeGroup(String groupName, TreeNode groupNode, TreeNode category) { - // Create a new group and add it - if(group == null){ - group = new TreeNode(groupName, groupName, true); - probes.add(group); - } + // If the current probe belongs to a group other than + // the most recent group. This should rarely be needed because the + // probe list is sorted... mostly. + if(groupNode == null || !groupNode.toString().equals(groupName)) { + groupNode = category.getChildByName(groupName); + } - StringTokenizer probe = new StringTokenizer(tokenString); - prev.setLength(0); - - // The first token is the probe name - token = probe.nextToken(); - currentProbe = new TreeDefinitionNode("probe " + token, token, null, true); //$NON-NLS-1$ - group.add(currentProbe); - - // the remaining tokens are variable names and variable types name:type. - while(probe.hasMoreTokens()){ - token = probe.nextToken(); - - // Because some variable types contain spaces (var2:struct task_struct) - // the only way to know if we have the entire string representing a - // variable is if we reach the next token containing a ':' or we reach - // the end of the stream. - if (token.contains(":") && prev.length() > 0){ //$NON-NLS-1$ - prev.setLength(prev.length() - 1); // Remove the trailing space. - currentProbe.add(new TreeNode(prev.toString(), prev.toString(), false)); - prev.setLength(0); - } - prev.append(token + " "); //$NON-NLS-1$ - } + // Create a new group and add it + if(groupNode == null) { + groupNode = new TreeNode(groupName, true); + category.add(groupNode); + } + return groupNode; + } - // Add the last token if there is one - if (prev.length() > 0){ - prev.setLength(prev.length() - 1); // Remove the trailing space. - currentProbe.add(new TreeNode(prev.toString(), prev.toString(), false)); - } + /** + * @return the name of the group a probe belongs to, based on the probe's name. + */ + private String extractProbeGroupName(String probeName) { + int dotIndex = probeName.indexOf('.'); + int parenIndex = probeName.indexOf('('); + if (dotIndex > 0 && parenIndex > 0) { + return probeName.substring(0, Math.min(dotIndex, parenIndex)); } + if (dotIndex > 0) { + return probeName.substring(0, dotIndex); + } + if (parenIndex > 0) { + return probeName.substring(0, parenIndex); + } + return probeName; + } + + private TreeNode makeStaticProbeNode(String probeName) { + return new TreeNode(new ProbeNodeData(probeName), probeName, true); + } + + private TreeNode makeProbeAliasNode(String probeName) { + return new TreeDefinitionNode(new ProbeNodeData(probeName), probeName, findDefinitionOf(probeName), true); + } + + private boolean isStaticProbeGroup(String groupName) { + return statics.getChildByName(groupName) != null; } /** - * Reads the static probes list and adds it to the probes tree. - * This function assumes that the probes list will be sorted. - * @return + * Search the tapset content dump for the path of the file which defines the provided probe alias. + * @param probeName The alias of the probe to find the definition file of. + * @return The path of the probe's definition file, or <code>null</code> if a definition + * file can't be found (which is the case for static probes). */ - private String addStaticProbes(String probeList) { - if (cancelRequested) { - return ""; //$NON-NLS-1$ + private String findDefinitionOf(String probeName) { + SharedParser sparser = SharedParser.getInstance(); + String tapsetContents = sparser.getTapsetContents(); + Matcher probeMatcher = Pattern.compile(MessageFormat.format(tapsetProbeRegex, Pattern.quote(probeName))).matcher(tapsetContents); + if (!probeMatcher.find()) { + return null; + } + int fileLocIndex = tapsetContents.substring(0, probeMatcher.start()).lastIndexOf(SharedParser.TAG_FILE); + try (Scanner scanner = new Scanner(tapsetContents.substring(fileLocIndex))) { + Matcher fileMatcher = sparser.filePattern.matcher(scanner.nextLine()); + return fileMatcher.matches() + ? fileMatcher.group(1) + : null; } - StringBuilder probes = new StringBuilder(probeList); + } - BufferedReader input = null; - try { - if (IDEPlugin.getDefault() == null) { - return ""; //$NON-NLS-1$ - } - URL location = IDEPlugin.getDefault().getBundle().getEntry("completion/static_probe_list.properties"); //$NON-NLS-1$ - location = FileLocator.toFileURL(location); - input = new BufferedReader(new FileReader(new File(location.getFile()))); - String line = input.readLine(); - while (line != null && !cancelRequested){ - probes.append('\n'); - probes.append(line); - line = input.readLine(); + /** + * Extracts the local variables from a (partially examined) probe alias token, and + * adds them as child tree entries of their parent probe. + */ + private void addAllVarNodesToProbeNode(StringTokenizer varTokenizer, TreeNode probeNode) { + StringBuilder prev = new StringBuilder(""); //$NON-NLS-1$ + // the remaining tokens are variable names and variable types name:type. + while(varTokenizer.hasMoreTokens()){ + String token = varTokenizer.nextToken(); + + // Because some variable types contain spaces (var2:struct task_struct) + // the only way to know if we have the entire string representing a + // variable is if we reach the next token containing a ':' or we reach + // the end of the stream. + if (token.contains(":") && prev.length() > 0){ //$NON-NLS-1$ + prev.setLength(prev.length() - 1); // Remove the trailing space. + addVarNodeToProbeNode(prev.toString(), probeNode); + prev.setLength(0); } - input.close(); - } catch (FileNotFoundException e) { - ExceptionErrorDialog.openError(Messages.ProbeParser_errorInitializingStaticProbes, e); - } catch (IOException e) { - ExceptionErrorDialog.openError(Messages.ProbeParser_errorInitializingStaticProbes, e); + prev.append(token + " "); //$NON-NLS-1$ } - return probes.toString(); + // Add the last token if there is one + if (prev.length() > 0){ + prev.setLength(prev.length() - 1); // Remove the trailing space. + addVarNodeToProbeNode(prev.toString(), probeNode); + } } - /** - * This method will clean up everything from the run. - */ - public void dispose() { - probes.dispose(); + private void addVarNodeToProbeNode(String info, TreeNode probeNode) { + probeNode.add(new TreeNode(new ProbevarNodeData(info), info, false)); } + } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java new file mode 100644 index 0000000000..cb3efdb36a --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/ProbevarNodeData.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * A structure for containing extra information of SystemTap probe variables. + * @since 3.0 + */ +public class ProbevarNodeData { + private String text; + private String name; + private List<String> types; + + /** + * @return The original line of text passed to this object, which contains the + * variable's name and its full type. + */ + @Override + public String toString() { + return text; + } + + /** + * @return The name of the variable. + */ + public String getName() { + return name; + } + + /** + * @return A list of all tokens used to describe the variable's type. + */ + public List<String> getTypes() { + return types; + } + + /** + * Create a new instance of probe variable node information. + * @param line A line of text generated by running "stap -L" which + * provides all information pertaining to a probe point. + */ + public ProbevarNodeData(String line) { + text = line.trim(); + int colonIndex = text.indexOf(':'); + if (colonIndex == -1) { + name = text; + types = Collections.emptyList(); + } else { + name = line.substring(0, colonIndex); + types = Arrays.asList(text.substring(colonIndex+1).split(" ")); //$NON-NLS-1$ + } + } +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java new file mode 100644 index 0000000000..0571f39d09 --- /dev/null +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/SharedParser.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2014 Red Hat, 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 + * + * Contributors: + * Red Hat - initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.internal.systemtap.ui.ide.structures; + +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; + +public class SharedParser extends TapsetParser { + + static final String TAG_FILE = "# file"; //$NON-NLS-1$ + /** + * A pattern that can be used to locate file paths listed in stap tapset dumps. + */ + final Pattern filePattern = Pattern.compile("# file (/.*\\.stp)"); //$NON-NLS-1$ + + private String tapsetContents = null; + + static SharedParser parser = null; + public static SharedParser getInstance(){ + if (parser != null) { + return parser; + } + parser = new SharedParser(); + return parser; + } + + private SharedParser() { + super("Shared Parser"); //$NON-NLS-1$ + } + + /** + * Clear the cached tapset contents, so that the next call to {@link #getTapsetContents()} + * will be guaranteed to use a new call of stap to gather up-to-date tapset contents. + */ + synchronized void clearTapsetContents() { + tapsetContents = null; + } + + /** + * Get the contents of default & all imported tapsets. When calling this method + * for the first time (or after changing the list of tapset directories), this will + * run a dummy stap script to obtain the tapset contents, which will be cached into + * memory. Subsequent calls will simply read the saved contents. + * @return The string contents of tapsets, or <code>null</code> if there was an + * error in obtaining this information. + */ + synchronized String getTapsetContents() { + if (tapsetContents == null) { + run(null); + } + return tapsetContents; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + tapsetContents = runStap(new String[] {"-v", "-p1", "-e"}, "probe begin{}", false); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ + // Exclude the dump of the test script by excluding everything before the second pathname + // (which is the first actual tapset file, not the input script). + tapsetContents = tapsetContents.substring(tapsetContents.indexOf(TAG_FILE, tapsetContents.indexOf(TAG_FILE)+1)); + return new Status(IStatus.OK, IDEPlugin.PLUGIN_ID, ""); //$NON-NLS-1$ + } + +} diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java index dd8dc3d117..d56b9f20ba 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetLibrary.java @@ -53,6 +53,14 @@ public final class TapsetLibrary { return probeTree; } + public static TreeNode getStaticProbes() { + return probeTree == null ? null : probeTree.getChildByName(Messages.ProbeParser_staticProbes); + } + + public static TreeNode getProbeAliases() { + return probeTree == null ? null : probeTree.getChildByName(Messages.ProbeParser_aliasProbes); + } + public static TreeNode getFunctions() { return functionTree; } @@ -69,7 +77,7 @@ public final class TapsetLibrary { // If the requested element is a probe variable // fetch the documentation for the parent probe then check the map - if (element.matches("probe::.*::.*")){ //$NON-NLS-1$ + if (element.matches("probe::.*::.*")) { //$NON-NLS-1$ String probe = element.split("::")[1]; //$NON-NLS-1$ getDocumentation("probe::" + probe); //$NON-NLS-1$ return pages.get(element); @@ -84,7 +92,7 @@ public final class TapsetLibrary { element.startsWith("probe::")) { //$NON-NLS-1$ // If this is a probe parse out the variables String[] sections = documentation.split("VALUES"); //$NON-NLS-1$ - if (sections.length > 1){ + if (sections.length > 1) { // Discard any other sections String variablesString = sections[1].split("CONTEXT|DESCRIPTION|SystemTap Tapset Reference")[0].trim(); //$NON-NLS-1$ String[] variables = variablesString.split("\n"); //$NON-NLS-1$ @@ -94,7 +102,7 @@ public final class TapsetLibrary { String variableName = variables[i].trim(); StringBuilder variableDocumentation = new StringBuilder(); i++; - while (i < variables.length && !variables[i].isEmpty()){ + while (i < variables.length && !variables[i].isEmpty()) { variableDocumentation.append(variables[i].trim()); variableDocumentation.append("\n"); //$NON-NLS-1$ i++; @@ -117,9 +125,9 @@ public final class TapsetLibrary { * @return * @since 2.0 */ - public static synchronized String getAndCacheDocumentation(String element){ + public static synchronized String getAndCacheDocumentation(String element) { String doc = pages.get(element); - if (doc == null){ + if (doc == null) { doc = getDocumentation(element); pages.put(element, doc); } @@ -164,6 +172,8 @@ public final class TapsetLibrary { * to get the information directly from the files. */ private static void runStapParser() { + SharedParser.getInstance().clearTapsetContents(); + functionParser = FunctionParser.getInstance(); functionParser.addListener(functionCompletionListener); functionParser.schedule(); @@ -287,7 +297,7 @@ public final class TapsetLibrary { return true; } - private static Job cacheFunctionManpages = new Job(Localization.getString("TapsetLibrary.0")){ //$NON-NLS-1$ + private static Job cacheFunctionManpages = new Job(Localization.getString("TapsetLibrary.0")) { //$NON-NLS-1$ private boolean cancelled; @Override @@ -308,7 +318,7 @@ public final class TapsetLibrary { }; - private static Job cacheProbeManpages = new Job(Localization.getString("TapsetLibrary.1")){ //$NON-NLS-1$ + private static Job cacheProbeManpages = new Job(Localization.getString("TapsetLibrary.1")) { //$NON-NLS-1$ @Override protected IStatus run(IProgressMonitor monitor) { TreeNode node = probeParser.getProbes(); @@ -351,7 +361,7 @@ public final class TapsetLibrary { * @since 2.0 */ public static void waitForInitialization() { - while (functionParser.getResult() == null){ + while (functionParser.getResult() == null) { try { synchronized (functionParser) { functionParser.wait(5000); @@ -360,7 +370,7 @@ public final class TapsetLibrary { break; } } - while (probeParser.getResult() == null){ + while (probeParser.getResult() == null) { try { synchronized (probeParser) { probeParser.wait(5000); @@ -376,8 +386,8 @@ public final class TapsetLibrary { * {@link TapsetLibrary#init()} such as the {@link TapsetParser} * @since 1.2 */ - public static void stop(){ - if(null != functionParser){ + public static void stop() { + if(null != functionParser) { functionParser.cancel(); cacheFunctionManpages.cancel(); try { @@ -388,7 +398,7 @@ public final class TapsetLibrary { // continue stopping. } } - if(probeParser != null){ + if(probeParser != null) { probeParser.cancel(); cacheProbeManpages.cancel(); try { diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java index ef5df9eabb..5c291d9510 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/TapsetParser.java @@ -96,7 +96,8 @@ public abstract class TapsetParser extends Job { /** * Runs the stap with the given options and returns the output generated * @param options String[] of any optional parameters to pass to stap - * @param probe String containing the script to run stap on + * @param probe String containing the script to run stap on, + * or <code>null</code> for scriptless commands * @param getErrors Set this to <code>true</code> if the script's error * stream contents should be returned instead of its standard output */ @@ -104,29 +105,33 @@ public abstract class TapsetParser extends Job { String[] args = null; String[] tapsets = IDEPlugin.getDefault().getPreferenceStore() .getString(IDEPreferenceConstants.P_TAPSETS).split(File.pathSeparator); + boolean noTapsets = tapsets[0].trim().length() == 0; + boolean noOptions = options[0].trim().length() == 0; - int size = 2; //start at 2 for stap, script, options will be added in later - if (tapsets.length > 0 && tapsets[0].trim().length() > 0) { + int size = probe != null ? 2 : 1; + if (tapsets.length > 0 && !noTapsets) { size += tapsets.length<<1; } - if (options.length > 0 && options[0].trim().length() > 0) { + if (options.length > 0 && !noOptions) { size += options.length; } args = new String[size]; args[0] = "stap"; //$NON-NLS-1$ - args[size-1] = probe; + if (probe != null) { + args[size-1] = probe; + } //Add extra tapset directories - if(tapsets.length > 0 && tapsets[0].trim().length() > 0) { - for(int i=0; i<tapsets.length; i++) { - args[1+(i<<1)] = "-I"; //$NON-NLS-1$ - args[2+(i<<1)] = tapsets[i]; + if (tapsets.length > 0 && !noTapsets) { + for (int i = 0; i < tapsets.length; i++) { + args[1 + 2*i] = "-I"; //$NON-NLS-1$ + args[2 + 2*i] = tapsets[i]; } } - if(options.length > 0 && options[0].trim().length() > 0) { - for(int i=0; i<options.length; i++) { - args[size-1-options.length+i] = options[i]; + if (options.length > 0 && !noOptions) { + for (int i = 0, s = noTapsets ? 1 : 1 + tapsets.length*2; i<options.length; i++) { + args[s + i] = options[i]; } } @@ -141,7 +146,7 @@ public abstract class TapsetParser extends Job { String password = p.getString(ConsoleLogPreferenceConstants.SCP_PASSWORD); Channel channel = SystemtapProcessFactory.execRemoteAndWait(args,str, strErr, user, host, password); - if(channel == null){ + if (channel == null) { displayError(Messages.TapsetParser_CannotRunStapTitle, Messages.TapsetParser_CannotRunStapMessage); } @@ -180,7 +185,7 @@ public abstract class TapsetParser extends Job { return null; } - private void displayError(final String title, final String error){ + private void displayError(final String title, final String error) { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/messages.properties b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/messages.properties index 42879be93d..f7b7d419bd 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/messages.properties +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/structures/messages.properties @@ -10,6 +10,8 @@ ############################################################################### ProbeParser_errorInitializingStaticProbes=Could not initialize static probe list +ProbeParser_staticProbes=Static Probes +ProbeParser_aliasProbes=Probe Aliases TapsetParser_CannotRunStapMessage=Make sure SystemTap is installed. TapsetParser_CannotRunStapTitle=Cannot Run SystemTap TapsetParser_ErrorRunningSystemtap=Error Running SystemTap diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java index 27d6e95148..7f67b04a24 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/BrowserView.java @@ -11,15 +11,24 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.views; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.linuxtools.systemtap.structures.listeners.IUpdateListener; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.PatternFilter; import org.eclipse.ui.handlers.CollapseAllHandler; @@ -88,6 +97,14 @@ public abstract class BrowserView extends ViewPart { protected abstract Image getEntryImage(TreeNode treeObj); + protected Image getGenericImage(TreeNode treeObj) { + if (treeObj.getChildCount() == 0) { + return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$ + } else { + return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); + } + } + /** * Provides the icon and text for each entry in the tapset tree. * @author Ryan Morse @@ -117,6 +134,18 @@ public abstract class BrowserView extends ViewPart { handlerService.activateHandler(CollapseAllHandler.COMMAND_ID, collapseHandler); } + protected void registerContextMenu(String menuName) { + Control control = this.viewer.getControl(); + MenuManager manager = new MenuManager(menuName); + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + Menu menu = manager.createContextMenu(control); + viewer.getControl().setMenu(menu); + + IWorkbenchPartSite partSite = getSite(); + partSite.registerContextMenu(manager, viewer); + partSite.setSelectionProvider(viewer); + } + public TreeViewer getViewer() { return viewer; } diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java index 4beb5ce4e1..2943bcd0de 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/FunctionBrowserView.java @@ -11,18 +11,13 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.views; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; import org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.FunctionBrowserAction; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ISingleTypedNode; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary; -import org.eclipse.linuxtools.systemtap.structures.FunctionNodeData; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IWorkbenchActionConstants; @@ -52,16 +47,15 @@ public class FunctionBrowserView extends BrowserView { @Override protected Image getEntryImage(TreeNode treeObj) { - if (!(treeObj.getData() instanceof FunctionNodeData)) { - return null; + if (!(treeObj.getData() instanceof ISingleTypedNode)) { + return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$ } - FunctionNodeData d = (FunctionNodeData) treeObj.getData(); - String type = d.getType(); + String type = ((ISingleTypedNode) treeObj.getData()).getType(); if (type == null) { return IDEPlugin.getImageDescriptor("icons/vars/var_void.gif").createImage(); //$NON-NLS-1$ - } else if(type.equals("long")) {//$NON-NLS-1$ + } else if (type.equals("long")) {//$NON-NLS-1$ return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$ - } else if(type.equals("string")) {//$NON-NLS-1$ + } else if (type.equals("string")) {//$NON-NLS-1$ return IDEPlugin.getImageDescriptor("icons/vars/var_str.gif").createImage(); //$NON-NLS-1$ } else { return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$ @@ -106,13 +100,7 @@ public class FunctionBrowserView extends BrowserView { private void makeActions() { doubleClickAction = new FunctionBrowserAction(getSite().getWorkbenchWindow(), this); viewer.addDoubleClickListener(doubleClickAction); - Control control = this.viewer.getControl(); - MenuManager manager = new MenuManager("functionPopup"); //$NON-NLS-1$ - - manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - Menu menu = manager.createContextMenu(control); - viewer.getControl().setMenu(menu); - getSite().registerContextMenu(manager, viewer); + registerContextMenu("functionPopup"); //$NON-NLS-1$ } @Override diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java index 2947fe9dda..4780864e39 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/KernelBrowserView.java @@ -36,8 +36,6 @@ import org.eclipse.linuxtools.systemtap.structures.KernelSourceTree; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.ISharedImages; -import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.UIJob; /** @@ -137,7 +135,7 @@ public class KernelBrowserView extends BrowserView { if(item.endsWith(".h")) { //$NON-NLS-1$ return IDEPlugin.getImageDescriptor("icons/files/file_h.gif").createImage(); //$NON-NLS-1$ } - return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER); + return getGenericImage(treeObj); } /** diff --git a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java index d257568746..8ce45b93c3 100644 --- a/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java +++ b/systemtap/org.eclipse.linuxtools.systemtap.ui.ide/src/org/eclipse/linuxtools/internal/systemtap/ui/ide/views/ProbeAliasBrowserView.java @@ -11,17 +11,16 @@ package org.eclipse.linuxtools.internal.systemtap.ui.ide.views; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.action.Separator; +import java.util.List; + import org.eclipse.linuxtools.internal.systemtap.ui.ide.IDEPlugin; import org.eclipse.linuxtools.internal.systemtap.ui.ide.actions.ProbeAliasAction; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbeNodeData; +import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.ProbevarNodeData; import org.eclipse.linuxtools.internal.systemtap.ui.ide.structures.TapsetLibrary; import org.eclipse.linuxtools.systemtap.structures.TreeNode; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.ui.IWorkbenchActionConstants; /** @@ -49,23 +48,30 @@ public class ProbeAliasBrowserView extends BrowserView { @Override protected Image getEntryImage(TreeNode treeObj) { - String item = treeObj.getData().toString(); - if(item.startsWith("probe")) {//$NON-NLS-1$ - return IDEPlugin.getImageDescriptor("icons/misc/probe_obj.gif").createImage(); //$NON-NLS-1$ - } - //Probe variables - if(item.endsWith(":long")) {//$NON-NLS-1$ + if (treeObj.getData() instanceof ProbevarNodeData) { + List<String> varTypes = ((ProbevarNodeData) treeObj.getData()).getTypes(); + if (varTypes.get(varTypes.size()-1).endsWith("*")) { //Pointers //$NON-NLS-1$ + return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$ + } + if (varTypes.contains("struct")) {//$NON-NLS-1$ + return IDEPlugin.getImageDescriptor("icons/vars/var_struct.gif").createImage(); //$NON-NLS-1$ + } + if (varTypes.contains("string")) {//$NON-NLS-1$ + return IDEPlugin.getImageDescriptor("icons/vars/var_str.gif").createImage(); //$NON-NLS-1$ + } + if (varTypes.contains("unknown")) {//$NON-NLS-1$ + return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$ + } + // All other types are displayed as long return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$ } - if(item.endsWith(":string")) {//$NON-NLS-1$ - return IDEPlugin.getImageDescriptor("icons/vars/var_str.gif").createImage(); //$NON-NLS-1$ - } - if(item.endsWith(":unknown")) {//$NON-NLS-1$ - return IDEPlugin.getImageDescriptor("icons/vars/var_unk.gif").createImage(); //$NON-NLS-1$ - } - return IDEPlugin.getImageDescriptor("icons/vars/var_long.gif").createImage(); //$NON-NLS-1$ + //Non-variable icons + if (treeObj.getData() instanceof ProbeNodeData) { + return IDEPlugin.getImageDescriptor("icons/misc/probe_obj.gif").createImage(); //$NON-NLS-1$ + } + return getGenericImage(treeObj); } /** @@ -75,7 +81,7 @@ public class ProbeAliasBrowserView extends BrowserView { public void refresh() { TreeNode probes = TapsetLibrary.getProbes(); if (probes != null){ - super.viewer.setInput(TapsetLibrary.getProbes()); + super.viewer.setInput(probes); } } @@ -85,22 +91,16 @@ public class ProbeAliasBrowserView extends BrowserView { private void makeActions() { doubleClickAction = new ProbeAliasAction(getSite().getWorkbenchWindow(), this); viewer.addDoubleClickListener(doubleClickAction); - Control control = this.viewer.getControl(); - MenuManager manager = new MenuManager("probePopup"); //$NON-NLS-1$ - - manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); - Menu menu = manager.createContextMenu(control); - viewer.getControl().setMenu(menu); - getSite().registerContextMenu(manager, viewer); + registerContextMenu("probePopup"); //$NON-NLS-1$ } @Override public void dispose() { super.dispose(); - if(null != viewer) { + if (null != viewer) { viewer.removeDoubleClickListener(doubleClickAction); } - if(null != doubleClickAction) { + if (null != doubleClickAction) { doubleClickAction.dispose(); } doubleClickAction = null; |