183 lines
7.3 KiB
C#
Raw Normal View History

/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Apache License, Version 2.0, please send an email to
* vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/
using System;
using System.Collections.Generic;
using System.Threading;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell.Interop;
using VSConstants = Microsoft.VisualStudio.VSConstants;
namespace Microsoft.VisualStudio.Navigation {
/// <summary>
/// Implements a simple library that tracks project symbols, objects etc.
/// </summary>
public class Library : IVsSimpleLibrary2 {
private Guid _guid;
private _LIB_FLAGS2 _capabilities;
private LibraryNode _root;
private uint _updateCount;
public Library(Guid libraryGuid) {
_guid = libraryGuid;
_root = new LibraryNode(String.Empty, String.Empty, LibraryNodeType.Package);
}
public _LIB_FLAGS2 LibraryCapabilities {
get { return _capabilities; }
set { _capabilities = value; }
}
public 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++;
}
}
public void RemoveNode(LibraryNode node) {
lock (this) {
_root = _root.Clone();
_root.RemoveNode(node);
_updateCount++;
}
}
#region IVsSimpleLibrary2 Members
public int AddBrowseContainer(VSCOMPONENTSELECTORDATA[] pcdComponent, ref uint pgrfOptions, out string pbstrComponentAdded) {
pbstrComponentAdded = null;
return VSConstants.E_NOTIMPL;
}
public int CreateNavInfo(SYMBOL_DESCRIPTION_NODE[] rgSymbolNodes, uint ulcNodes, out IVsNavInfo ppNavInfo) {
ppNavInfo = null;
return VSConstants.E_NOTIMPL;
}
public int GetBrowseContainersForHierarchy(IVsHierarchy pHierarchy, uint celt, VSBROWSECONTAINER[] rgBrowseContainers, uint[] pcActual) {
return VSConstants.E_NOTIMPL;
}
public int GetGuid(out Guid pguidLib) {
pguidLib = _guid;
return VSConstants.S_OK;
}
public int GetLibFlags2(out uint pgrfFlags) {
pgrfFlags = (uint)LibraryCapabilities;
return VSConstants.S_OK;
}
public int GetList2(uint ListType, uint flags, VSOBSEARCHCRITERIA2[] pobSrch, out IVsSimpleObjectList2 ppIVsSimpleObjectList2) {
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 (var item in _root.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("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 {
ppIVsSimpleObjectList2 = null;
return VSConstants.E_FAIL;
}
}
} else {
ppIVsSimpleObjectList2 = _root as IVsSimpleObjectList2;
}
return VSConstants.S_OK;
}
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 void VisitNodes(ILibraryNodeVisitor visitor, CancellationToken ct = default(CancellationToken)) {
lock (this) {
_root.Visit(visitor, ct);
}
}
public int GetSeparatorStringWithOwnership(out string pbstrSeparator) {
pbstrSeparator = ".";
return VSConstants.S_OK;
}
public int GetSupportedCategoryFields2(int Category, out uint pgrfCatField) {
pgrfCatField = (uint)_LIB_CATEGORY2.LC_HIERARCHYTYPE | (uint)_LIB_CATEGORY2.LC_PHYSICALCONTAINERTYPE;
return VSConstants.S_OK;
}
public int LoadState(IStream pIStream, LIB_PERSISTTYPE lptType) {
return VSConstants.S_OK;
}
public int RemoveBrowseContainer(uint dwReserved, string pszLibName) {
return VSConstants.E_NOTIMPL;
}
public int SaveState(IStream pIStream, LIB_PERSISTTYPE lptType) {
return VSConstants.S_OK;
}
public int UpdateCounter(out uint pCurUpdate) {
pCurUpdate = _updateCount;
return VSConstants.S_OK;
}
#endregion
}
}