예제 #1
0
        private bool RecurseInto(SelectionItem si, ProjectWalkDepth depth)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            object value;

            if (VSErr.Succeeded(si.Hierarchy.GetProperty(si.Id,
                                                         (int)__VSHPROPID.VSHPROPID_HasEnumerationSideEffects, out value)))
            {
                if (value != null)
                {
                    bool hasSideEffects = (bool)value;

                    // Unless we are walking SCC projects, don't go deeper
                    // because we don't want side effects!

                    if (hasSideEffects)
                    {
                        if (depth == ProjectWalkDepth.AllDescendantsInHierarchy && IgnoreSideEffects(si.SccProject))
                        {
                            return(true);
                        }

                        return(false);
                    }
                }
            }

            if (si.SccProject == null && VSErr.Succeeded(si.Hierarchy.GetProperty(si.Id,
                                                                                  (int)__VSHPROPID2.VSHPROPID_ChildrenEnumerated, out value)))
            {
                if (value != null)
                {
                    bool childrenEnumerated = (bool)value;

                    if (!childrenEnumerated)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Gets the list of files specified by the hierarchy (IVsSccProject2 or IVsHierarchy)
        /// </summary>
        /// <param name="hierarchy"></param>
        /// <param name="id"></param>
        /// <param name="depth"></param>
        /// <returns></returns>
        /// <remarks>The list might contain duplicates if files are included more than once</remarks>
        public IEnumerable <string> GetSccFiles(IVsHierarchy hierarchy, uint id, ProjectWalkDepth depth, IDictionary <string, uint> map)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // Note: This command is not cached like the other commands on this object!
            if (hierarchy == null)
            {
                throw new ArgumentNullException("hierarchy");
            }

            SelectionItem si = new SelectionItem(hierarchy, id);

            string[] files;
            if (!SelectionUtils.GetSccFiles(si, out files, depth >= ProjectWalkDepth.SpecialFiles, IncludeNoScc(depth), map))
            {
                yield break;
            }

            foreach (string file in files)
            {
                yield return(SvnTools.GetNormalizedFullPath(file));
            }

            if (depth > ProjectWalkDepth.SpecialFiles)
            {
                Dictionary <SelectionItem, SelectionItem> previous = new Dictionary <SelectionItem, SelectionItem>();
                previous.Add(si, si);

                foreach (SelectionItem item in GetDescendants(si, previous, depth))
                {
                    if (!SelectionUtils.GetSccFiles(item, out files, depth >= ProjectWalkDepth.SpecialFiles, depth != ProjectWalkDepth.AllDescendantsInHierarchy, map))
                    {
                        continue;
                    }

                    foreach (string file in files)
                    {
                        yield return(SvnTools.GetNormalizedFullPath(file));
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Gets the descendants of a selection item; yielding for each result to allow delay loading
        /// </summary>
        /// <param name="si"></param>
        /// <param name="previous"></param>
        /// <returns></returns>
        private IEnumerable <SelectionItem> GetDescendants(SelectionItem si, Dictionary <SelectionItem, SelectionItem> previous, ProjectWalkDepth depth)
        {
            if (si == null)
            {
                throw new ArgumentNullException("si");
            }

            // A hierarchy node can have 2 identities. We only need the inner one

            uint   subId;
            IntPtr hierPtr;
            int    hr;

            try
            {
                hr = si.Hierarchy.GetNestedHierarchy(si.Id, ref hierarchyId, out hierPtr, out subId);
            }
            catch (Exception e)
            {
                ExternalException ee = e as ExternalException;

                if (ee != null && !VSErr.Succeeded(ee.ErrorCode))
                {
                    hr = ee.ErrorCode; // Should have been returned instead
                }
                else if (e is NotImplementedException)
                {
                    hr = VSErr.E_NOTIMPL; // From Microsoft.VisualStudio.PerformanceTools.DummyVsUIHierarchy.GetNestedHierarchy()
                }
                else
                {
                    hr = VSErr.E_FAIL;
                }

                hierPtr = IntPtr.Zero;
                subId   = VSItemId.Nil;
            }

            if (VSErr.Succeeded(hr) && hierPtr != IntPtr.Zero)
            {
                IVsHierarchy nestedHierarchy = Marshal.GetObjectForIUnknown(hierPtr) as IVsHierarchy;
                Marshal.Release(hierPtr);

                if (nestedHierarchy == null || (nestedHierarchy == MiscellaneousProject))
                {
                    yield break;
                }

                if (depth <= ProjectWalkDepth.AllDescendantsInHierarchy)
                {
                    yield break; // Don't walk into sub-hierarchies
                }
                else
                {
                    si = new SelectionItem(nestedHierarchy, subId);
                }
            }

            if (!previous.ContainsKey(si))
            {
                previous.Add(si, si);
                yield return(si);
            }

            // Note: VS2005 and earlier have all projects on the top level; from VS2008+ projects are nested
            // We can ignore that as we would include the projects anyway

            if (!RecurseInto(si, depth))
            {
                yield break;
            }

            object value;

            if (!VSErr.Succeeded(si.Hierarchy.GetProperty(si.Id,
                                                          (int)__VSHPROPID.VSHPROPID_FirstChild, out value)))
            {
                yield break;
            }

            uint childId = GetItemIdFromObject(value);

            while (childId != VSItemId.Nil)
            {
                SelectionItem i = new SelectionItem(si.Hierarchy, childId);

                foreach (SelectionItem ii in GetDescendants(i, previous, depth))
                {
                    yield return(ii);
                }

                if (!VSErr.Succeeded(si.Hierarchy.GetProperty(i.Id,
                                                              (int)__VSHPROPID.VSHPROPID_NextSibling, out value)))
                {
                    yield break;
                }

                childId = GetItemIdFromObject(value);
            }
        }
예제 #4
0
 bool IncludeNoScc(ProjectWalkDepth depth)
 {
     return((depth != ProjectWalkDepth.AllDescendantsInHierarchy) && (depth != ProjectWalkDepth.SpecialFiles));
 }