i'm trying develop plugin visual studio 2015. have command gets added context menu when project right clicked , can project right clicked. trying determine if project contains class implements interface. first step classes in project. did this:
protected ienumerable<envdte.codeclass> getclasses(envdte.codeelements elements, envdte.project project) { foreach (envdte.codeelement element in elements) { system.diagnostics.debug.writeline(element.infolocation); var cls = element envdte.codeclass; if (cls != null) { yield return cls; } var ns = element envdte.codenamespace; if (ns != null) { foreach (var childcls in getclasses(ns.members, project)) { yield return childcls; } } } }
so go through , pull out classes. problem go through referenced include bcl classes. thought using infolocation
might help, returns vscminfolocationexternal
(presumably because in context plugin running, external). i've tried things element.projectitem
, element.projectitem.containingproject
, element.parent
hope of comparing parent project, throw system.runtime.interopservices.comexception
. there way, given know project, determine if particular codeelement
part of project, or referenced project?
edit: best i've been able come far this, first default namespace project:
var defaultns = project.properties.item("defaultnamespace").value.tostring();
and can this:
if (ns != null && ns.name == defaultns)
so won't go drilling down system
, good. problem if project had multiple namespaces wanted search. can't figure out if there way list of namespaces defined in project.
edit: suggested dupe deals type
isn't entirely relevant.
this may suit needs or may not used parse code elements , figure out if definition in solution or if comes in via reference. there no way know if reference 3rd party vs bcl however. code removed brevity since inside api , hard break out. add trick once have types full name , know reference reflect dlls signed microsoft key type name, if find 1 bcl, otherwise probably not.
public static string codeelementastypefullname(envdte80.codeelement2 element) { if (element == null) throw new argumentnullexception(nameof(element)); if (element.kind == vscmelement.vscmelementclass || element.kind == vscmelement.vscmelementenum || element.kind == vscmelement.vscmelementstruct) return element.fullname; else return ((dynamic)element).type.asfullname; } protected void flattenelement(envdte80.codeelement2 element) { try { string vartype = codeelementastypefullname(element); switch (element.kind) { case vscmelement.vscmelementvariable: case vscmelement.vscmelementproperty: { envdte80.codeelement2 defined = null; ///this api, collection of files in solution class/enum/stuct defs parsed out collections. foreach (squishfile file in this.solutionfiles) { //next line goes through each solution file 1 one figure out if file defines class/enum/struct definition. defined = file.containscodeelement(vartype); if (defined != null) break; } if (defined != null) { if (defined.kind == vscmelement.vscmelementclass || defined.kind == vscmelement.vscmelementstruct || defined.kind == vscmelement.vscmelementenum) //the item defined locally! }else //the item reference } } } public class squishfile { public concurrentbag<codeclass> classdefinitions = new concurrentbag<codeclass>(); public concurrentbag<codeenum> enumdefinitions = new concurrentbag<codeenum>(); public concurrentbag<codestruct> structdefinitions = new concurrentbag<codestruct>(); protected projectitem _projectitem; public projectitem projectitem { { return _projectitem; } } public squishfile(projectitem projectitem) { if (projectitem.filecodemodel == null) throw new exception("cannot make squish file out of project item no filecodemodel!"); _projectitem = projectitem; foreach (envdte80.codeelement2 ele in projectitem.filecodemodel.codeelements) discovery(ele); } public envdte80.codeelement2 containscodeelement(string fullname) { foreach(envdte80.codeelement2 ele in classdefinitions) if (ele.fullname.equals(fullname)) return ele; foreach (envdte80.codeelement2 ele in enumdefinitions) if (ele.fullname.equals(fullname)) return ele; foreach (envdte80.codeelement2 ele in structdefinitions) if (ele.fullname.equals(fullname)) return ele; return null; } protected void discovery(envdte80.codeelement2 element) { if (element.iscodetype && element.kind == vscmelement.vscmelementclass) this.classdefinitions.add(element envdte80.codeclass2); else if (element.iscodetype && element.kind == vscmelement.vscmelementenum) this.enumdefinitions.add(element envdte.codeenum); else if (element.iscodetype && element.kind == vscmelement.vscmelementstruct) this.structdefinitions.add(element envdte80.codestruct2); foreach (envdte80.codeelement2 ele in element.children) discovery(ele); } }
Comments
Post a Comment