internal void RemoveNode(LibraryNode node) { lock (_updates) { _updates.Add(new KeyValuePair <UpdateType, LibraryNode>(UpdateType.Remove, node)); } ApplyUpdates(false); }
public Library(Guid libraryGuid) { _guid = libraryGuid; _root = new LibraryNode(null, String.Empty, String.Empty, LibraryNodeType.Package); _updates = new List <KeyValuePair <UpdateType, LibraryNode> >(); _searching = new SemaphoreSlim(1); }
internal async void AddNode(LibraryNode node) { lock (_updates) { _updates.Add(new KeyValuePair <UpdateType, LibraryNode>(UpdateType.Add, node)); } ApplyUpdates(false); }
protected CommonLibraryNode(LibraryNode parent, IScopeNode scope, string namePrefix, IVsHierarchy hierarchy, uint itemId) : base(parent, GetLibraryNodeName(scope, namePrefix), namePrefix + scope.Name, scope.NodeType) { _ownerHierarchy = hierarchy; _fileId = itemId; // Now check if we have all the information to navigate to the source location. if ((null != _ownerHierarchy) && (VSConstants.VSITEMID_NIL != _fileId)) { if ((SourceLocation.Invalid != scope.Start) && (SourceLocation.Invalid != scope.End)) { _sourceSpan = new TextSpan(); _sourceSpan.iStartIndex = scope.Start.Column - 1; if (scope.Start.Line > 0) { _sourceSpan.iStartLine = scope.Start.Line - 1; } _sourceSpan.iEndIndex = scope.End.Column; if (scope.End.Line > 0) { _sourceSpan.iEndLine = scope.End.Line - 1; } CanGoToSource = true; } } _scope = scope; }
internal void RemoveNode(LibraryNode node) { lock (this) { _root = _root.Clone(); _root.RemoveNode(node); _updateCount++; } }
internal void RemoveNode(LibraryNode node) { lock (syncLock) { this.root = this.root.Clone(); this.root.RemoveNode(node); this.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 = _root.Clone(); _root.AddNode(node); _updateCount++; } }
/// <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) { try { var project = task.ModuleID.Hierarchy.GetProject()?.GetCommonProject(); if (project == null) { return; } HierarchyNode fileNode = fileNode = project.NodeFromItemId(task.ModuleID.ItemID); HierarchyInfo parent; if (fileNode == null || !_hierarchies.TryGetValue(task.ModuleID.Hierarchy, out parent)) { return; } LibraryNode module = CreateFileLibraryNode( parent.ProjectLibraryNode, fileNode, System.IO.Path.GetFileName(task.FileName), task.FileName ); // 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. if (null != task.ModuleID) { LibraryNode previousItem = null; lock (_files) { if (_files.TryGetValue(task.ModuleID, out previousItem)) { _files.Remove(task.ModuleID); parent.ProjectLibraryNode.RemoveNode(previousItem); } } } parent.ProjectLibraryNode.AddNode(module); _library.Update(); if (null != task.ModuleID) { lock (_files) { _files.Add(task.ModuleID, module); } } } catch (COMException) { // we're shutting down and can't get the project } }
private void ApplyUpdates(bool assumeLockHeld) { if (!assumeLockHeld) { if (!_searching.Wait(0)) { // Didn't get the lock immediately, which means we are // currently searching. Once the search is done, updates // will be applied. return; } } try { lock (_updates) { if (_updates.Count == 0) { return; } // re-create root node here because we may have handed out // the node before and don't want to mutate it's list. _root = _root.Clone(); _updateCount += 1; foreach (var kv in _updates) { switch (kv.Key) { case UpdateType.Add: _root.AddNode(kv.Value); break; case UpdateType.Remove: _root.RemoveNode(kv.Value); break; default: Debug.Fail("Unsupported update type " + kv.Key.ToString()); break; } } _updates.Clear(); } } finally { if (!assumeLockHeld) { _searching.Release(); } } }
/// <summary> /// Does a delete w/o checking if it's a non-meber item, for handling the /// transition from member item to non-member item. /// </summary> private void OnDeleteFile(IVsHierarchy hierarchy, HierarchyEventArgs args) { 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); } }
/// <summary> /// Does a delete w/o checking if it's a non-meber item, for handling the /// transition from member item to non-member item. /// </summary> private void OnDeleteFile(IVsHierarchy hierarchy, HierarchyEventArgs args) { var id = new ModuleId(hierarchy, args.ItemID); LibraryNode node = null; lock (this._files) { if (this._files.TryGetValue(id, out node)) { this._files.Remove(id); if (this._hierarchies.TryGetValue(hierarchy, out var parent)) { parent.ProjectLibraryNode.RemoveNode(node); } } } if (null != node) { this._library.RemoveNode(node); } }
private void CreateModuleTree(LibraryNode current, IScopeNode scope, string namePrefix, ModuleId moduleId) { if ((null == scope) || (null == scope.NestedScopes)) { return; } foreach (IScopeNode subItem in scope.NestedScopes) { LibraryNode newNode = CreateLibraryNode(current, subItem, namePrefix, moduleId.Hierarchy, moduleId.ItemID); string newNamePrefix = namePrefix; current.AddNode(newNode); if ((newNode.NodeType & LibraryNodeType.Classes) != LibraryNodeType.None) { newNamePrefix = namePrefix + newNode.Name + "."; } // Now use recursion to get the other types. CreateModuleTree(newNode, subItem, newNamePrefix, moduleId); } }
public virtual LibraryNode CreateFileLibraryNode(LibraryNode parent, HierarchyNode hierarchy, string name, string filename, LibraryNodeType libraryNodeType) { return(new LibraryNode(null, name, filename, libraryNodeType)); }
protected abstract LibraryNode CreateLibraryNode(LibraryNode parent, IScopeNode subItem, string namePrefix, IVsHierarchy hierarchy, uint itemid);
public Library(Guid libraryGuid) { this._guid = libraryGuid; this._root = new LibraryNode(null, string.Empty, string.Empty, LibraryNodeType.Package); }
private static SimpleObjectList <LibraryNode> SearchNodes(VSOBSEARCHCRITERIA2 srch, SimpleObjectList <LibraryNode> list, LibraryNode curNode) { foreach (var child in curNode.Children) { if (child.Name.IndexOf(srch.szName, StringComparison.OrdinalIgnoreCase) != -1) { list.Children.Add(child.Clone(child.Name)); } SearchNodes(srch, list, child); } return(list); }
public int GetList2(uint ListType, uint flags, VSOBSEARCHCRITERIA2[] pobSrch, out IVsSimpleObjectList2 ppIVsSimpleObjectList2) { if ((flags & (uint)_LIB_LISTFLAGS.LLF_RESOURCEVIEW) != 0) { ppIVsSimpleObjectList2 = null; return(VSConstants.E_NOTIMPL); } ICustomSearchListProvider listProvider; if (pobSrch != null && pobSrch.Length > 0) { if ((listProvider = pobSrch[0].pIVsNavInfo as ICustomSearchListProvider) != null) { switch ((_LIB_LISTTYPE)ListType) { case _LIB_LISTTYPE.LLT_NAMESPACES: ppIVsSimpleObjectList2 = listProvider.GetSearchList(); break; default: ppIVsSimpleObjectList2 = null; return(VSConstants.E_FAIL); } } else { if (pobSrch[0].eSrchType == VSOBSEARCHTYPE.SO_ENTIREWORD && ListType == (uint)_LIB_LISTTYPE.LLT_MEMBERS) { string srchText = pobSrch[0].szName; int colonIndex; if ((colonIndex = srchText.LastIndexOf(':')) != -1) { string filename = srchText.Substring(0, srchText.LastIndexOf(':')); foreach (ProjectLibraryNode project in _root.Children) { foreach (var item in project.Children) { if (item.FullName == filename) { ppIVsSimpleObjectList2 = item.DoSearch(pobSrch[0]); if (ppIVsSimpleObjectList2 != null) { return(VSConstants.S_OK); } } } } } ppIVsSimpleObjectList2 = null; return(VSConstants.E_FAIL); } else if (pobSrch[0].eSrchType == VSOBSEARCHTYPE.SO_SUBSTRING && ListType == (uint)_LIB_LISTTYPE.LLT_NAMESPACES) { var lib = new LibraryNode(null, "Search results " + pobSrch[0].szName, "Search results " + pobSrch[0].szName, LibraryNodeType.Package); foreach (var item in SearchNodes(pobSrch[0], new SimpleObjectList <LibraryNode>(), _root).Children) { lib.Children.Add(item); } ppIVsSimpleObjectList2 = lib; return(VSConstants.S_OK); } else if ((pobSrch[0].grfOptions & (uint)_VSOBSEARCHOPTIONS.VSOBSO_LOOKINREFS) != 0 && ListType == (uint)_LIB_LISTTYPE.LLT_HIERARCHY) { LibraryNode node = pobSrch[0].pIVsNavInfo as LibraryNode; if (node != null) { var refs = node.FindReferences(); if (refs != null) { ppIVsSimpleObjectList2 = refs; return(VSConstants.S_OK); } } } ppIVsSimpleObjectList2 = null; return(VSConstants.E_FAIL); } } else { ppIVsSimpleObjectList2 = _root as IVsSimpleObjectList2; } return(VSConstants.S_OK); }
protected CommonLibraryNode(LibraryNode parent, string name, string fullName, IVsHierarchy hierarchy, uint itemId, LibraryNodeType type, IList <LibraryNode> children = null) : base(parent, name, fullName, type, children: children) { _ownerHierarchy = hierarchy; _fileId = itemId; }
public Library(Guid libraryGuid) { _guid = libraryGuid; _root = new LibraryNode(null, String.Empty, String.Empty, LibraryNodeType.Package); }
public NodeFileLibraryNode(LibraryNode parent, HierarchyNode hierarchy, string name, string filename, LibraryNodeType libraryNodeType) : base(parent, name, filename, libraryNodeType) { }