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

« back to all changes in this revision

Viewing changes to src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpReferenceFinder.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:
66
66
                        var firstMember = searchedMembers.FirstOrDefault ();
67
67
                        if (firstMember is INamedElement) {
68
68
                                var namedElement = (INamedElement)firstMember;
69
 
                                memberName = namedElement.Name;
 
69
                                var name = namedElement.Name;
 
70
                                if (namedElement is IMethod && (((IMethod)namedElement).IsConstructor | ((IMethod)namedElement).IsDestructor))
 
71
                                        name = ((IMethod)namedElement).DeclaringType.Name;
 
72
                                memberName = name;
70
73
 
71
74
                                keywordName = CSharpAmbience.NetToCSharpTypeName (namedElement.FullName);
72
75
                                if (keywordName == namedElement.FullName)
78
81
                                memberName = ((IVariable)firstMember).Name;
79
82
                        if (firstMember is ITypeParameter)
80
83
                                memberName = ((ITypeParameter)firstMember).Name;
 
84
                        if (firstMember is INamespace)
 
85
                                memberName = ((INamespace)firstMember).Name;
81
86
                }
82
87
                
83
88
                void SetPossibleFiles (IEnumerable<FilePath> files)
92
97
                        }
93
98
                }
94
99
                
95
 
                MemberReference GetReference (ResolveResult result, AstNode node, string fileName, Mono.TextEditor.TextEditorData editor)
 
100
                MemberReference GetReference (Project project, ResolveResult result, AstNode node, SyntaxTree syntaxTree, string fileName, Mono.TextEditor.TextEditorData editor)
96
101
                {
 
102
                        AstNode originalNode = node;
97
103
                        if (result == null) {
98
104
                                return null;
99
105
                        }
107
113
                                valid = searchedMembers.FirstOrDefault (
108
114
                                        member => member is IMember && ((IMember)member).Region == foundMember.Region);
109
115
                        } else if (result is NamespaceResolveResult) {
110
 
                                var ns = ((NamespaceResolveResult)result).NamespaceName;
111
 
                                valid = searchedMembers.FirstOrDefault (n => n is string && n.ToString () == ns);
 
116
                                var ns = ((NamespaceResolveResult)result).Namespace;
 
117
                                valid = searchedMembers.FirstOrDefault (n => n is INamespace && ns.FullName.StartsWith (((INamespace)n).FullName, StringComparison.Ordinal));
112
118
                        } else if (result is LocalResolveResult) {
113
119
                                var ns = ((LocalResolveResult)result).Variable;
114
120
                                valid = searchedMembers.FirstOrDefault (n => n is IVariable && ((IVariable)n).Region == ns.Region);
117
123
                        } else {
118
124
                                valid = searchedMembers.FirstOrDefault ();
119
125
                        }
 
126
 
120
127
                        if (node is ConstructorInitializer)
121
128
                                return null;
122
 
 
123
129
                        if (node is ObjectCreateExpression)
124
130
                                node = ((ObjectCreateExpression)node).Type;
125
131
 
129
135
                        if (node is MemberReferenceExpression)
130
136
                                node = ((MemberReferenceExpression)node).MemberNameToken;
131
137
                        
 
138
                        if (node is SimpleType)
 
139
                                node = ((SimpleType)node).IdentifierToken;
 
140
 
132
141
                        if (node is MemberType)
133
142
                                node = ((MemberType)node).MemberNameToken;
134
143
                        
 
144
                        if (node is NamespaceDeclaration) {
 
145
                                var nsd = ((NamespaceDeclaration)node);
 
146
                                node = nsd.Identifiers.LastOrDefault (n => n.Name == memberName) ?? nsd.Identifiers.FirstOrDefault ();
 
147
                                if (node == null)
 
148
                                        return null;
 
149
                        }
 
150
 
135
151
                        if (node is TypeDeclaration && (searchedMembers.First () is IType)) 
136
152
                                node = ((TypeDeclaration)node).NameToken;
137
 
                        
 
153
                        if (node is DelegateDeclaration) 
 
154
                                node = ((DelegateDeclaration)node).NameToken;
 
155
 
138
156
                        if (node is EntityDeclaration && (searchedMembers.First () is IMember)) 
139
157
                                node = ((EntityDeclaration)node).NameToken;
140
158
                        
155
173
                                node = ((IdentifierExpression)node).IdentifierToken;
156
174
                        }
157
175
 
158
 
                        var region = new DomRegion (fileName, node.StartLocation, node.EndLocation);
 
176
                        var region = new DomRegion (fileName, node.StartLocation, node.EndLocation);
159
177
 
160
178
                        var length = node is PrimitiveType ? keywordName.Length : node.EndLocation.Column - node.StartLocation.Column;
161
 
                        return new MemberReference (valid, region, editor.LocationToOffset (region.Begin), length);
 
179
                        return new CSharpMemberReference (project, originalNode, syntaxTree, valid, region, editor.LocationToOffset (region.Begin), length);
 
180
                }
 
181
 
 
182
                public class CSharpMemberReference : MemberReference
 
183
                {
 
184
                        public SyntaxTree SyntaxTree {
 
185
                                get;
 
186
                                private set;
 
187
                        }
 
188
 
 
189
                        public AstNode AstNode {
 
190
                                get;
 
191
                                private set;
 
192
                        }
 
193
 
 
194
                        public Project Project {
 
195
                                get;
 
196
                                private set;
 
197
                        }
 
198
 
 
199
                        public CSharpMemberReference (Project project, AstNode astNode, SyntaxTree syntaxTree,  object entity, DomRegion region, int offset, int length) : base (entity, region, offset, length)
 
200
                        {
 
201
                                this.Project = project;
 
202
                                this.AstNode = astNode;
 
203
                                this.SyntaxTree = syntaxTree;
 
204
                        }
162
205
                }
163
206
 
164
207
                bool IsNodeValid (object searchedMember, AstNode node)
176
219
                        var parsedDocument = doc.ParsedDocument;
177
220
                        if (parsedDocument == null)
178
221
                                return Enumerable.Empty<MemberReference> ();
179
 
                        var unit = parsedDocument.GetAst<CompilationUnit> ();
180
 
                        var file = parsedDocument.ParsedFile as CSharpParsedFile;
 
222
                        var unit = parsedDocument.GetAst<SyntaxTree> ();
 
223
                        var file = parsedDocument.ParsedFile as CSharpUnresolvedFile;
181
224
                        var result = new List<MemberReference> ();
182
225
                        
183
226
                        foreach (var obj in searchedMembers) {
184
227
                                if (obj is IEntity) {
185
 
                                        refFinder.FindReferencesInFile (refFinder.GetSearchScopes ((IEntity)obj), file, unit, doc.Compilation, (astNode, r) => {
 
228
                                        var entity = (IEntity)obj;
 
229
 
 
230
                                        // May happen for anonymous types since empty constructors are always generated.
 
231
                                        // But there is no declaring type definition for them - we filter out this case.
 
232
                                        if (entity.EntityType == EntityType.Constructor && entity.DeclaringTypeDefinition == null)
 
233
                                                continue;
 
234
 
 
235
                                        refFinder.FindReferencesInFile (refFinder.GetSearchScopes (entity), file, unit, doc.Compilation, (astNode, r) => {
186
236
                                                if (IsNodeValid (obj, astNode))
187
 
                                                        result.Add (GetReference (r, astNode, editor.FileName, editor)); 
 
237
                                                        result.Add (GetReference (doc.Project, r, astNode, unit, editor.FileName, editor)); 
188
238
                                        }, CancellationToken.None);
189
239
                                } else if (obj is IVariable) {
190
240
                                        refFinder.FindLocalReferences ((IVariable)obj, file, unit, doc.Compilation, (astNode, r) => { 
191
241
                                                if (IsNodeValid (obj, astNode))
192
 
                                                        result.Add (GetReference (r, astNode, editor.FileName, editor));
 
242
                                                        result.Add (GetReference (doc.Project, r, astNode, unit, editor.FileName, editor));
193
243
                                        }, CancellationToken.None);
194
244
                                } else if (obj is ITypeParameter) {
195
245
                                        refFinder.FindTypeParameterReferences ((ITypeParameter)obj, file, unit, doc.Compilation, (astNode, r) => { 
196
246
                                                if (IsNodeValid (obj, astNode))
197
 
                                                        result.Add (GetReference (r, astNode, editor.FileName, editor));
198
 
                                        }, CancellationToken.None);
199
 
                                }
 
247
                                                        result.Add (GetReference (doc.Project, r, astNode, unit, editor.FileName, editor));
 
248
                                        }, CancellationToken.None);
 
249
                                } else if (obj is INamespace) {
 
250
                                        var entity = (INamespace)obj;
 
251
                                        refFinder.FindReferencesInFile (refFinder.GetSearchScopes (entity), file, unit, doc.Compilation, (astNode, r) => {
 
252
                                                if (IsNodeValid (obj, astNode))
 
253
                                                        result.Add (GetReference (doc.Project, r, astNode, unit, editor.FileName, editor)); 
 
254
                                        }, CancellationToken.None);
 
255
                                } 
200
256
                        }
201
257
                        return result;
202
258
                }
203
259
                
204
 
                public override IEnumerable<MemberReference> FindReferences (Project project, IProjectContent content, IEnumerable<FilePath> possibleFiles, IEnumerable<object> members)
 
260
                public override IEnumerable<MemberReference> FindReferences (Project project, IProjectContent content, IEnumerable<FilePath> possibleFiles, IProgressMonitor monitor, IEnumerable<object> members)
205
261
                {
206
 
                        if (project == null)
207
 
                                throw new ArgumentNullException ("project", "Project not set.");
208
262
                        if (content == null)
209
263
                                throw new ArgumentNullException ("content", "Project content not set.");
210
264
                        SetPossibleFiles (possibleFiles);
211
265
                        SetSearchedMembers (members);
212
 
                        
213
 
                        var scopes = searchedMembers.Select (e => refFinder.GetSearchScopes (e as IEntity));
214
 
                        var compilation = TypeSystemService.GetCompilation (project);
 
266
 
 
267
                        var scopes = searchedMembers.Select (e => e is IEntity ? refFinder.GetSearchScopes ((IEntity)e) : refFinder.GetSearchScopes ((INamespace)e));
 
268
                        var compilation = project != null ? TypeSystemService.GetCompilation (project) : content.CreateCompilation ();
215
269
                        List<MemberReference> refs = new List<MemberReference> ();
216
270
                        foreach (var opendoc in openDocuments) {
217
271
                                foreach (var newRef in FindInDocument (opendoc.Item2)) {
220
274
                                        refs.Add (newRef);
221
275
                                }
222
276
                        }
223
 
                        
224
277
                        foreach (var file in files) {
 
278
                                if (monitor != null)
 
279
                                        monitor.Step (1);
225
280
                                string text = Mono.TextEditor.Utils.TextFileUtility.ReadAllText (file);
226
281
                                if (memberName != null && text.IndexOf (memberName, StringComparison.Ordinal) < 0 &&
227
282
                                        (keywordName == null || text.IndexOf (keywordName, StringComparison.Ordinal) < 0))
233
288
                                                continue;
234
289
                                        
235
290
                                        var storedFile = content.GetFile (file);
236
 
                                        var parsedFile = storedFile as CSharpParsedFile;
 
291
                                        var parsedFile = storedFile as CSharpUnresolvedFile;
237
292
                                        
238
293
                                        if (parsedFile == null && storedFile is ParsedDocumentDecorator) {
239
 
                                                parsedFile = ((ParsedDocumentDecorator)storedFile).ParsedFile as CSharpParsedFile;
 
294
                                                parsedFile = ((ParsedDocumentDecorator)storedFile).ParsedFile as CSharpUnresolvedFile;
240
295
                                        }
241
296
                                        
242
297
                                        if (parsedFile == null) {
243
298
                                                // for fallback purposes - should never happen.
244
299
                                                parsedFile = unit.ToTypeSystem ();
245
 
                                                content = content.UpdateProjectContent (content.GetFile (file), parsedFile);
 
300
                                                content = content.AddOrUpdateFiles (parsedFile);
246
301
                                                compilation = content.CreateCompilation ();
247
302
                                        }
248
303
                                        foreach (var scope in scopes) {
252
307
                                                        unit,
253
308
                                                        compilation,
254
309
                                                        (astNode, result) => {
255
 
                                                                var newRef = GetReference (result, astNode, file, editor);
 
310
                                                                var newRef = GetReference (project, result, astNode, unit, file, editor);
256
311
                                                                if (newRef == null || refs.Any (r => r.FileName == newRef.FileName && r.Region == newRef.Region))
257
312
                                                                        return;
258
313
                                                                refs.Add (newRef);