diff --git a/src/Main/Base/Project/Src/Project/Items/ItemType.cs b/src/Main/Base/Project/Src/Project/Items/ItemType.cs
index d55a31f781..1a7f658d52 100644
--- a/src/Main/Base/Project/Src/Project/Items/ItemType.cs
+++ b/src/Main/Base/Project/Src/Project/Items/ItemType.cs
@@ -56,6 +56,11 @@ namespace ICSharpCode.SharpDevelop.Project
public static readonly ItemType Folder = new ItemType("Folder");
public static readonly ItemType WebReferences = new ItemType("WebReferences");
+ ///
+ /// Gets a collection of item types that are known not to be used for files.
+ ///
+ public static readonly ReadOnlyCollectionWrapper NonFileItemTypes
+ = new ReadOnlyCollectionWrapper(new List(ReferenceItemTypes) { Folder, WebReferences, Import });
readonly string itemName;
diff --git a/src/Main/Base/Project/Src/Services/File/FileService.cs b/src/Main/Base/Project/Src/Services/File/FileService.cs
index b427276267..8a55dc6ddd 100644
--- a/src/Main/Base/Project/Src/Services/File/FileService.cs
+++ b/src/Main/Base/Project/Src/Services/File/FileService.cs
@@ -81,6 +81,8 @@ namespace ICSharpCode.SharpDevelop
if (fileName == null)
throw new ArgumentNullException("fileName");
+ WorkbenchSingleton.AssertMainThread();
+
fileName = FileUtility.NormalizePath(fileName);
OpenedFile file;
openedFileDict.TryGetValue(fileName, out file);
diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
index 615ee237ed..952d398417 100644
--- a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
+++ b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
@@ -8,6 +8,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
@@ -246,7 +247,6 @@ namespace ICSharpCode.SharpDevelop
{
if (!initializing) return;
//int progressStart = progressMonitor.WorkDone;
- ParseableFileContentEnumerator enumerator = new ParseableFileContentEnumerator(project);
try {
IProjectContent[] referencedContents;
lock (this.ReferencedContents) {
@@ -260,21 +260,21 @@ namespace ICSharpCode.SharpDevelop
}
}
- while (enumerator.MoveNext()) {
- int i = enumerator.Index;
- if ((i % 4) == 2) {
- //progressMonitor.WorkDone = progressStart + i;
- token.ThrowIfCancellationRequested();
+ ParseableFileContentFinder finder = new ParseableFileContentFinder();
+ var fileContents =
+ from p in project.Items.AsParallel().WithCancellation(token)
+ where !ItemType.NonFileItemTypes.Contains(p.ItemType)
+ select finder.Create(p);
+ fileContents.ForAll(
+ entry => {
+ ITextBuffer content = entry.GetContent();
+ if (content != null)
+ ParserService.ParseFile(this, entry.FileName, content);
}
-
- ParserService.ParseFile(this, enumerator.CurrentFileName, new StringTextBuffer(enumerator.CurrentFileContent));
-
- if (!initializing) return;
- }
+ );
} finally {
initializing = false;
//progressMonitor.WorkDone = progressStart + enumerator.ItemCount;
- enumerator.Dispose();
}
}
diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
index 8694142246..0ebfd830c4 100644
--- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
+++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
@@ -275,11 +275,6 @@ namespace ICSharpCode.SharpDevelop
static ITextBuffer GetParseableFileContentInternal(string fileName)
{
- IViewContent viewContent = FileService.GetOpenFile(fileName);
- IEditable editable = viewContent as IEditable;
- if (editable != null) {
- return editable.CreateSnapshot();
- }
//ITextBuffer res = project.GetParseableFileContent(fileName);
//if (res != null)
// return res;
diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs b/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs
index 4ce8347dde..ebefb6ac92 100644
--- a/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs
+++ b/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs
@@ -5,201 +5,65 @@
// $Revision$
//
-using ICSharpCode.SharpDevelop.Editor;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text;
+
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
+using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Project
{
- ///
- /// An enumerator which enumerates through a list of project items, returning the
- /// parseable file content of each item.
- ///
- ///
- /// This class is thread-safe in a very limited way:
- /// It can be created from every thread, but may be only used by the thread that created it.
- /// It automatically uses WorkbenchSingleton.SafeThreadCall for reading currently open
- /// files when it is created/accessed from a thread.
- ///
- public class ParseableFileContentEnumerator : IEnumerator>
+ public class ParseableFileContentEntry
{
- void IEnumerator.Reset() {
- throw new NotSupportedException();
- }
+ public string FileName { get; private set; }
+ ITextBuffer openContent;
- KeyValuePair current;
-
- object IEnumerator.Current {
- get {
- return current;
- }
- }
-
- public KeyValuePair Current {
- get {
- return current;
- }
- }
-
- public string CurrentFileName {
- get {
- return current.Key;
- }
- }
-
- public string CurrentFileContent {
- get {
- return current.Value;
- }
- }
-
- public void Dispose()
- {
- }
-
- IList projectItems;
- bool isOnMainThread;
- Encoding defaultEncoding;
-
- public ParseableFileContentEnumerator(IProject project) : this(project.Items) { }
-
- public ParseableFileContentEnumerator(IList projectItems)
+ public ITextBuffer GetContent()
{
- isOnMainThread = !WorkbenchSingleton.InvokeRequired;
- this.projectItems = projectItems;
- if (projectItems.Count > 0) {
- nextItem = projectItems[0];
- }
- defaultEncoding = ParserService.DefaultFileEncoding;
- }
-
- string GetParseableFileContent(IProject project, string fileName)
- {
- // Loading the source files is done asynchronously:
- // While one file is parsed, the next is already loaded from disk.
-
- // Load file from memory if it is open
- OpenedFile file = FileService.GetOpenedFile(fileName);
- if (file != null) {
- string content;
- if (isOnMainThread) {
- content = GetFileContentFromFileDocumentProvider(file);
- } else {
- content = WorkbenchSingleton.SafeThreadFunction(GetFileContentFromFileDocumentProvider, file);
- }
- if (content != null) {
- return content;
- }
-
- using(Stream s = file.OpenRead()) {
- Encoding encoding = defaultEncoding;
- return ICSharpCode.TextEditor.Util.FileReader.ReadFileContent(s, ref encoding);
- }
- }
-
- // load file
- return ICSharpCode.TextEditor.Util.FileReader.ReadFileContent(fileName, defaultEncoding);
- }
-
- ProjectItem nextItem;
- int index = 0;
-
- public int ItemCount {
- get {
- return projectItems.Count;
- }
- }
-
- public int Index {
- get {
- return index;
- }
- }
-
- public bool MoveNext()
- {
- ProjectItem item = nextItem;
- nextItem = (++index < projectItems.Count) ? projectItems[index] : null;
- if (item == null) return false;
-
- if (ParserService.CreateParser(item.FileName) == null)
- return MoveNext();
-
- string fileContent;
+ if (openContent != null)
+ return openContent;
try {
- fileContent = GetFileContent(item);
- } catch (FileNotFoundException ex) {
- LoggingService.Warn("ParseableFileContentEnumerator: " + ex.Message);
- return MoveNext(); // skip files that were not found
- } catch (IOException ex) {
- LoggingService.Warn("ParseableFileContentEnumerator: " + ex.Message);
- return MoveNext(); // skip invalid files
- }
- current = new KeyValuePair(item.FileName, fileContent);
- return true;
- }
-
- string GetFileContent(ProjectItem item)
- {
- string fileName = item.FileName;
- if (IsFileOpen(fileName)) {
- string content;
- if (isOnMainThread)
- content = GetFileContentFromOpenFile(fileName);
- else
- content = WorkbenchSingleton.SafeThreadFunction(GetFileContentFromOpenFile, fileName);
- if (content != null)
- return content;
+ return new StringTextBuffer(ICSharpCode.AvalonEdit.Utils.FileReader.ReadFileContent(FileName, ParserService.DefaultFileEncoding));
+ } catch (IOException) {
+ return null;
+ } catch (UnauthorizedAccessException) {
+ return null;
}
- return GetParseableFileContent(item.Project, fileName);
}
- IList viewContentFileNamesCollection;
-
- bool IsFileOpen(string fileName)
+ internal ParseableFileContentEntry(ProjectItem item, IList viewContentFileNamesCollection)
{
- if (viewContentFileNamesCollection == null) {
- try {
- viewContentFileNamesCollection = WorkbenchSingleton.SafeThreadFunction>(FileService.GetOpenFiles);
- } catch (InvalidOperationException ex) {
- // can happen if the user closes SharpDevelop while the parser thread is running
- LoggingService.Warn(ex);
- viewContentFileNamesCollection = new string[0];
+ this.FileName = item.FileName;
+ foreach (string name in viewContentFileNamesCollection) {
+ if (FileUtility.IsEqualFileName(name, this.FileName)) {
+ openContent = WorkbenchSingleton.SafeThreadFunction(ParserService.GetParseableFileContent, this.FileName);
+ break;
}
}
- foreach (string contentName in viewContentFileNamesCollection) {
- if (contentName != null) {
- if (FileUtility.IsEqualFileName(fileName, contentName))
- return true;
- }
- }
- return false;
- }
-
- string GetFileContentFromOpenFile(string fileName)
- {
- IViewContent viewContent = FileService.GetOpenFile(fileName);
- IEditable editable = viewContent as IEditable;
- if (editable != null) {
- return editable.Text;
- }
- return null;
}
+ }
+
+ ///
+ /// Can be used to create ParseableFileContentEntry for ProjectItems.
+ /// This class is thread-safe.
+ ///
+ public class ParseableFileContentFinder
+ {
+ IList viewContentFileNamesCollection = WorkbenchSingleton.SafeThreadFunction(FileService.GetOpenFiles);
- static string GetFileContentFromFileDocumentProvider(OpenedFile file)
+ ///
+ /// Retrieves the file contents for the specified project items.
+ ///
+ public ParseableFileContentEntry Create(ProjectItem p)
{
- IFileDocumentProvider p = file.CurrentView as IFileDocumentProvider;
- if (p == null) return null;
- IDocument document = p.GetDocumentForFile(file);
- if (document == null) return null;
- return document.Text;
+ return new ParseableFileContentEntry(p, viewContentFileNamesCollection);
}
}
}
diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs
index 01ea976992..b1391a5d29 100644
--- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs
+++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs
@@ -152,7 +152,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
ownerClass = ownerClass.GetCompoundClass();
files = GetPossibleFiles(ownerClass, member);
}
- ParseableFileContentEnumerator enumerator = new ParseableFileContentEnumerator(files.ToArray());
+ ParseableFileContentFinder finder = new ParseableFileContentFinder();
List references = new List();
try {
if (progressMonitor != null) {
@@ -163,21 +163,27 @@ namespace ICSharpCode.SharpDevelop.Refactoring
System.Diagnostics.Debugger.Break();
}
#endif
- while (enumerator.MoveNext()) {
+ int index = 0;
+ foreach (ProjectItem item in files) {
+ var entry = finder.Create(item);
+
if (progressMonitor != null) {
- progressMonitor.WorkDone = enumerator.Index;
+ progressMonitor.WorkDone = index;
if (progressMonitor.IsCancelled) {
return null;
}
}
- AddReferences(references, ownerClass, member, isLocal, enumerator.CurrentFileName, enumerator.CurrentFileContent);
+ ITextBuffer content = entry.GetContent();
+ if (content != null) {
+ AddReferences(references, ownerClass, member, isLocal, entry.FileName, content.Text);
+ }
+ index++;
}
} finally {
if (progressMonitor != null) {
progressMonitor.Done();
}
- enumerator.Dispose();
}
return references;
}
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs
index 7cb7656125..496e5d5050 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Dialogs/GotoDialog.cs
@@ -113,19 +113,6 @@ namespace ICSharpCode.SharpDevelop.Gui
listBox.ScrollIntoView(listBox.Items[index]);
}
- static readonly IList emptyList = new ICompletionItem[0];
-
- IList Resolve(string expression)
- {
- ITextEditor editor = GetEditor();
- if (editor != null) {
- CodeCompletionItemProvider cdp = new DotCodeCompletionItemProvider();
- var list = cdp.GenerateCompletionListForExpression(editor, new ExpressionResult(expression));
- return list != null ? list.Items.ToList() : emptyList;
- }
- return emptyList;
- }
-
Dictionary visibleEntries = new Dictionary();
int bestMatchType;
double bestPriority;
@@ -164,29 +151,6 @@ namespace ICSharpCode.SharpDevelop.Gui
if (!int.TryParse(line, out lineNr))
lineNr = 0;
AddSourceFiles(file, lineNr);
- } else if (dotPos > 0) {
- AddSourceFiles(text, 0);
- string expression = text.Substring(0, dotPos).Trim();
- text = text.Substring(dotPos + 1).Trim();
- ShowCompletionData(Resolve(expression), text);
- foreach (IClass c in SearchClasses(expression)) {
- if (c.Name.Equals(expression, StringComparison.InvariantCultureIgnoreCase)) {
- foreach (IMethod m in c.DefaultReturnType.GetMethods()) {
- if (!m.IsConstructor) {
- AddItemIfMatchText(text, m, ClassBrowserIconService.GetIcon(m));
- }
- }
- foreach (IField f in c.DefaultReturnType.GetFields()) {
- AddItemIfMatchText(text, f, ClassBrowserIconService.GetIcon(f));
- }
- foreach (IProperty p in c.DefaultReturnType.GetProperties()) {
- AddItemIfMatchText(text, p, ClassBrowserIconService.GetIcon(p));
- }
- foreach (IEvent evt in c.DefaultReturnType.GetEvents()) {
- AddItemIfMatchText(text, evt, ClassBrowserIconService.GetIcon(evt));
- }
- }
- }
} else {
AddSourceFiles(text, 0);
foreach (IClass c in SearchClasses(text)) {