Exemplo n.º 1
0
		/// <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.EntityType == EntityType.Destructor || member.EntityType == EntityType.Operator)
				return new [] { member };

			if (member.EntityType == EntityType.Constructor) {
				if (includeOverloads)
					return member.DeclaringType.GetMembers (m => m.EntityType == EntityType.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;
			// only collect members in declaringType
			if (matchDeclaringType)
				return GetMembers (declaringType, member.Name, true, memberFilter);

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

			var searchTypes = new List<ITypeDefinition> ();
			var interfaces = from t in declaringType.GetAllBaseTypeDefinitions ()
							 where t.Kind == TypeKind.Interface && GetMembers (t, member.Name, true, memberFilter).Any ()
							 select t;
			searchTypes.AddRange (GetBaseTypes (interfaces));

			if (member.DeclaringType.Kind == TypeKind.Class) {
				var members = GetMembers (declaringType, member.Name, 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 (baseType => type.IsDerivedFrom (baseType)))
							continue;
						result.AddRange (GetMembers (type, member.Name, true, memberFilter));
					}
				}
			}
			return result;
		}
Exemplo n.º 2
0
        void Collect(Project sourceProject, IEntity entity, bool searchInProject = false)
        {
            if (searchedProjects.Contains(sourceProject))
            {
                return;
            }

            if (searchProject != null && sourceProject != searchProject)
            {
                // searching for a entity not defined in the project
                AddProject(searchProject);
                return;
            }

            if (sourceProject == null)
            {
                if (entity == null)
                {
                    foreach (var project in solution.GetAllProjects())
                    {
                        AddProject(project);
                    }
                    return;
                }
                // entity is defined in a referenced assembly
                var assemblyName = entity.ParentAssembly.AssemblyName;
                if (!searchedAssemblies.Add(assemblyName))
                {
                    return;
                }
                foreach (var project in GetAllReferencingProjects(solution, assemblyName))
                {
                    AddProject(project);
                }

                return;
            }

            var declaringType = entity.DeclaringTypeDefinition;

            // TODO: possible optimization for protected
            switch (entity.Accessibility)
            {
            case Accessibility.Public:
            case Accessibility.Protected:
            case Accessibility.ProtectedOrInternal:
            case Accessibility.Internal:
            case Accessibility.ProtectedAndInternal:

                if (declaringType != null)
                {
                    Collect(sourceProject, entity.DeclaringTypeDefinition, searchInProject);
                }
                else if (searchProject != null || searchInProject)
                {
                    AddProject(sourceProject);
                }
                else
                {
                    foreach (var project in ReferenceFinder.GetAllReferencingProjects(solution, sourceProject))
                    {
                        if (entity.Accessibility == Accessibility.Internal || entity.Accessibility == Accessibility.ProtectedAndInternal)
                        {
                            if (!entity.ParentAssembly.InternalsVisibleTo(TypeSystemService.GetProjectContentWrapper(project).Compilation.MainAssembly))
                            {
                                continue;
                            }
                        }
                        AddProject(project);
                    }
                }
                break;

            default:             // private
                if (projectOnly)
                {
                    AddProject(sourceProject);
                }
                else if (declaringType != null)
                {
                    AddFiles(sourceProject, declaringType.Parts.Select(p => p.Region.FileName));
                }
                break;
            }
        }