Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
authorMike Krüger <mkrueger@novell.com>2011-02-09 13:10:01 +0300
committerMike Krüger <mkrueger@novell.com>2011-02-09 13:13:07 +0300
commit9de9e7553a988d6ef4d5caf3b81c2d7a9edf4ab8 (patch)
tree3bd96ec4dd8e67d08e1649c07d2f2579707e28b6 /main/src
parent0e820cfb369f1de7a2c9bc149c16c135327307e0 (diff)
Overworked find all references model. It's now per file (=mime type)
instead of per project. Change was required for supporting references in files that are part of the project but are embedded in another language - see 'Bug 663095 - Find References does not find method references in ASPX'.
Diffstat (limited to 'main/src')
-rw-r--r--main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml7
-rw-r--r--main/src/core/MonoDevelop.Ide/Makefile.am1
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/DefaultCodeFormatter.cs2
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs230
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj1
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs13
6 files changed, 252 insertions, 2 deletions
diff --git a/main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml b/main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml
index 6c463a6594..67e203a66b 100644
--- a/main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml
+++ b/main/src/core/MonoDevelop.Ide/ExtensionModel/MonoDevelop.Ide.addin.xml
@@ -139,7 +139,12 @@
<ExtensionNode name="Formatter" type="MonoDevelop.Ide.CodeFormatting.CodeFormatterExtensionNode" />
</ExtensionPoint>
- <!-- Extensions -->
+ <ExtensionPoint path = "/MonoDevelop/Ide/ReferenceFinder" name = "Reference finders">
+ <Description>Reference finder.</Description>
+ <ExtensionNode name="ReferenceFinder" type="MonoDevelop.Ide.FindInFiles.ReferenceFinderCodon"/>
+ </ExtensionPoint>
+
+ <!-- Extensions -->
<Extension path = "/MonoDevelop/Core/Applications">
<Application id = "gsetup"
diff --git a/main/src/core/MonoDevelop.Ide/Makefile.am b/main/src/core/MonoDevelop.Ide/Makefile.am
index 0c782e037a..508f76f6fb 100644
--- a/main/src/core/MonoDevelop.Ide/Makefile.am
+++ b/main/src/core/MonoDevelop.Ide/Makefile.am
@@ -377,6 +377,7 @@ FILES = \
MonoDevelop.Ide.FindInFiles/FindInFilesDialog.cs \
MonoDevelop.Ide.FindInFiles/FindReplace.cs \
MonoDevelop.Ide.FindInFiles/ISearchProgressMonitor.cs \
+ MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs \
MonoDevelop.Ide.FindInFiles/Scope.cs \
MonoDevelop.Ide.FindInFiles/SearchProgressMonitor.cs \
MonoDevelop.Ide.FindInFiles/SearchResult.cs \
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/DefaultCodeFormatter.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/DefaultCodeFormatter.cs
index 0f89c56c1c..151a9e1072 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/DefaultCodeFormatter.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/DefaultCodeFormatter.cs
@@ -53,7 +53,7 @@ namespace MonoDevelop.Ide.CodeFormatting
string eolMarker = currentPolicy.GetEolMarker ();
var result = new StringBuilder ();
- for (int i = startOffset; i <= endOffset; i++) {
+ for (int i = startOffset; i <= endOffset && i < input.Length; i++) {
char ch = input[i];
switch (ch) {
case '\t':
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs
new file mode 100644
index 0000000000..f0a9c56dbc
--- /dev/null
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/ReferencesFinder.cs
@@ -0,0 +1,230 @@
+//
+// ReferenceFinder.cs
+//
+// Author:
+// Mike Krüger <mkrueger@novell.com>
+//
+// Copyright (c) 2011 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using MonoDevelop.Projects.Dom;
+using System.Collections.Generic;
+using System.Linq;
+using Mono.Addins;
+using MonoDevelop.Core;
+using MonoDevelop.Projects.Dom.Parser;
+using MonoDevelop.Projects.CodeGeneration;
+using MonoDevelop.Projects;
+
+namespace MonoDevelop.Ide.FindInFiles
+{
+ public abstract class ReferenceFinder
+ {
+ public bool IncludeDocumentation {
+ get;
+ set;
+ }
+
+ static List<ReferenceFinderCodon> referenceFinderCodons = new List<ReferenceFinderCodon> ();
+
+ static ReferenceFinder ()
+ {
+ AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/ReferenceFinder", delegate(object sender, ExtensionNodeEventArgs args) {
+ var codon = (ReferenceFinderCodon)args.ExtensionNode;
+ switch (args.Change) {
+ case ExtensionChange.Add:
+ referenceFinderCodons.Add (codon);
+ break;
+ case ExtensionChange.Remove:
+ referenceFinderCodons.Remove (codon);
+ break;
+ }
+ });
+ }
+
+ public static ReferenceFinder GetReferenceFinder (string mimeType)
+ {
+ var codon = referenceFinderCodons.FirstOrDefault (c => c.SupportedMimeTypes.Any (mt => mt == mimeType));
+ return codon != null ? codon.ReferenceFinder : null;
+ }
+
+ public abstract IEnumerable<MemberReference> FindReferences (ProjectDom dom, FilePath fileName, INode member);
+
+
+ public static IEnumerable<MemberReference> FindReferences (INode member)
+ {
+ return FindReferences (IdeApp.ProjectOperations.CurrentSelectedSolution, member);
+ }
+
+ public static IEnumerable<MemberReference> FindReferences (Solution solution, INode member)
+ {
+ var scope = GetScope (member);
+ ReferenceFinder finder;
+ ProjectDom dom = null;
+ ICompilationUnit unit = null;
+ IEnumerable<INode> searchNodes = new INode[] { member };
+ if (member is LocalVariable) {
+ dom = ((LocalVariable)member).DeclaringMember.DeclaringType.SourceProjectDom;
+ unit = ((LocalVariable)member).CompilationUnit;
+ } else if (member is IParameter) {
+ dom = ((IParameter)member).DeclaringMember.DeclaringType.SourceProjectDom;
+ unit = ((IParameter)member).DeclaringMember.DeclaringType.CompilationUnit;
+ } else if (member is IType) {
+ dom = ((IType)member).SourceProjectDom;
+ unit = ((IType)member).CompilationUnit;
+ } else if (member is IMember) {
+ dom = ((IMember)member).DeclaringType.SourceProjectDom;
+ unit = ((IMember)member).DeclaringType.CompilationUnit;
+ searchNodes = CollectMembers (dom, (IMember)member);
+ }
+
+ switch (scope) {
+ case RefactoryScope.File:
+ case RefactoryScope.DeclaringType:
+ if (dom == null || unit == null)
+ yield break;
+ finder = GetReferenceFinder (DesktopService.GetMimeTypeForUri (unit.FileName));
+ if (finder == null)
+ yield break;
+ foreach (var searchNode in searchNodes) {
+ foreach (var foundReference in finder.FindReferences (dom, unit.FileName, searchNode)) {
+ yield return foundReference;
+ }
+ }
+ break;
+ case RefactoryScope.Project:
+ if (dom == null)
+ yield break;
+ foreach (var file in dom.Project.Files) {
+ finder = GetReferenceFinder (DesktopService.GetMimeTypeForUri (file.FilePath));
+ if (finder == null)
+ continue;
+ foreach (var searchNode in searchNodes) {
+ foreach (var foundReference in finder.FindReferences (dom, file.FilePath, searchNode)) {
+ yield return foundReference;
+ }
+ }
+ }
+ break;
+
+ case RefactoryScope.Solution:
+ foreach (var project in solution.GetAllProjects ()) {
+ var currentDom = ProjectDomService.GetProjectDom (project);
+ foreach (var file in project.Files) {
+ finder = GetReferenceFinder (DesktopService.GetMimeTypeForUri (file.FilePath));
+ if (finder == null)
+ continue;
+ foreach (var searchNode in searchNodes) {
+ foreach (var foundReference in finder.FindReferences (currentDom, file.FilePath, searchNode)) {
+ yield return foundReference;
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ internal static IEnumerable<INode> CollectMembers (ProjectDom dom, IMember member)
+ {
+ if (member is IMethod && ((IMethod)member).IsConstructor) {
+ yield return member;
+ } else {
+ bool isOverrideable = member.DeclaringType.ClassType == ClassType.Interface || member.IsOverride || member.IsVirtual || member.IsAbstract;
+ bool isLastMember = false;
+ // for members we need to collect the whole 'class' of members (overloads & implementing types)
+ HashSet<string> alreadyVisitedTypes = new HashSet<string> ();
+ foreach (IType type in dom.GetInheritanceTree (member.DeclaringType)) {
+ if (type.ClassType == ClassType.Interface || isOverrideable || type.DecoratedFullName == member.DeclaringType.DecoratedFullName) {
+ // search in the class for the member
+ foreach (IMember interfaceMember in type.SearchMember (member.Name, true)) {
+ if (interfaceMember.MemberType == member.MemberType)
+ yield return interfaceMember;
+ }
+
+ // now search in all subclasses of this class for the member
+ isLastMember = !member.IsOverride;
+ foreach (IType implementingType in dom.GetSubclasses (type)) {
+ string name = implementingType.DecoratedFullName;
+ if (alreadyVisitedTypes.Contains (name))
+ continue;
+ alreadyVisitedTypes.Add (name);
+ foreach (IMember typeMember in implementingType.SearchMember (member.Name, true)) {
+ if (typeMember.MemberType == member.MemberType) {
+ isLastMember = type.ClassType != ClassType.Interface && (typeMember.IsVirtual || typeMember.IsAbstract || !typeMember.IsOverride);
+ yield return typeMember;
+ }
+ }
+ if (!isOverrideable)
+ break;
+ }
+ if (isLastMember)
+ break;
+ }
+ }
+ }
+ }
+
+ static RefactoryScope GetScope (INode node)
+ {
+ IMember member = node as IMember;
+ if (member == null)
+ return RefactoryScope.DeclaringType;
+
+ if (member.DeclaringType != null && member.DeclaringType.ClassType == ClassType.Interface)
+ return GetScope (member.DeclaringType);
+
+ if (member.IsPublic)
+ return RefactoryScope.Solution;
+
+ if (member.IsProtected || member.IsInternal || member.DeclaringType == null)
+ return RefactoryScope.Project;
+ return RefactoryScope.DeclaringType;
+ }
+ }
+
+ [ExtensionNode (Description="A reference finder. The specified class needs to inherit from MonoDevelop.Projects.CodeGeneration.ReferenceFinder")]
+ internal class ReferenceFinderCodon : TypeExtensionNode
+ {
+ [NodeAttribute("supportedmimetypes", "Mime types supported by this binding (to be shown in the Open File dialog)")]
+ string[] supportedMimetypes;
+
+ public string[] SupportedMimeTypes {
+ get {
+ return supportedMimetypes;
+ }
+ set {
+ supportedMimetypes = value;
+ }
+ }
+
+ public ReferenceFinder ReferenceFinder {
+ get {
+ return (ReferenceFinder)GetInstance ();
+ }
+ }
+
+ public override string ToString ()
+ {
+ return string.Format ("[ReferenceFinderCodon: SupportedMimeTypes={0}, ReferenceFinder={1}]", SupportedMimeTypes.Count () + ":" + String.Join (";", SupportedMimeTypes), ReferenceFinder);
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
index 9d06e65ef6..b02fe951ad 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.csproj
@@ -1419,6 +1419,7 @@
<Compile Include="gtk-gui\MonoDevelop.Ide.Projects.NewPolicySetDialog.cs" />
<Compile Include="MonoDevelop.Components\HeaderBox.cs" />
<Compile Include="MonoDevelop.Ide.Extensions\StartupHandlerExtensionAttribute.cs" />
+ <Compile Include="MonoDevelop.Ide.FindInFiles\ReferencesFinder.cs" />
</ItemGroup>
<ItemGroup>
<None Include="ChangeLog" />
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
index df5113e000..b8ee4e93d4 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs
@@ -1810,5 +1810,18 @@ namespace MonoDevelop.Ide
return new ProviderProxy (data);
}
+ public TextEditorData GetTextEditorData (FilePath filePath)
+ {
+ foreach (var doc in IdeApp.Workbench.Documents) {
+ if (doc.FileName == filePath) {
+ return doc.Editor;
+ }
+ }
+
+ TextEditorData data = new TextEditorData ();
+ data.Document.FileName = filePath;
+ data.Text = File.ReadAllText (filePath);
+ return data;
+ }
}
}