From 6b922df8c2eb4eff03a33e6286d1cdd6559dc85d Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Mon, 29 Mar 2010 02:31:04 +0000 Subject: [PATCH] - test view to inspect control flow graph --- .../.classpath | 7 + .../org.eclipse.cdt.codan.ui.cfgview/.project | 34 ++ .../.settings/org.eclipse.jdt.core.prefs | 8 + .../META-INF/MANIFEST.MF | 17 + .../build.properties | 6 + .../icons/connector.png | Bin 0 -> 1036 bytes .../icons/decision.png | Bin 0 -> 1039 bytes .../icons/exit.png | Bin 0 -> 1059 bytes .../icons/jump.png | Bin 0 -> 1039 bytes .../icons/refresh_view.gif | Bin 0 -> 182 bytes .../icons/start.png | Bin 0 -> 1038 bytes .../icons/task.png | Bin 0 -> 996 bytes .../plugin.xml | 16 + .../ui/cfgview/ControlFlowGraphPlugin.java | 82 ++++ .../cfgview/views/ControlFlowGraphView.java | 416 ++++++++++++++++++ 15 files changed, 586 insertions(+) create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/.classpath create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/.project create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/.settings/org.eclipse.jdt.core.prefs create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/META-INF/MANIFEST.MF create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/build.properties create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/icons/connector.png create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/icons/decision.png create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/icons/exit.png create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/icons/jump.png create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/icons/refresh_view.gif create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/icons/start.png create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/icons/task.png create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/plugin.xml create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/ControlFlowGraphPlugin.java create mode 100644 codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/.classpath b/codan/org.eclipse.cdt.codan.ui.cfgview/.classpath new file mode 100644 index 00000000000..64c5e31b7a2 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/.project b/codan/org.eclipse.cdt.codan.ui.cfgview/.project new file mode 100644 index 00000000000..3df8f20cc97 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/.project @@ -0,0 +1,34 @@ + + + org.eclipse.cdt.codan.ui.cfgview + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.api.tools.apiAnalysisBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.pde.api.tools.apiAnalysisNature + + diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/.settings/org.eclipse.jdt.core.prefs b/codan/org.eclipse.cdt.codan.ui.cfgview/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..345c8c82184 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Sat Mar 27 20:39:28 EDT 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/META-INF/MANIFEST.MF b/codan/org.eclipse.cdt.codan.ui.cfgview/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..eb3c510d920 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Control Flow Graph +Bundle-SymbolicName: org.eclipse.cdt.codan.ui.cfgview;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.eclipse.cdt.codan.ui.cfgview.ControlFlowGraphPlugin +Bundle-Vendor: Eclipse CDT +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.cdt.codan.core;bundle-version="1.0.0", + org.eclipse.cdt.codan.core.cxx;bundle-version="1.0.0", + org.eclipse.cdt.core;bundle-version="5.2.0", + org.eclipse.cdt.ui;bundle-version="5.2.0", + org.eclipse.core.resources;bundle-version="3.6.0", + org.eclipse.ui.editors;bundle-version="3.6.0" +Bundle-RequiredExecutionEnvironment: J2SE-1.5 +Bundle-ActivationPolicy: lazy diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/build.properties b/codan/org.eclipse.cdt.codan.ui.cfgview/build.properties new file mode 100644 index 00000000000..0d3d3a745d4 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + icons/ diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/icons/connector.png b/codan/org.eclipse.cdt.codan.ui.cfgview/icons/connector.png new file mode 100644 index 0000000000000000000000000000000000000000..f7e9831d34766e1778613ad4e6f04c17ee46cddf GIT binary patch literal 1036 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NSs56Z83KGlTR>*F$4J7=wNF5l>#x-p@6 zXL048%BsCpt=mHK0bQ&_0{XIuit)q`}ybRKY#!H`~UC%|NlT&je^k- z7{CxX9G!6lXgz0vM`SSr1K(i~W;~w1A_XWYS>hT|5}cn_Ql40p$`Fv4nOCCc=Nh6= zW~^tbXJXfTrVOa4z|+MsL?bx)f(tXx5snjC2SPQovzWGWtj^9_<=wTKsrBarraNnxO^Kt5 wWd~)JX|QdTR$HLZsJ1|*RgIxsC-FQZgTXbGj$5i1Zh!*K)78&qol`;+01vsN_W%F@ literal 0 HcmV?d00001 diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/icons/decision.png b/codan/org.eclipse.cdt.codan.ui.cfgview/icons/decision.png new file mode 100644 index 0000000000000000000000000000000000000000..de3db627dee0f2f4a101712bee30d727c7bbaae1 GIT binary patch literal 1039 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NSs56Z83KGlTzwXrdoQ#ITx1r!*gR~BMci^5|0Rz8OPzz4dxozHh+Y$%veF@K zm1ENS=;RG?WgEQHx1?upNiW<{Sh};QVs~lv-s;xvp?$leChU%xyf=2r-nhQwebY`) zn{j&j%ri4*pPjwn!h%H?7p=a!dh^ZA+i!2*ac9TA`}+<)IC%2O$um#STzGNe^2^IN z-rTtT_V%53cOJZd@aW^CH{afT|NZ^vpP#?~{{Hv>-~a#rfsP*qqai?x5P0zH6EH6@ za29w(7BevL9R^{>CO=O(HD12eMqws~v&cYWax{C%RrcW_trlL@dRjje%i(iC%|I#f7V&0P%G7b6Mw<&;$Sw)xFvP literal 0 HcmV?d00001 diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/icons/exit.png b/codan/org.eclipse.cdt.codan.ui.cfgview/icons/exit.png new file mode 100644 index 0000000000000000000000000000000000000000..c1c59a95330d80715c17a6c2f5eb326297109f41 GIT binary patch literal 1059 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NSs56Z83KGlT-7H?YD|?MYI`_IQ0gYROnzjYEZVzeO9@?=ZtaC?r z_s)pkU6FmeqbBT*p13Dw%HFuf1C6bRT00K6O*q~^gzyJLG^Y7ok|Ns93y*3I)Lx8*xnC;`I0MyA@;1OBOz`%DHgc*Y3Q}o+$$=YWH+;4ABTqE^uJx3D~#PbPA*J z1w$9%3#Jaj7p}XD8iWU$HFr3i2}l+fd>XQ~ojb#zQ&ZE^VD({^HF pjU!7tpYX9qCo4;*v@5bQG9=ZT3TNuB5Cb}i!PC{xWt~$(695(Q(TD&5 literal 0 HcmV?d00001 diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/icons/jump.png b/codan/org.eclipse.cdt.codan.ui.cfgview/icons/jump.png new file mode 100644 index 0000000000000000000000000000000000000000..179cbd6f2be45d666e3c827d6d3b67296c77f3cc GIT binary patch literal 1039 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NSs56Z83KGlT(zfa+0D|npRHpvThD%uf$bb4$9d+VD+8j|gvGCq&spo5xFN1^ zoqO3v@2X9HNgI=rHzucVPA%L~*t{*IV@Fu$j_}@Hk^Q@)r|gYevt~`hfrhrjZ4*yS zoPK)x^2^J&+}v{c<>l+Iuitxr@6m@x&p$tZ@%hD@uW#Obd-Lx5yU#yA|N8su_ut?D z{{Q>`|3A=$qhK@y=o|vs!PYy0R&o}2L>4nJ@ErzW#^d=bQh-5!lzq6e6Q{pkHml=}tX` z2CW53M-|rci8akwc;bxuxznq91QNt2PnaO^u#G#zkm;w8(3zs5qE!jHw|o*9#VRW+ zO*iG>qRGGz)2jOD*HkkxP*{1o L`njxgN@xNA@h+<~ literal 0 HcmV?d00001 diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/icons/refresh_view.gif b/codan/org.eclipse.cdt.codan.ui.cfgview/icons/refresh_view.gif new file mode 100644 index 0000000000000000000000000000000000000000..a063c230aca909c805f6a97a93c524c89198cc6c GIT binary patch literal 182 zcmZ?wbhEHb6krfw*v!E2|G#~Gz5V?8@&EtNpFh8T|Ni;^@7vF>x4%E%zCPam|NsB{ zfkN}=0~ripp!k!8k%57iK?lSGnZdx4yy2uL^Ir3ap5|M3p71&;7@R&L;67QxL54l! zu*}gfQtm|zTcZ0WIjBgri1Vs5s`jxmIW;RhF|qP|cz{DfsHKg4$1sH2{nEMt%SQ literal 0 HcmV?d00001 diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/icons/start.png b/codan/org.eclipse.cdt.codan.ui.cfgview/icons/start.png new file mode 100644 index 0000000000000000000000000000000000000000..ce34b006b1cd122cd55f66bc39cea3a470d4a8d3 GIT binary patch literal 1038 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NSs56Z83KGlT=l0Y8B9~RnxSSj$IN=JrR_XxmpR%V^YnZd7=|n|OpI%id#rcDi3w9rO`UOO z#=2|kHr&{-@y5ojx3+G(y=~{6oxASr+Iw&B{`>n6JUDRe^|fc8pMCoI>C4YA-+q1j z{`>pyzrX+f`}_a@f1o=@!DtB3Ed;_YZLI`a##!JISzV4A*!7+%11c)=ba4#P2u{A>&dlS&d18}6GvjKh z0Ly@Gw&ocY5*XkmMQf%oT{&s6+*@lQr^kv#oEfhca2~MbW#B!eDqQyW R$U#sbdAjNSs56Z83KGlT&-v6+0N22ooV1U-^6R7MZj{Oh}EGnYr~`0My9QD%-xnVWp7;b z!RCo4Cak}{e)rwor=Ola`|Rwkx3^w=dGX=iL1%5w9@ w&6|-k8(6IMZ}1o>oJ~y7U34g;u92OIVPc06-@+}fhd`m|>FVdQ&MBb@0Qx>`y#N3J literal 0 HcmV?d00001 diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/plugin.xml b/codan/org.eclipse.cdt.codan.ui.cfgview/plugin.xml new file mode 100644 index 00000000000..40df7b700c2 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/plugin.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/ControlFlowGraphPlugin.java b/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/ControlFlowGraphPlugin.java new file mode 100644 index 00000000000..5c04087efa2 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/ControlFlowGraphPlugin.java @@ -0,0 +1,82 @@ +package org.eclipse.cdt.codan.ui.cfgview; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class ControlFlowGraphPlugin extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.cdt.codan.ui.cfgview"; //$NON-NLS-1$ + + // The shared instance + private static ControlFlowGraphPlugin plugin; + + /** + * The constructor + */ + public ControlFlowGraphPlugin() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static ControlFlowGraphPlugin getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path + * + * @param path the path + * @return the image descriptor + */ + public ImageDescriptor getImageDescriptor(String key) { + ImageRegistry registry = getImageRegistry(); + ImageDescriptor descriptor = registry.getDescriptor(key); + if (descriptor == null) { + descriptor = imageDescriptorFromPlugin(PLUGIN_ID,key); + registry.put(key, descriptor); + } + return descriptor; + } + + public Image getImage(String key) { + ImageRegistry registry = getImageRegistry(); + Image image = registry.get(key); + if (image == null) { + ImageDescriptor descriptor = imageDescriptorFromPlugin(PLUGIN_ID,key); + registry.put(key, descriptor); + image = registry.get(key); + } + return image; + } + + +} diff --git a/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java b/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java new file mode 100644 index 00000000000..33066065296 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cfgview/src/org/eclipse/cdt/codan/ui/cfgview/views/ControlFlowGraphView.java @@ -0,0 +1,416 @@ +package org.eclipse.cdt.codan.ui.cfgview.views; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.ControlFlowGraphBuilder; +import org.eclipse.cdt.codan.core.cxx.internal.model.cfg.CxxControlFlowGraph; +import org.eclipse.cdt.codan.internal.core.cfg.AbstractBasicBlock; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IBasicBlock; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IConnectorNode; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IControlFlowGraph; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionArc; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IDecisionNode; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IExitNode; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IJumpNode; +import org.eclipse.cdt.codan.provisional.core.model.cfg.ISingleOutgoing; +import org.eclipse.cdt.codan.provisional.core.model.cfg.IStartNode; +import org.eclipse.cdt.codan.ui.cfgview.ControlFlowGraphPlugin; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.parser.ParserUtil; +import org.eclipse.cdt.core.resources.FileStorage; +import org.eclipse.cdt.internal.ui.util.EditorUtility; +import org.eclipse.cdt.ui.CDTUITools; +import org.eclipse.cdt.ui.text.SharedASTJob; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.DrillDownAdapter; +import org.eclipse.ui.part.ViewPart; +import org.eclipse.ui.texteditor.AbstractTextEditor; + +/** + * This sample class demonstrates how to plug-in a new workbench view. The view + * shows data obtained from the model. The sample creates a dummy model on the + * fly, but a real implementation would connect to the model available either in + * this or another plug-in (e.g. the workspace). The view is connected to the + * model using a content provider. + *

+ * The view uses a label provider to define how model objects should be + * presented in the view. Each view can present the same model objects using + * different labels and icons, if needed. Alternatively, a single label provider + * can be shared between views in order to ensure that objects of the same type + * are presented in the same way everywhere. + *

+ */ +public class ControlFlowGraphView extends ViewPart { + /** + * The ID of the view as specified by the extension. + */ + public static final String ID = "org.eclipse.cdt.codan.ui.cfgview.views.ControlFlowGraphView"; + private TreeViewer viewer; + private DrillDownAdapter drillDownAdapter; + private Action action1; + private Action doubleClickAction; + + class ViewContentProvider implements IStructuredContentProvider, + ITreeContentProvider { + public void inputChanged(Viewer v, Object oldInput, Object newInput) { + } + + public void dispose() { + } + + public Object[] getElements(Object parent) { + return getChildren(parent); + } + + public Object getParent(Object child) { + return null; + } + + public Object[] getChildren(Object parent) { + if (parent instanceof Collection) { + return ((Collection) parent).toArray(); + } else if (parent instanceof IControlFlowGraph) { + Collection blocks = getFlat( + ((IControlFlowGraph) parent).getStartNode(), + new ArrayList()); + return blocks.toArray(); + } else if (parent instanceof IDecisionNode) { + ArrayList blocks = new ArrayList(); + Iterator iter = ((IDecisionNode) parent) + .getDecisionArcs(); + for (; iter.hasNext();) { + IDecisionArc arc = iter.next(); + blocks.add(arc); + } + blocks.add(((IDecisionNode) parent).getConnectionNode()); + return blocks.toArray(); + } else if (parent instanceof IDecisionArc) { + Collection blocks = getFlat( + ((IDecisionArc) parent).getOutgoing(), + new ArrayList()); + return blocks.toArray(); + } + return new Object[0]; + } + + public boolean hasChildren(Object parent) { + return getChildren(parent).length > 0; + } + } + + class ViewLabelProvider extends LabelProvider { + public String getText(Object obj) { + if (obj == null) + return null; + String strdata = ""; + if (obj instanceof AbstractBasicBlock) { + strdata = ((AbstractBasicBlock) obj).toStringData(); + } + return obj.getClass().getSimpleName() + ": " + strdata; + } + + public Image getImage(Object obj) { + String imageKey = "task.png"; + if (obj instanceof IDecisionNode + || obj instanceof IControlFlowGraph) + imageKey = "decision.png"; + else if (obj instanceof IExitNode) + imageKey = "exit.png"; + else if (obj instanceof IStartNode) + imageKey = "start.png"; + else if (obj instanceof IJumpNode) + imageKey = "jump.png"; + else if (obj instanceof IConnectorNode) + imageKey = "connector.png"; + return ControlFlowGraphPlugin.getDefault().getImage( + "icons/" + imageKey); + } + } + + /** + * The constructor. + */ + public ControlFlowGraphView() { + } + + /** + * @param prev + * @param startNode + * @return + */ + public Collection getFlat(IBasicBlock node, + Collection prev) { + prev.add(node); + if (node instanceof IConnectorNode) { + return prev; + } + if (node instanceof ISingleOutgoing) { + getFlat(((ISingleOutgoing) node).getOutgoing(), prev); + } else if (node instanceof IDecisionNode) { + getFlat(((IDecisionNode) node).getConnectionNode().getOutgoing(), + prev); + } + return prev; + } + + /** + * This is a callback that will allow us to create the viewer and initialize + * it. + */ + public void createPartControl(Composite parent) { + viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); + drillDownAdapter = new DrillDownAdapter(viewer); + viewer.setContentProvider(new ViewContentProvider()); + viewer.setLabelProvider(new ViewLabelProvider()); + viewer.setInput(getViewSite()); + makeActions(); + hookContextMenu(); + hookSingleClickAction(); + contributeToActionBars(); + } + + private void hookContextMenu() { + MenuManager menuMgr = new MenuManager("#PopupMenu"); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + ControlFlowGraphView.this.fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(viewer.getControl()); + viewer.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, viewer); + } + + private void contributeToActionBars() { + IActionBars bars = getViewSite().getActionBars(); + fillLocalPullDown(bars.getMenuManager()); + fillLocalToolBar(bars.getToolBarManager()); + } + + private void fillLocalPullDown(IMenuManager manager) { + manager.add(action1); + manager.add(new Separator()); + } + + private void fillContextMenu(IMenuManager manager) { + manager.add(action1); + manager.add(new Separator()); + drillDownAdapter.addNavigationActions(manager); + // Other plug-ins can contribute there actions here + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + + private void fillLocalToolBar(IToolBarManager manager) { + manager.add(action1); + manager.add(new Separator()); + drillDownAdapter.addNavigationActions(manager); + } + + private void makeActions() { + action1 = new Action() { + public void run() { + IEditorPart e = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage() + .getActiveEditor(); + ITranslationUnit tu = (ITranslationUnit) CDTUITools + .getEditorInputCElement(e.getEditorInput()); + Job job = new SharedASTJob("Job Name", tu) { + @Override + public IStatus runOnAST(ILanguage lang, + IASTTranslationUnit ast) throws CoreException { + processAst(ast); + return Status.OK_STATUS; + } + }; + job.schedule(); + } + }; + action1.setText("Synchronize"); + action1.setToolTipText("Action 1 tooltip"); + action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages() + .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); + doubleClickAction = new Action() { + public void run() { + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection) selection) + .getFirstElement(); + showMessage("Double-click detected on " + obj.toString()); + } + }; + } + + private void hookDoubleClickAction() { + viewer.addDoubleClickListener(new IDoubleClickListener() { + public void doubleClick(DoubleClickEvent event) { + doubleClickAction.run(); + } + }); + } + + private void showMessage(String message) { + MessageDialog.openInformation(viewer.getControl().getShell(), + "Control Flow Graph", message); + } + + protected void processAst(IASTTranslationUnit ast) { + final ArrayList functions = new ArrayList(); + CASTVisitor visitor = new CASTVisitor() { + { + shouldVisitDeclarations = true; + } + + public int visit(IASTDeclaration decl) { + if (decl instanceof IASTFunctionDefinition) { + CxxControlFlowGraph graph = new ControlFlowGraphBuilder() + .build((IASTFunctionDefinition) decl); + functions.add(graph); + return PROCESS_SKIP; + } + return PROCESS_CONTINUE; + } + }; + ast.accept(visitor); + viewer.getControl().getDisplay().asyncExec(new Runnable() { + public void run() { + // TODO Auto-generated method stub + viewer.setInput(functions); + } + }); + } + + /** + * Passing the focus request to the viewer's control. + */ + public void setFocus() { + viewer.getControl().setFocus(); + } + + private class ASTHighlighterAction extends Action { + private static final String A_PART_INSTANCEOF = "aPart instanceof "; //$NON-NLS-1$ + IEditorPart aPart = null; + + public ASTHighlighterAction(IEditorPart part) { + this.aPart = part; + } + + public void setPart(IEditorPart part) { + this.aPart = part; + } + + protected boolean open(String filename) throws PartInitException, + CModelException { + IPath path = new Path(filename); + IFile f = ResourcesPlugin.getWorkspace().getRoot() + .getFileForLocation(path); + if (f != null) { + EditorUtility.openInEditor(f); + return true; + } + FileStorage storage = new FileStorage(null, path); + EditorUtility.openInEditor(storage); + return true; + } + + @Override + public void run() { + ISelection selection = viewer.getSelection(); + Object obj = ((IStructuredSelection) selection).getFirstElement(); + if (obj instanceof AbstractBasicBlock) { + Object data = ((AbstractBasicBlock) obj).getData(); + if (data instanceof IASTNode) { + IASTNode node = (IASTNode) data; + if (node instanceof IASTTranslationUnit) // don't + + return; + IASTFileLocation loc = node.getFileLocation(); + String filename = loc.getFileName(); + if (filename.equals("")) + return; + IResource r = ParserUtil.getResourceForFilename(filename); + if (r != null) { + try { + aPart = EditorUtility.openInEditor(r); + } catch (PartInitException pie) { + return; + } catch (CModelException e) { + return; + } + } else { +// IPath path = new Path(filename); +// if (tu != null) { +// try { +// aPart = EditorUtility.openInEditor(path, tu); +// } catch (PartInitException e) { +// return; +// } +// } + } + if (aPart instanceof AbstractTextEditor) { + ((AbstractTextEditor) aPart).selectAndReveal( + loc.getNodeOffset(), + loc.getNodeLength()); + } else + System.out.println(A_PART_INSTANCEOF + + aPart.getClass().getName()); + aPart.getSite().getPage().activate( + aPart.getSite().getPage().findView(ID)); + } + } + } + } + + private void hookSingleClickAction() { + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + new ASTHighlighterAction(null).run(); + } + }); + } +} \ No newline at end of file