5
// Mike KrĆ¼ger <mkrueger@novell.com>
7
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
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:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
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
30
This is a new approach for speeding up find all reference - it does a full text search & then it resolves the found expression.
31
Unfortunately this isn't as exact as the current approach - but this should be used if the resolver is more exact & capable of
35
using System.Collections.Generic;
36
using Mono.TextEditor;
37
using MonoDevelop.Projects.Dom;
38
using MonoDevelop.Core;
39
using MonoDevelop.Projects.Dom.Parser;
40
using MonoDevelop.Ide;
42
namespace MonoDevelop.Refactoring.References
44
public class MemberReference
46
public FilePath FileName {
51
public ITextEditorDataProvider DataProvider {
56
public DocumentLocation Location {
71
public MemberReference (FilePath fileName, ITextEditorDataProvider dataProvider, DocumentLocation location, int offset, int length)
73
this.FileName = fileName;
74
this.DataProvider = dataProvider;
75
this.Location = location;
82
public enum RefactoryScope
90
public static class ReferencesFinder
92
public static IEnumerable<MemberReference> GetReferences (IMember member)
94
IType type = member is IType ? (IType)member : member.DeclaringType;
96
LoggingService.LogError ("Declaring type of '" + member + "' not found.");
99
var matcher = GetReferenceMatcher (member);
100
foreach (var fileInfo in GetFileNames (member)) {
101
var textFile = TextFileProvider.Instance.GetEditableTextFile (fileInfo.FileName);
102
if (textFile.Text == null) // file not found
104
var expressionFinder = ProjectDomService.GetExpressionFinder (fileInfo.FileName);
106
foreach (var match in matcher.Search (textFile.Text)) {
107
var data = (textFile as ITextEditorDataProvider).GetTextEditorData ();
108
ExpressionResult expr = expressionFinder.FindFullExpression (data, match.Offset);
109
if (expr.Expression == null)
112
var resolver = ProjectDomService.GetParser (fileInfo.FileName).CreateResolver (fileInfo.Dom, data, fileInfo.FileName);
113
var location = data.Document.OffsetToLocation (match.Offset);
114
ResolveResult resolveResult = resolver.Resolve (expr, new DomLocation (location.Line, location.Column));
116
// TODO: Add IsReferenceTo in the resolve results - could could be taken from FindMemberAstVisitor
117
if (resolveResult != null && resolveResult.IsReferenceTo (member))
118
yield return new MemberReference (fileInfo.FileName, (textFile as ITextEditorDataProvider), location, match.Position, match.Length);
123
public static IReferenceMatcher GetReferenceMatcher (IMember member)
125
IMethod method = member as IMethod;
126
if (method != null) {
127
if (method.IsConstructor) {
128
return new AggregatedReferenceMatcher (
129
new WholeWordMatcher (member.DeclaringType.Name),
130
new WholeWordMatcher ("this"),
131
new WholeWordMatcher ("base")
134
if (method.IsFinalizer)
135
return new WholeWordMatcher (member.DeclaringType.Name);
138
IProperty property = member as IProperty;
139
if (property != null && property.IsIndexer)
140
return new IndexBeforeReferenceMatcher ("[");
142
return new WholeWordMatcher (member.Name);
148
static RefactoryScope GetScope (IMember member)
150
if (member.DeclaringType != null && member.DeclaringType.ClassType == ClassType.Interface)
151
return GetScope (member.DeclaringType);
154
return RefactoryScope.Solution;
156
if (member.IsProtected || member.IsInternal || member.DeclaringType == null)
157
return RefactoryScope.Project;
158
return RefactoryScope.DeclaringType;
162
public struct ReferenceMatch
164
public readonly int Offset;
165
public readonly int Length;
167
public ReferenceMatch (int offset, int length)
169
this.Offset = offset;
170
this.Length = length;
174
public interface IReferenceMatcher
176
IEnumerable<ReferenceMatch> Search (string inputText);
179
class WholeWordMatcher : IReferenceMatcher
183
public WholeWordMatcher (string pattern)
185
this.pattern = pattern;
188
public IEnumerable<ReferenceMatch> Search (string inputText)
190
if (pattern.Length == 0)
193
while ((pos = inputText.IndexOf (pattern, pos + 1)) >= 0) {
194
if (pos > 0 && char.IsLetterOrDigit (inputText, pos - 1) ||
195
pos < inputText.Length - pattern.Length - 1 && char.IsLetterOrDigit (inputText, pos + pattern.Length))
197
yield return new ReferenceMatch (pos, pattern.Length);
202
class AggregatedReferenceMatcher : IReferenceMatcher
204
IEnumerable<IReferenceMatcher> referenceMatcher;
206
public AggregatedReferenceMatcher (params IReferenceMatcher[] matcher)
208
this.referenceMatcher = matcher;
211
public AggregatedReferenceMatcher (IEnumerable<IReferenceMatcher> matcher)
213
this.referenceMatcher = matcher;
216
public IEnumerable<ReferenceMatch> Search (string inputText)
218
foreach (IReferenceMatcher matcher in referenceMatcher) {
219
foreach (ReferenceMatch match in matcher.Search (inputText)) {
226
class IndexBeforeReferenceMatcher : IReferenceMatcher
230
public IndexBeforeReferenceMatcher (string tag)
235
public IEnumerable<ReferenceMatch> Search (string inputText)
238
while ((pos = inputText.IndexOf (tag, pos + 1)) >= 0) {
239
yield return new ReferenceMatch (pos - 1, tag.Length);
b'\\ No newline at end of file'