private void CreateModuleTree(LibraryNode root, LibraryNode current, IScopeNode scope, string namePrefix, ModuleId moduleId) { if ((null == root) || (null == scope) || (null == scope.NestedScopes)) { return; } foreach (IScopeNode subItem in scope.NestedScopes) { LibraryNode newNode = CreateLibraryNode(subItem, namePrefix, moduleId.Hierarchy, moduleId.ItemID); string newNamePrefix = namePrefix; // The classes are always added to the root node, the functions to the // current node. if ((newNode.NodeType & LibraryNode.LibraryNodeType.Members) != LibraryNode.LibraryNodeType.None) { current.AddNode(newNode); } else if ((newNode.NodeType & LibraryNode.LibraryNodeType.Classes) != LibraryNode.LibraryNodeType.None) { // Classes are always added to the root. root.AddNode(newNode); newNamePrefix = newNode.Name + "."; } // Now use recursion to get the other types. CreateModuleTree(root, newNode, subItem, newNamePrefix, moduleId); } }
/// <summary> /// Called by derived class when a file has been parsed. The caller should /// provide the LibraryTask received from the OnNewFile call and an IScopeNode /// which represents the contents of the library. /// /// It is safe to call this method from any thread. /// </summary> protected void FileParsed(LibraryTask task, IScopeNode scope) { LibraryNode module = new LibraryNode( System.IO.Path.GetFileName(task.FileName), LibraryNode.LibraryNodeType.PhysicalContainer ); // TODO: Creating the module tree should be done lazily as needed // Currently we replace the entire tree and rely upon the libraries // update count to invalidate the whole thing. We could do this // finer grained and only update the changed nodes. But then we // need to make sure we're not mutating lists which are handed out. CreateModuleTree(module, module, scope, "", task.ModuleID); if (null != task.ModuleID) { LibraryNode previousItem = null; lock (_files) { if (_files.TryGetValue(task.ModuleID, out previousItem)) { _files.Remove(task.ModuleID); } } _library.RemoveNode(previousItem); } _library.AddNode(module); if (null != task.ModuleID) { lock (_files) { _files.Add(task.ModuleID, module); } } }
internal void RemoveNode(LibraryNode node) { lock (this) { _root = new LibraryNode(_root); _root.RemoveNode(node); _updateCount++; } }
internal void AddNode(LibraryNode node) { lock (this) { // re-create root node here because we may have handed out the node before and don't want to mutate it's list. _root = new LibraryNode(_root); _root.AddNode(node); _updateCount++; } }
private void OnDeleteFile(object sender, HierarchyEventArgs args) { IVsHierarchy hierarchy = sender as IVsHierarchy; if (null == hierarchy) { return; } ModuleId id = new ModuleId(hierarchy, args.ItemID); LibraryNode node = null; lock (_files) { if (_files.TryGetValue(id, out node)) { _files.Remove(id); } } if (null != node) { _library.RemoveNode(node); } }
public Library(Guid libraryGuid) { _guid = libraryGuid; _root = new LibraryNode(String.Empty, LibraryNode.LibraryNodeType.Package); }