Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit d3237ba

Browse files
Merge branch 'master' of github.com:icsharpcode/SharpDevelop
2 parents 8247fde + d8fd301 commit d3237ba

6 files changed

Lines changed: 114 additions & 59 deletions

File tree

src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/CSharpSymbolSearch.cs

Lines changed: 86 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
using System.Threading;
2525
using System.Threading.Tasks;
2626

27+
using ICSharpCode.NRefactory.Analysis;
2728
using CSharpBinding.Parser;
2829
using ICSharpCode.AvalonEdit.Document;
2930
using ICSharpCode.AvalonEdit.Highlighting;
@@ -56,22 +57,44 @@ public class CSharpSymbolSearch : ISymbolSearch
5657
FindReferences fr = new FindReferences();
5758
IList<IFindReferenceSearchScope> searchScopes;
5859
IList<string>[] interestingFileNames;
60+
Dictionary<string, IList<IFindReferenceSearchScope>> searchScopesPerFile;
5961
int workAmount;
6062
double workAmountInverse;
6163

6264
public CSharpSymbolSearch(IProject project, ISymbol entity)
6365
{
6466
this.project = project;
65-
searchScopes = fr.GetSearchScopes(entity);
6667
compilation = SD.ParserService.GetCompilation(project);
68+
var relatedSymbols = GetRelatedSymbols(entity);
69+
if ((relatedSymbols != null) && relatedSymbols.Any()) {
70+
searchScopes = relatedSymbols.SelectMany(e => fr.GetSearchScopes(e)).ToList();
71+
} else {
72+
searchScopes = fr.GetSearchScopes(entity);
73+
}
74+
75+
searchScopesPerFile = new Dictionary<string, IList<IFindReferenceSearchScope>>();
6776
interestingFileNames = new IList<string>[searchScopes.Count];
6877
for (int i = 0; i < searchScopes.Count; i++) {
69-
interestingFileNames[i] = fr.GetInterestingFiles(searchScopes[i], compilation).Select(f => f.FileName).ToList();
70-
workAmount += interestingFileNames[i].Count;
78+
var thisSearchScope = searchScopes[i];
79+
var interestingFiles = fr.GetInterestingFiles(thisSearchScope, compilation).Select(f => f.FileName).ToList();
80+
foreach (var file in interestingFiles) {
81+
if (!searchScopesPerFile.ContainsKey(file))
82+
searchScopesPerFile[file] = new List<IFindReferenceSearchScope>();
83+
searchScopesPerFile[file].Add(thisSearchScope);
84+
}
85+
interestingFileNames[i] = interestingFiles.ToList();
86+
workAmount += interestingFiles.Count;
7187
}
7288
workAmountInverse = 1.0 / workAmount;
7389
}
7490

91+
IEnumerable<ISymbol> GetRelatedSymbols(ISymbol entity)
92+
{
93+
TypeGraph typeGraph = new TypeGraph(new [] { compilation.MainAssembly });
94+
var symbolCollector = new SymbolCollector();
95+
return symbolCollector.GetRelatedSymbols(typeGraph, entity);
96+
}
97+
7598
public double WorkAmount {
7699
get { return workAmount; }
77100
}
@@ -83,38 +106,36 @@ public Task FindReferencesAsync(SymbolSearchArgs args, Action<SearchedFile> call
83106
var cancellationToken = args.ProgressMonitor.CancellationToken;
84107
return Task.Run(
85108
() => {
86-
for (int i = 0; i < searchScopes.Count; i++) {
87-
IFindReferenceSearchScope searchScope = searchScopes[i];
88-
object progressLock = new object();
89-
Parallel.ForEach(
90-
interestingFileNames[i],
91-
new ParallelOptions {
92-
MaxDegreeOfParallelism = Environment.ProcessorCount,
93-
CancellationToken = cancellationToken
94-
},
95-
delegate (string fileName) {
96-
try {
97-
FindReferencesInFile(args, searchScope, FileName.Create(fileName), callback, cancellationToken);
98-
} catch (OperationCanceledException) {
99-
throw;
100-
} catch (Exception ex) {
101-
throw new ApplicationException("Error searching in file '" + fileName + "'", ex);
102-
}
103-
lock (progressLock)
104-
args.ProgressMonitor.Progress += workAmountInverse;
105-
});
106-
}
109+
object progressLock = new object();
110+
Parallel.ForEach(
111+
searchScopesPerFile.Keys,
112+
new ParallelOptions {
113+
MaxDegreeOfParallelism = Environment.ProcessorCount,
114+
CancellationToken = cancellationToken
115+
},
116+
delegate (string fileName) {
117+
try {
118+
FindReferencesInFile(args, searchScopesPerFile[fileName], FileName.Create(fileName), callback, cancellationToken);
119+
} catch (OperationCanceledException) {
120+
throw;
121+
} catch (Exception ex) {
122+
throw new ApplicationException("Error searching in file '" + fileName + "'", ex);
123+
}
124+
lock (progressLock)
125+
args.ProgressMonitor.Progress += workAmountInverse;
126+
});
107127
}, cancellationToken
108128
);
109129
}
110130

111-
void FindReferencesInFile(SymbolSearchArgs args, IFindReferenceSearchScope searchScope, FileName fileName, Action<SearchedFile> callback, CancellationToken cancellationToken)
131+
void FindReferencesInFile(SymbolSearchArgs args, IList<IFindReferenceSearchScope> searchScopeList, FileName fileName, Action<SearchedFile> callback, CancellationToken cancellationToken)
112132
{
113133
ITextSource textSource = args.ParseableFileContentFinder.Create(fileName);
114134
if (textSource == null)
115135
return;
116-
if (searchScope.SearchTerm != null) {
117-
if (textSource.IndexOf(searchScope.SearchTerm, 0, textSource.TextLength, StringComparison.Ordinal) < 0)
136+
if (searchScopeList != null) {
137+
if (!searchScopeList.Any(
138+
scope => (scope.SearchTerm == null) || (textSource.IndexOf(scope.SearchTerm, 0, textSource.TextLength, StringComparison.Ordinal) >= 0)))
118139
return;
119140
}
120141

@@ -134,7 +155,7 @@ void FindReferencesInFile(SymbolSearchArgs args, IFindReferenceSearchScope searc
134155
}
135156

136157
fr.FindReferencesInFile(
137-
searchScope, unresolvedFile, parseInfo.SyntaxTree, compilation,
158+
searchScopeList, unresolvedFile, parseInfo.SyntaxTree, compilation,
138159
delegate (AstNode node, ResolveResult result) {
139160
if (document == null) {
140161
document = new ReadOnlyDocument(textSource, fileName);
@@ -154,8 +175,18 @@ void FindReferencesInFile(SymbolSearchArgs args, IFindReferenceSearchScope searc
154175
if (highlighter != null) {
155176
highlighter.Dispose();
156177
}
157-
if (results.Count > 0)
158-
callback(new SearchedFile(fileName, results));
178+
if (results.Count > 0) {
179+
// Remove overlapping results
180+
List<SearchResultMatch> fixedResults = new List<SearchResultMatch>();
181+
int lastEndOffset = 0;
182+
foreach (var result in results.OrderBy(m => m.StartOffset)) {
183+
if (result.StartOffset >= lastEndOffset) {
184+
fixedResults.Add(result);
185+
lastEndOffset = result.EndOffset;
186+
}
187+
}
188+
callback(new SearchedFile(fileName, fixedResults));
189+
}
159190
}
160191

161192
public Task RenameAsync(SymbolRenameArgs args, Action<PatchedFile> callback, Action<Error> errorCallback)
@@ -166,32 +197,30 @@ public Task RenameAsync(SymbolRenameArgs args, Action<PatchedFile> callback, Act
166197
return Task.Run(
167198
() => {
168199
bool isNameValid = Mono.CSharp.Tokenizer.IsValidIdentifier(args.NewName);
169-
for (int i = 0; i < searchScopes.Count; i++) {
170-
IFindReferenceSearchScope searchScope = searchScopes[i];
171-
object progressLock = new object();
172-
Parallel.ForEach(
173-
interestingFileNames[i],
174-
new ParallelOptions {
175-
MaxDegreeOfParallelism = Environment.ProcessorCount,
176-
CancellationToken = cancellationToken
177-
},
178-
delegate (string fileName) {
179-
RenameReferencesInFile(args, searchScope, FileName.Create(fileName), callback, errorCallback, isNameValid, cancellationToken);
180-
lock (progressLock)
181-
args.ProgressMonitor.Progress += workAmountInverse;
182-
});
183-
}
200+
object progressLock = new object();
201+
Parallel.ForEach(
202+
searchScopesPerFile.Keys,
203+
new ParallelOptions {
204+
MaxDegreeOfParallelism = Environment.ProcessorCount,
205+
CancellationToken = cancellationToken
206+
},
207+
delegate (string fileName) {
208+
RenameReferencesInFile(args, searchScopesPerFile[fileName], FileName.Create(fileName), callback, errorCallback, isNameValid, cancellationToken);
209+
lock (progressLock)
210+
args.ProgressMonitor.Progress += workAmountInverse;
211+
});
184212
}, cancellationToken
185213
);
186214
}
187215

188-
void RenameReferencesInFile(SymbolRenameArgs args, IFindReferenceSearchScope searchScope, FileName fileName, Action<PatchedFile> callback, Action<Error> errorCallback, bool isNameValid, CancellationToken cancellationToken)
216+
void RenameReferencesInFile(SymbolRenameArgs args, IList<IFindReferenceSearchScope> searchScopeList, FileName fileName, Action<PatchedFile> callback, Action<Error> errorCallback, bool isNameValid, CancellationToken cancellationToken)
189217
{
190218
ITextSource textSource = args.ParseableFileContentFinder.Create(fileName);
191219
if (textSource == null)
192220
return;
193-
if (searchScope.SearchTerm != null) {
194-
if (textSource.IndexOf(searchScope.SearchTerm, 0, textSource.TextLength, StringComparison.Ordinal) < 0)
221+
if (searchScopeList != null) {
222+
if (!searchScopeList.Any(
223+
scope => (scope.SearchTerm == null) || (textSource.IndexOf(scope.SearchTerm, 0, textSource.TextLength, StringComparison.Ordinal) >= 0)))
195224
return;
196225
}
197226

@@ -213,7 +242,7 @@ void RenameReferencesInFile(SymbolRenameArgs args, IFindReferenceSearchScope sea
213242
CSharpAstResolver resolver = new CSharpAstResolver(compilation, parseInfo.SyntaxTree, unresolvedFile);
214243

215244
fr.RenameReferencesInFile(
216-
new[] { searchScope }, args.NewName, resolver,
245+
searchScopeList, args.NewName, resolver,
217246
delegate (RenameCallbackArguments callbackArgs) {
218247
var node = callbackArgs.NodeToReplace;
219248
string newCode = callbackArgs.NewNode.ToString();
@@ -249,10 +278,16 @@ void RenameReferencesInFile(SymbolRenameArgs args, IFindReferenceSearchScope sea
249278
}
250279
IDocument changedDocument = new TextDocument(document);
251280
var oldVersion = changedDocument.Version;
281+
List<SearchResultMatch> fixedResults = new List<SearchResultMatch>();
282+
int lastStartOffset = changedDocument.TextLength + 1;
252283
foreach (var result in results.OrderByDescending(m => m.StartOffset)) {
253-
changedDocument.Replace(result.StartOffset, result.Length, result.NewCode);
284+
if (result.EndOffset <= lastStartOffset) {
285+
changedDocument.Replace(result.StartOffset, result.Length, result.NewCode);
286+
fixedResults.Add(result);
287+
lastStartOffset = result.StartOffset;
288+
}
254289
}
255-
callback(new PatchedFile(fileName, results, oldVersion, changedDocument.Version));
290+
callback(new PatchedFile(fileName, fixedResults, oldVersion, changedDocument.Version));
256291
}
257292
}
258293
}

src/AddIns/Debugger/Debugger.Core/Process.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,8 +527,16 @@ public void AsyncTerminate()
527527
System.Threading.Thread.Sleep(0);
528528

529529
// Stop&terminate - both must be called
530-
corProcess.Stop(uint.MaxValue);
531-
corProcess.Terminate(0);
530+
try {
531+
corProcess.Stop(uint.MaxValue);
532+
corProcess.Terminate(0);
533+
} catch (COMException ex) {
534+
if (ex.ErrorCode == unchecked((int)0x80131301)) {
535+
// COMException (0x80131301): Process was terminated.
536+
} else {
537+
throw;
538+
}
539+
}
532540
this.TerminateCommandIssued = true;
533541

534542
// Do not mark the process as exited

src/AddIns/DisplayBindings/IconEditor/PickFormatDialog.Designer.cs

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesPanel.Designer.cs

Lines changed: 7 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesPanel.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,12 @@ public override bool StorePanelContents()
8080
}
8181
return true;
8282
}
83+
84+
void fileTypesListBox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
85+
{
86+
if (fileTypesListBox.IndexFromPoint(e.X, e.Y) == ListBox.NoMatches) {
87+
fileTypesListBox.SelectedIndex = -1;
88+
}
89+
}
8390
}
8491
}

src/Main/Base/Project/Src/Editor/Commands/FindReferencesCommand.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public class RenameSymbolCommand : ResolveResultMenuCommand
5353
public override void Run(ResolveResult symbol)
5454
{
5555
var entity = GetSymbol(symbol);
56+
if ((entity is IMember) && ((entity.SymbolKind == SymbolKind.Constructor) || (entity.SymbolKind == SymbolKind.Destructor))) {
57+
// Don't rename constructors/destructors, rename their declaring type instead
58+
entity = ((IMember) entity).DeclaringType.GetDefinition();
59+
}
5660
if (entity != null) {
5761
var project = GetProjectFromSymbol(entity);
5862
if (project != null) {

0 commit comments

Comments
 (0)