c# - Determine if CodeElement belongs to project -


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