Skip to content
This repository
Browse code

implement XamlSymbolSearch

  • Loading branch information...
commit bd32925e074b926986bf47706c9ef73a2e905d3e 1 parent a45a631
Siegfried Pammer siegfriedpammer authored
4 src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs
@@ -186,9 +186,7 @@ public override ItemType GetDefaultItemType(string fileName)
186 186
187 187 public override ISymbolSearch PrepareSymbolSearch(IEntity entity)
188 188 {
189   - // TODO implement CompositeSymbolSearch to allow multiple instances to be returned, e.g., XamlSymbolSearch, etc.
190   - // return CompositeSymbolSearch.Create(new XamlSymbolSearch(...), base.PrepareSymbolSearch(...))
191   - return new CSharpSymbolSearch(Project, entity);
  189 + return CompositeSymbolSearch.Create(new CSharpSymbolSearch(Project, entity), base.PrepareSymbolSearch(entity));
192 190 }
193 191 }
194 192 }
2  src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBehavior.cs
@@ -32,7 +32,7 @@ public override ItemType GetDefaultItemType(string fileName)
32 32
33 33 public override ISymbolSearch PrepareSymbolSearch(IEntity entity)
34 34 {
35   - return new XamlSymbolSearch(entity);
  35 + return CompositeSymbolSearch.Create(new XamlSymbolSearch(Project, entity), base.PrepareSymbolSearch(entity));
36 36 }
37 37 }
38 38
5 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlBinding.csproj
@@ -13,9 +13,8 @@
13 13 <WarningLevel>4</WarningLevel>
14 14 <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
15 15 <SourceAnalysisOverrideSettingsFile>C:\Users\Daniel\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
16   - <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
17   - <TargetFrameworkProfile>
18   - </TargetFrameworkProfile>
  16 + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
  17 + <TargetFrameworkProfile>Client</TargetFrameworkProfile>
19 18 </PropertyGroup>
20 19 <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
21 20 <DebugSymbols>true</DebugSymbols>
90 src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlSymbolSearch.cs
@@ -2,9 +2,20 @@
2 2 // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
3 3
4 4 using System;
  5 +using System.Collections.Generic;
  6 +using System.IO;
  7 +using System.Linq;
  8 +using System.Threading;
5 9 using System.Threading.Tasks;
  10 +using ICSharpCode.AvalonEdit.Highlighting;
  11 +using ICSharpCode.Core;
  12 +using ICSharpCode.NRefactory.CSharp.Resolver;
  13 +using ICSharpCode.NRefactory.Editor;
  14 +using ICSharpCode.NRefactory.Semantics;
6 15 using ICSharpCode.NRefactory.TypeSystem;
7 16 using ICSharpCode.SharpDevelop.Editor.Search;
  17 +using ICSharpCode.SharpDevelop.Parser;
  18 +using ICSharpCode.SharpDevelop.Project;
8 19 using ICSharpCode.SharpDevelop.Refactoring;
9 20
10 21 namespace ICSharpCode.XamlBinding
@@ -14,19 +25,88 @@ namespace ICSharpCode.XamlBinding
14 25 /// </summary>
15 26 public class XamlSymbolSearch : ISymbolSearch
16 27 {
17   - public XamlSymbolSearch(IEntity entity)
  28 + IProject project;
  29 + ICompilation compilation;
  30 + IEntity entity;
  31 + List<FileName> interestingFileNames;
  32 + int workAmount;
  33 + double workAmountInverse;
  34 +
  35 + public XamlSymbolSearch(IProject project, IEntity entity)
18 36 {
  37 + this.entity = entity;
  38 + compilation = ParserService.GetCompilation(project);
  39 + interestingFileNames = new List<FileName>();
  40 + foreach (var item in project.ParentSolution.SolutionFolderContainers.Select(f => f.SolutionItems).SelectMany(si => si.Items).Where(i => ".xaml".Equals(Path.GetExtension(i.Location), StringComparison.OrdinalIgnoreCase)))
  41 + interestingFileNames.Add(new FileName(Path.Combine(project.ParentSolution.Directory, item.Location)));
  42 + foreach (var item in project.ParentSolution.Projects.SelectMany(p => p.Items).OfType<FileProjectItem>().Where(i => ".xaml".Equals(Path.GetExtension(i.FileName), StringComparison.OrdinalIgnoreCase)))
  43 + interestingFileNames.Add(new FileName(item.FileName));
  44 + workAmount = interestingFileNames.Count;
  45 + workAmountInverse = 1.0 / workAmount;
19 46 }
20 47
21 48 public double WorkAmount {
22   - get {
23   - throw new NotImplementedException();
24   - }
  49 + get { return workAmount; }
25 50 }
26 51
27 52 public Task FindReferencesAsync(SymbolSearchArgs searchArguments, Action<SearchedFile> callback)
28 53 {
29   - throw new NotImplementedException();
  54 + if (callback == null)
  55 + throw new ArgumentNullException("callback");
  56 + var cancellationToken = searchArguments.ProgressMonitor.CancellationToken;
  57 + return Task.Run(
  58 + () => {
  59 + object progressLock = new object();
  60 + Parallel.ForEach(
  61 + interestingFileNames,
  62 + new ParallelOptions {
  63 + MaxDegreeOfParallelism = Environment.ProcessorCount,
  64 + CancellationToken = cancellationToken
  65 + },
  66 + delegate (FileName fileName) {
  67 + FindReferencesInFile(searchArguments, entity, fileName, callback, cancellationToken);
  68 + lock (progressLock)
  69 + searchArguments.ProgressMonitor.Progress += workAmountInverse;
  70 + });
  71 + }, cancellationToken
  72 + );
  73 + }
  74 +
  75 + void FindReferencesInFile(SymbolSearchArgs searchArguments, IEntity entity, FileName fileName, Action<SearchedFile> callback, CancellationToken cancellationToken)
  76 + {
  77 + ITextSource textSource = searchArguments.ParseableFileContentFinder.Create(fileName);
  78 + if (textSource == null)
  79 + return;
  80 + int offset = textSource.IndexOf(entity.Name, 0, textSource.TextLength, StringComparison.Ordinal);
  81 + if (offset < 0)
  82 + return;
  83 +
  84 + var parseInfo = ParserService.Parse(fileName, textSource) as XamlFullParseInformation;
  85 + if (parseInfo == null)
  86 + return;
  87 + ReadOnlyDocument document = null;
  88 + DocumentHighlighter highlighter = null;
  89 + List<Reference> results = new List<Reference>();
  90 + XamlResolver resolver = new XamlResolver();
  91 + do {
  92 + if (document == null) {
  93 + document = new ReadOnlyDocument(textSource);
  94 + var highlighting = HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(fileName));
  95 + if (highlighting != null)
  96 + highlighter = new DocumentHighlighter(document, highlighting.MainRuleSet);
  97 + else
  98 + highlighter = null;
  99 + }
  100 + var result = resolver.Resolve(parseInfo, document.GetLocation(offset + entity.Name.Length / 2 + 1), compilation, cancellationToken);
  101 + int length = entity.Name.Length;
  102 + if ((result is TypeResolveResult && ((TypeResolveResult)result).Type.Equals(entity)) || (result is MemberResolveResult && ((MemberResolveResult)result).Member.Equals(entity))) {
  103 + var region = new DomRegion(fileName, document.GetLocation(offset), document.GetLocation(offset + length));
  104 + var builder = SearchResultsPad.CreateInlineBuilder(region.Begin, region.End, document, highlighter);
  105 + results.Add(new Reference(region, result, offset, length, builder));
  106 + }
  107 + offset = textSource.IndexOf(entity.Name, offset + length, textSource.TextLength - offset - length, StringComparison.OrdinalIgnoreCase);
  108 + } while (offset > 0);
  109 + callback(new SearchedFile(fileName, results));
30 110 }
31 111 }
32 112 }
4 src/AddIns/Misc/SearchAndReplace/Project/Gui/ObserverSearchResult.cs
@@ -68,13 +68,15 @@ void IObserver<SearchedFile>.OnNext(SearchedFile value)
68 68
69 69 void IObserver<SearchedFile>.OnError(Exception error)
70 70 {
  71 + if (error == null)
  72 + throw new ArgumentNullException("error");
71 73 // flatten AggregateException and
72 74 // filter OperationCanceledException
73 75 try {
74 76 if (error is AggregateException)
75 77 ((AggregateException)error).Flatten().Handle(ex => ex is OperationCanceledException);
76 78 else if (!(error is OperationCanceledException))
77   - throw error;
  79 + MessageService.ShowException(error);
78 80 } catch (Exception ex) {
79 81 MessageService.ShowException(ex);
80 82 }
28 src/Main/Base/Project/Src/Services/RefactoringService/FindReferenceService.cs
@@ -232,4 +232,32 @@ public interface ISymbolSearch
232 232
233 233 Task FindReferencesAsync(SymbolSearchArgs searchArguments, Action<SearchedFile> callback);
234 234 }
  235 +
  236 + public sealed class CompositeSymbolSearch : ISymbolSearch
  237 + {
  238 + IEnumerable<ISymbolSearch> symbolSearches;
  239 +
  240 + CompositeSymbolSearch(params ISymbolSearch[] symbolSearches)
  241 + {
  242 + this.symbolSearches = symbolSearches;
  243 + }
  244 +
  245 + public static ISymbolSearch Create(ISymbolSearch symbolSearch1, ISymbolSearch symbolSearch2)
  246 + {
  247 + if (symbolSearch1 == null)
  248 + return symbolSearch2;
  249 + if (symbolSearch2 == null)
  250 + return symbolSearch1;
  251 + return new CompositeSymbolSearch(symbolSearch1, symbolSearch2);
  252 + }
  253 +
  254 + public double WorkAmount {
  255 + get { return symbolSearches.Sum(s => s.WorkAmount); }
  256 + }
  257 +
  258 + public Task FindReferencesAsync(SymbolSearchArgs searchArguments, Action<SearchedFile> callback)
  259 + {
  260 + return Task.WhenAll(symbolSearches.Select(s => s.FindReferencesAsync(searchArguments, callback)));
  261 + }
  262 + }
235 263 }

0 comments on commit bd32925

Please sign in to comment.
Something went wrong with that request. Please try again.