~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/MemberCollector.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// 
2
 
// MemberCollector.cs
3
 
//  
4
 
// Author:
5
 
//       Mansheng Yang <lightyang0@gmail.com>
6
 
// 
7
 
// Copyright (c) 2012 Mansheng Yang
8
 
// 
9
 
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
 
// of this software and associated documentation files (the "Software"), to deal
11
 
// in the Software without restriction, including without limitation the rights
12
 
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 
// copies of the Software, and to permit persons to whom the Software is
14
 
// furnished to do so, subject to the following conditions:
15
 
// 
16
 
// The above copyright notice and this permission notice shall be included in
17
 
// all copies or substantial portions of the Software.
18
 
// 
19
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
 
// THE SOFTWARE.
26
 
using System;
27
 
using System.Collections.Generic;
28
 
using System.Linq;
29
 
using MonoDevelop.Projects;
30
 
using MonoDevelop.Ide.TypeSystem;
31
 
using ICSharpCode.NRefactory.TypeSystem;
32
 
 
33
 
namespace MonoDevelop.Ide.FindInFiles
34
 
{
35
 
        public static class MemberCollector
36
 
        {
37
 
 
38
 
                static bool MatchParameters (IMember a, IMember b)
39
 
                {
40
 
                        return MatchParameters (a as IParameterizedMember, b as IParameterizedMember);
41
 
                }
42
 
 
43
 
                static bool MatchParameters (IParameterizedMember a, IParameterizedMember b)
44
 
                {
45
 
                        if (a == null && b == null) return true;
46
 
                        if (a == null || b == null) return false;
47
 
                        return ParameterListComparer.Instance.Equals (a.Parameters, b.Parameters);
48
 
                }
49
 
 
50
 
                /// <summary>
51
 
                /// find all base types(types that are not derived from other types) in the specified types
52
 
                /// </summary>
53
 
                /// <param name="types"></param>
54
 
                /// <returns></returns>
55
 
                public static IEnumerable<ITypeDefinition> GetBaseTypes (IEnumerable<ITypeDefinition> types)
56
 
                {
57
 
                        if (types == null)
58
 
                                yield break;
59
 
                        types = types.ToList ();
60
 
                        if (!types.Any ())
61
 
                                yield break;
62
 
 
63
 
                        var baseType = types.FirstOrDefault ();
64
 
                        var otherTypes = new List<ITypeDefinition> ();
65
 
 
66
 
                        foreach (var type in types.Skip (1)) {
67
 
                                if (baseType.IsDerivedFrom (type)) {
68
 
                                        baseType = type;
69
 
                                } else if (!type.IsDerivedFrom (baseType)) {
70
 
                                        // this type is not directly related to baseType
71
 
                                        otherTypes.Add (type);
72
 
                                }
73
 
                        }
74
 
                        yield return baseType;
75
 
                        foreach (var type in GetBaseTypes (otherTypes))
76
 
                                yield return type;
77
 
                }
78
 
 
79
 
                static IEnumerable<IMember> GetMembers (ITypeDefinition type, string name, bool ignoreInherited,
80
 
                                                                                                Func<IMember, bool> filter)
81
 
                {
82
 
                        var options = ignoreInherited ? GetMemberOptions.IgnoreInheritedMembers : GetMemberOptions.None;
83
 
                        var members = type.GetMembers (m => m.Name == name, options);
84
 
                        if (filter != null)
85
 
                                members = members.Where (filter);
86
 
                        return members;
87
 
                }
88
 
 
89
 
                static IEnumerable<ITypeDefinition> Import (ICompilation compilation, IEnumerable<ITypeDefinition> types)
90
 
                {
91
 
                        return types.Select (t => compilation.Import (t));
92
 
                }
93
 
 
94
 
                /// <summary>
95
 
                /// collect members with the same signature/name(if overloads are included) as the specified member
96
 
                /// in the inheritance tree
97
 
                /// </summary>
98
 
                public static IEnumerable<IMember> CollectMembers (Solution solution, IMember member, ReferenceFinder.RefactoryScope scope,
99
 
                                                                                                                   bool includeOverloads = true, bool matchDeclaringType = false)
100
 
                {
101
 
                        if (solution == null || member.EntityType == EntityType.Destructor || member.EntityType == EntityType.Operator)
102
 
                                return new [] { member };
103
 
 
104
 
                        if (member.EntityType == EntityType.Constructor) {
105
 
                                if (includeOverloads)
106
 
                                        return member.DeclaringType.GetConstructors ();
107
 
                                return new [] { member };
108
 
                        }
109
 
 
110
 
                        Func<IMember, bool> memberFilter = null;
111
 
                        if (member is IParameterizedMember && !includeOverloads)
112
 
                                memberFilter = m => MatchParameters (m, member);
113
 
 
114
 
                        var declaringType = member.DeclaringTypeDefinition;
115
 
                        // only collect members in declaringType
116
 
                        if (matchDeclaringType)
117
 
                                return GetMembers (declaringType, member.Name, true, memberFilter);
118
 
 
119
 
                        if (declaringType.Kind != TypeKind.Class && declaringType.Kind != TypeKind.Interface)
120
 
                                return GetMembers (declaringType, member.Name, false, memberFilter);
121
 
 
122
 
                        var searchTypes = new List<ITypeDefinition> ();
123
 
                        var interfaces = from t in declaringType.GetAllBaseTypeDefinitions ()
124
 
                                                         where t.Kind == TypeKind.Interface && GetMembers (t, member.Name, true, memberFilter).Any ()
125
 
                                                         select t;
126
 
                        searchTypes.AddRange (GetBaseTypes (interfaces));
127
 
 
128
 
                        if (member.DeclaringType.Kind == TypeKind.Class) {
129
 
                                var members = GetMembers (declaringType, member.Name, false, memberFilter).ToList ();
130
 
                                if (members.Any (m => m.IsOverridable))
131
 
                                        searchTypes.AddRange (GetBaseTypes (members.Select (m => m.DeclaringTypeDefinition)));
132
 
                                else if (searchTypes.Count == 0)
133
 
                                        return members;
134
 
                        }
135
 
 
136
 
                        IList<ICompilation> compilations;
137
 
                        if (scope == ReferenceFinder.RefactoryScope.Solution || scope == ReferenceFinder.RefactoryScope.Unknown) {
138
 
                                var projects = SearchCollector.CollectProjects (solution, searchTypes);
139
 
                                compilations = projects.Select (TypeSystemService.GetCompilation).ToList ();
140
 
                        } else {
141
 
                                compilations = new [] { member.Compilation };
142
 
                        }
143
 
 
144
 
                        var result = new List<IMember> ();
145
 
                        var mainAssemblies = new HashSet<string> (compilations.Select (c => c.MainAssembly.AssemblyName));
146
 
                        var searchedAssemblies = new HashSet<string> ();
147
 
                        var searchedTypes = new HashSet<string> ();
148
 
 
149
 
                        foreach (var compilation in compilations) {
150
 
                                var baseTypeImports = Import(compilation, searchTypes).Where (t => t != null).ToList ();
151
 
                                if (!baseTypeImports.Any ()) continue;
152
 
 
153
 
                                foreach (var assembly in compilation.Assemblies) {
154
 
                                        // search main assemblies in their projects' own compilation, to avoid possible resolving problems
155
 
                                        if ((mainAssemblies.Contains(assembly.AssemblyName) && assembly != compilation.MainAssembly) ||
156
 
                                                !searchedAssemblies.Add (assembly.AssemblyName))
157
 
                                                continue;
158
 
 
159
 
                                        foreach (var type in assembly.GetAllTypeDefinitions ()) {
160
 
                                                // members in base types will also be added
161
 
                                                // because IsDerivedFrom return true for a type itself
162
 
                                                if (!searchedTypes.Add (type.ReflectionName) || !baseTypeImports.Any (baseType => type.IsDerivedFrom (baseType)))
163
 
                                                        continue;
164
 
                                                result.AddRange (GetMembers (type, member.Name, true, memberFilter));
165
 
                                        }
166
 
                                }
167
 
                        }
168
 
                        return result;
169
 
                }
170
 
        
171
 
        }
172
 
}
173
 
 
 
1
// 
 
2
// MemberCollector.cs
 
3
//  
 
4
// Author:
 
5
//       Mansheng Yang <lightyang0@gmail.com>
 
6
// 
 
7
// Copyright (c) 2012 Mansheng Yang
 
8
// 
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
// 
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
// 
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
using System;
 
27
using System.Collections.Generic;
 
28
using System.Linq;
 
29
using MonoDevelop.Projects;
 
30
using MonoDevelop.Ide.TypeSystem;
 
31
using ICSharpCode.NRefactory.TypeSystem;
 
32
 
 
33
namespace MonoDevelop.Ide.FindInFiles
 
34
{
 
35
        public static class MemberCollector
 
36
        {
 
37
 
 
38
                static bool MatchParameters (IMember a, IMember b)
 
39
                {
 
40
                        return MatchParameters (a as IParameterizedMember, b as IParameterizedMember);
 
41
                }
 
42
 
 
43
                static bool MatchParameters (IParameterizedMember a, IParameterizedMember b)
 
44
                {
 
45
                        if (a == null && b == null) return true;
 
46
                        if (a == null || b == null) return false;
 
47
                        return ParameterListComparer.Instance.Equals (a.Parameters, b.Parameters);
 
48
                }
 
49
 
 
50
                /// <summary>
 
51
                /// find all base types(types that are not derived from other types) in the specified types
 
52
                /// </summary>
 
53
                /// <param name="types"></param>
 
54
                /// <returns></returns>
 
55
                public static IEnumerable<ITypeDefinition> GetBaseTypes (IEnumerable<ITypeDefinition> types)
 
56
                {
 
57
                        if (types == null)
 
58
                                yield break;
 
59
                        types = types.ToList ();
 
60
                        if (!types.Any ())
 
61
                                yield break;
 
62
 
 
63
                        var baseType = types.FirstOrDefault ();
 
64
                        var otherTypes = new List<ITypeDefinition> ();
 
65
 
 
66
                        foreach (var type in types.Skip (1)) {
 
67
                                if (baseType.IsDerivedFrom (type)) {
 
68
                                        baseType = type;
 
69
                                } else if (!type.IsDerivedFrom (baseType)) {
 
70
                                        // this type is not directly related to baseType
 
71
                                        otherTypes.Add (type);
 
72
                                }
 
73
                        }
 
74
                        yield return baseType;
 
75
                        foreach (var type in GetBaseTypes (otherTypes))
 
76
                                yield return type;
 
77
                }
 
78
 
 
79
                static IEnumerable<IMember> GetMembers (ITypeDefinition type, IMember member, bool ignoreInherited,
 
80
                                                                                                Func<IMember, bool> filter)
 
81
                {
 
82
                        var options = ignoreInherited ? GetMemberOptions.IgnoreInheritedMembers : GetMemberOptions.None;
 
83
                        var members = type.GetMembers (m => m.Name == member.Name, options);
 
84
 
 
85
/*                      // Filter out shadowed members.
 
86
                        // class A { public string Foo { get; set; } } class B : A { public string Foo { get; set; } }
 
87
                        if (member.EntityType == EntityType.Property || !(member is IParameterizedMember)) {
 
88
                                members = members.Where (m => m == member || m.DeclaringType.Kind == TypeKind.Interface);
 
89
                        }*/
 
90
 
 
91
                        if (filter != null)
 
92
                                members = members.Where (filter);
 
93
                        return members;
 
94
                }
 
95
 
 
96
                static IEnumerable<ITypeDefinition> Import (ICompilation compilation, IEnumerable<ITypeDefinition> types)
 
97
                {
 
98
                        return types.Select (t => compilation.Import (t));
 
99
                }
 
100
 
 
101
                /// <summary>
 
102
                /// collect members with the same signature/name(if overloads are included) as the specified member
 
103
                /// in the inheritance tree
 
104
                /// </summary>
 
105
                public static IEnumerable<IMember> CollectMembers (Solution solution, IMember member, ReferenceFinder.RefactoryScope scope,
 
106
                                                                                                                   bool includeOverloads = true, bool matchDeclaringType = false)
 
107
                {
 
108
                        if (solution == null || member.EntityType == EntityType.Destructor || member.EntityType == EntityType.Operator)
 
109
                                return new [] { member };
 
110
 
 
111
                        if (member.EntityType == EntityType.Constructor) {
 
112
                                if (includeOverloads)
 
113
                                        return member.DeclaringType.GetMembers (m => m.EntityType == EntityType.Constructor, GetMemberOptions.IgnoreInheritedMembers);
 
114
                                return new [] { member };
 
115
                        }
 
116
 
 
117
                        Func<IMember, bool> memberFilter = null;
 
118
                        if (member is IParameterizedMember && !includeOverloads)
 
119
                                memberFilter = m => MatchParameters (m, member);
 
120
 
 
121
                        var declaringType = member.DeclaringTypeDefinition;
 
122
                        if (declaringType == null)
 
123
                                return new [] { member };
 
124
                        // only collect members in declaringType
 
125
                        if (matchDeclaringType)
 
126
                                return GetMembers (declaringType, member, true, memberFilter);
 
127
 
 
128
                        if (declaringType.Kind != TypeKind.Class && declaringType.Kind != TypeKind.Interface)
 
129
                                return GetMembers (declaringType, member, false, memberFilter);
 
130
 
 
131
                        var searchTypes = new List<ITypeDefinition> ();
 
132
                        var interfaces = from t in declaringType.GetAllBaseTypeDefinitions ()
 
133
                                                         where t.Kind == TypeKind.Interface && GetMembers (t, member, true, memberFilter).Any ()
 
134
                                                         select t;
 
135
                        searchTypes.AddRange (GetBaseTypes (interfaces));
 
136
 
 
137
                        if (member.DeclaringType.Kind == TypeKind.Class) {
 
138
                                var members = GetMembers (declaringType, member, false, memberFilter).ToList ();
 
139
                                if (members.Any (m => m.IsOverridable))
 
140
                                        searchTypes.AddRange (GetBaseTypes (members.Select (m => m.DeclaringTypeDefinition)));
 
141
                                else if (searchTypes.Count == 0)
 
142
                                        return members;
 
143
                        }
 
144
 
 
145
                        IList<ICompilation> compilations;
 
146
                        if (scope == ReferenceFinder.RefactoryScope.Solution || scope == ReferenceFinder.RefactoryScope.Unknown) {
 
147
                                var projects = SearchCollector.CollectProjects (solution, searchTypes);
 
148
                                compilations = projects.Select (TypeSystemService.GetCompilation).ToList ();
 
149
                        } else {
 
150
                                compilations = new [] { member.Compilation };
 
151
                        }
 
152
 
 
153
                        var result = new List<IMember> ();
 
154
                        var mainAssemblies = new HashSet<string> (compilations.Select (c => c.MainAssembly.AssemblyName));
 
155
                        var searchedAssemblies = new HashSet<string> ();
 
156
                        var searchedTypes = new HashSet<string> ();
 
157
 
 
158
                        foreach (var compilation in compilations) {
 
159
                                var baseTypeImports = Import(compilation, searchTypes).Where (t => t != null).ToList ();
 
160
                                if (!baseTypeImports.Any ()) continue;
 
161
 
 
162
                                foreach (var assembly in compilation.Assemblies) {
 
163
                                        // search main assemblies in their projects' own compilation, to avoid possible resolving problems
 
164
                                        if ((mainAssemblies.Contains(assembly.AssemblyName) && assembly != compilation.MainAssembly) ||
 
165
                                                !searchedAssemblies.Add (assembly.AssemblyName))
 
166
                                                continue;
 
167
 
 
168
                                        foreach (var type in assembly.GetAllTypeDefinitions ()) {
 
169
                                                // members in base types will also be added
 
170
                                                // because IsDerivedFrom return true for a type itself
 
171
                                                if (!searchedTypes.Add (type.ReflectionName) || !baseTypeImports.Any (type.IsDerivedFrom))
 
172
                                                        continue;
 
173
                                                result.AddRange (GetMembers (type, member, true, memberFilter));
 
174
                                        }
 
175
                                }
 
176
                        }
 
177
                        return result;
 
178
                }
 
179
        
 
180
        }
 
181
}
 
182