void TestCollectFiles(Project project, IEnumerable <IEntity> entities, IEnumerable <Tuple <Project, IEnumerable <FilePath> > > expected)
 {
     VerifyResult(SearchCollector.CollectFiles(project, entities).ToList(), expected.ToList());
 }
        static IEnumerable <SearchCollector.FileList> GetFileNames(Solution solution, object node, RefactoryScope scope,
                                                                   IProgressMonitor monitor, IEnumerable <object> searchNodes)
        {
            if (!(node is IField) && node is IVariable || scope == RefactoryScope.File)
            {
                string fileName;
                if (node is IEntity)
                {
                    fileName = ((IEntity)node).Region.FileName;
                }
                else if (node is ITypeParameter)
                {
                    fileName = ((ITypeParameter)node).Region.FileName;
                }
                else
                {
                    fileName = ((IVariable)node).Region.FileName;
                }
                var fileList = GetFileList(fileName);
                if (fileList != null)
                {
                    yield return(fileList);
                }
                yield break;
            }

            if (node is ITypeParameter)
            {
                var typeParameter = node as ITypeParameter;
                if (typeParameter.Owner != null)
                {
                    yield return(SearchCollector.CollectDeclaringFiles(typeParameter.Owner));

                    yield break;
                }
                var fileList = GetFileList(typeParameter.Region.FileName);
                if (fileList != null)
                {
                    yield return(fileList);
                }
                yield break;
            }

            var compilationProvider = (ICompilationProvider)node;

            switch (scope)
            {
            case RefactoryScope.DeclaringType:
                var entity = (IEntity)compilationProvider;
                if (entity.DeclaringTypeDefinition != null)
                {
                    yield return(SearchCollector.CollectDeclaringFiles(entity.DeclaringTypeDefinition));
                }
                else
                {
                    yield return(SearchCollector.CollectDeclaringFiles(entity));
                }
                break;

            case RefactoryScope.Project:
                var sourceProject = TypeSystemService.GetProject(compilationProvider.Compilation.MainAssembly.UnresolvedAssembly.Location);
                foreach (var file in SearchCollector.CollectFiles(sourceProject, searchNodes))
                {
                    yield return(file);
                }
                break;

            default:
                var files = SearchCollector.CollectFiles(solution, searchNodes).ToList();
                if (monitor != null)
                {
                    monitor.BeginTask(GettextCatalog.GetString("Searching for references in solution..."), files.Count);
                }
                foreach (var file in files)
                {
                    if (monitor != null && monitor.IsCancelRequested)
                    {
                        yield break;
                    }
                    yield return(file);

                    if (monitor != null)
                    {
                        monitor.Step(1);
                    }
                }
                if (monitor != null)
                {
                    monitor.EndTask();
                }
                break;
            }
        }
 void TestCollectProjects(Solution solution, IEnumerable <IEntity> entities, IEnumerable <Project> expected)
 {
     VerifyResult(SearchCollector.CollectProjects(solution, entities).ToList(), expected.ToList());
 }
        /// <summary>
        /// collect members with the same signature/name(if overloads are included) as the specified member
        /// in the inheritance tree
        /// </summary>
        public static IEnumerable <IMember> CollectMembers(Solution solution, IMember member, ReferenceFinder.RefactoryScope scope,
                                                           bool includeOverloads = true, bool matchDeclaringType = false)
        {
            if (solution == null || member.SymbolKind == SymbolKind.Destructor || member.SymbolKind == SymbolKind.Operator)
            {
                return new [] { member }
            }
            ;

            if (member.SymbolKind == SymbolKind.Constructor)
            {
                if (includeOverloads)
                {
                    return(member.DeclaringType.GetMembers(m => m.SymbolKind == SymbolKind.Constructor, GetMemberOptions.IgnoreInheritedMembers));
                }
                return(new [] { member });
            }

            Func <IMember, bool> memberFilter = null;

            if (member is IParameterizedMember && !includeOverloads)
            {
                memberFilter = m => MatchParameters(m, member);
            }

            var declaringType = member.DeclaringTypeDefinition;

            if (declaringType == null)
            {
                return new [] { member }
            }
            ;
            // only collect members in declaringType
            if (matchDeclaringType)
            {
                return(GetMembers(declaringType, member, true, memberFilter));
            }

            if (declaringType.Kind != TypeKind.Class && declaringType.Kind != TypeKind.Interface)
            {
                return(GetMembers(declaringType, member, false, memberFilter));
            }

            var searchTypes = new List <ITypeDefinition> ();

            if (includeOverloads)
            {
                var interfaces = from t in declaringType.GetAllBaseTypeDefinitions()
                                 where t.Kind == TypeKind.Interface && GetMembers(t, member, true, memberFilter).Any()
                                 select t;
                searchTypes.AddRange(GetBaseTypes(interfaces));
            }

            if (member.DeclaringType.Kind == TypeKind.Class)
            {
                var members = GetMembers(declaringType, member, false, memberFilter).ToList();
                if (members.Any(m => m.IsOverridable))
                {
                    searchTypes.AddRange(GetBaseTypes(members.Select(m => m.DeclaringTypeDefinition)));
                }
                else if (searchTypes.Count == 0)
                {
                    return(members);
                }
            }

            IList <ICompilation> compilations;

            if (scope == ReferenceFinder.RefactoryScope.Solution || scope == ReferenceFinder.RefactoryScope.Unknown)
            {
                var projects = SearchCollector.CollectProjects(solution, searchTypes);
                compilations = projects.Select(TypeSystemService.GetCompilation).ToList();
            }
            else
            {
                compilations = new [] { member.Compilation };
            }

            var result             = new List <IMember> ();
            var mainAssemblies     = new HashSet <string> (compilations.Select(c => c.MainAssembly.AssemblyName));
            var searchedAssemblies = new HashSet <string> ();
            var searchedTypes      = new HashSet <string> ();

            foreach (var compilation in compilations)
            {
                var baseTypeImports = Import(compilation, searchTypes).Where(t => t != null).ToList();
                if (!baseTypeImports.Any())
                {
                    continue;
                }

                foreach (var assembly in compilation.Assemblies)
                {
                    // search main assemblies in their projects' own compilation, to avoid possible resolving problems
                    if ((mainAssemblies.Contains(assembly.AssemblyName) && assembly != compilation.MainAssembly) ||
                        !searchedAssemblies.Add(assembly.AssemblyName))
                    {
                        continue;
                    }

                    foreach (var type in assembly.GetAllTypeDefinitions())
                    {
                        // members in base types will also be added
                        // because IsDerivedFrom return true for a type itself
                        if (!searchedTypes.Add(type.ReflectionName) || !baseTypeImports.Any(type.IsDerivedFrom))
                        {
                            continue;
                        }
                        result.AddRange(GetMembers(type, member, true, memberFilter));
                    }
                }
            }
            if (!result.Contains(member))
            {
                result.Add(member);
            }
            return(result);
        }
    }
}