Browse Source

Run LoadSolutionProjectsThread when a solution is being opened.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
d4e36711ec
  1. 23
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/RopeTextSource.cs
  2. 7
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocument.cs
  3. 6
      src/Main/Base/Project/Src/Gui/Dialogs/GotoDialog.cs
  4. 30
      src/Main/Base/Project/Src/Project/CompilableProject.cs
  5. 255
      src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
  6. 3
      src/Main/Base/Project/Src/Services/ParserService/ParserService.cs

23
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/RopeTextSource.cs

@ -14,6 +14,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -14,6 +14,7 @@ namespace ICSharpCode.AvalonEdit.Document
public sealed class RopeTextSource : ITextSource
{
readonly Rope<char> rope;
readonly ITextSourceVersion version;
/// <summary>
/// Creates a new RopeTextSource.
@ -22,7 +23,18 @@ namespace ICSharpCode.AvalonEdit.Document @@ -22,7 +23,18 @@ namespace ICSharpCode.AvalonEdit.Document
{
if (rope == null)
throw new ArgumentNullException("rope");
this.rope = rope;
this.rope = rope.Clone();
}
/// <summary>
/// Creates a new RopeTextSource.
/// </summary>
public RopeTextSource(Rope<char> rope, ITextSourceVersion version)
{
if (rope == null)
throw new ArgumentNullException("rope");
this.rope = rope.Clone();
this.version = version;
}
/// <summary>
@ -30,7 +42,6 @@ namespace ICSharpCode.AvalonEdit.Document @@ -30,7 +42,6 @@ namespace ICSharpCode.AvalonEdit.Document
/// </summary>
/// <remarks>
/// RopeTextSource only publishes a copy of the contained rope to ensure that the underlying rope cannot be modified.
/// Unless the creator of the RopeTextSource still has a reference on the rope, RopeTextSource is immutable.
/// </remarks>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification="Not a property because it creates a clone")]
public Rope<char> GetRope()
@ -75,8 +86,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -75,8 +86,7 @@ namespace ICSharpCode.AvalonEdit.Document
/// <inheritdoc/>
public ITextSource CreateSnapshot()
{
// we clone the underlying rope because the creator of the RopeTextSource might be modifying it
return new RopeTextSource(rope.Clone());
return this;
}
/// <inheritdoc/>
@ -91,8 +101,9 @@ namespace ICSharpCode.AvalonEdit.Document @@ -91,8 +101,9 @@ namespace ICSharpCode.AvalonEdit.Document
return rope.IndexOfAny(anyOf, startIndex, count);
}
ITextSourceVersion ITextSource.Version {
get { return null; }
/// <inheritdoc/>
public ITextSourceVersion Version {
get { return version; }
}
string ITextSource.GetText(ICSharpCode.Editor.ISegment segment)

7
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Document/TextDocument.cs

@ -298,7 +298,9 @@ namespace ICSharpCode.AvalonEdit.Document @@ -298,7 +298,9 @@ namespace ICSharpCode.AvalonEdit.Document
public ITextSource CreateSnapshot()
{
lock (lockObject) {
return new RopeTextSource(rope.Clone());
if (currentCheckpoint == null)
currentCheckpoint = new ChangeTrackingCheckpoint(lockObject);
return new RopeTextSource(rope, currentCheckpoint);
}
}
@ -325,7 +327,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -325,7 +327,7 @@ namespace ICSharpCode.AvalonEdit.Document
if (currentCheckpoint == null)
currentCheckpoint = new ChangeTrackingCheckpoint(lockObject);
checkpoint = currentCheckpoint;
return new RopeTextSource(rope.Clone());
return new RopeTextSource(rope, currentCheckpoint);
}
}
@ -927,6 +929,7 @@ namespace ICSharpCode.AvalonEdit.Document @@ -927,6 +929,7 @@ namespace ICSharpCode.AvalonEdit.Document
var container = new ServiceContainer();
container.AddService(typeof(IDocument), this);
container.AddService(typeof(TextDocument), this);
serviceProvider = container;
}
return serviceProvider;
}

6
src/Main/Base/Project/Src/Gui/Dialogs/GotoDialog.cs

@ -2,19 +2,15 @@ @@ -2,19 +2,15 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.Core;
using ICSharpCode.Core.Presentation;
using ICSharpCode.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.CodeCompletion;

30
src/Main/Base/Project/Src/Project/CompilableProject.cs

@ -10,6 +10,9 @@ using System.Linq; @@ -10,6 +10,9 @@ using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Xml.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project.Converter;
using ICSharpCode.SharpDevelop.Util;
@ -403,6 +406,10 @@ namespace ICSharpCode.SharpDevelop.Project @@ -403,6 +406,10 @@ namespace ICSharpCode.SharpDevelop.Project
void Reparse(bool references, bool code)
{
lock (SyncRoot) {
if (parseProjectContent == null)
return; // parsing hasn't started yet; no need to re-parse
}
#warning Reparse
throw new NotImplementedException();
}
@ -643,5 +650,28 @@ namespace ICSharpCode.SharpDevelop.Project @@ -643,5 +650,28 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
#endregion
#region Type System
volatile ParseProjectContent parseProjectContent;
public override IProjectContent ProjectContent {
get {
if (parseProjectContent == null) {
lock (SyncRoot) {
if (parseProjectContent == null) {
parseProjectContent = new ParseProjectContent(this);
}
}
}
return parseProjectContent;
}
}
public override ITypeResolveContext TypeResolveContext {
get {
return new CompositeTypeResolveContext(new ITypeResolveContext[] { this.ProjectContent, MinimalResolveContext.Instance });
}
}
#endregion
}
}

255
src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs

@ -7,130 +7,114 @@ using System.IO; @@ -7,130 +7,114 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.Editor;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
/*
namespace ICSharpCode.SharpDevelop.Parser
{
public sealed class ParseProjectContent : DefaultProjectContent
public class ParseProjectContent : SimpleProjectContent, IDisposable
{
readonly IProject project;
readonly object lockObj = new object();
bool initializing;
bool disposed;
public ParseProjectContent(IProject project)
{
if (project == null)
throw new ArgumentNullException("project");
this.project = project;
this.Language = project.LanguageProperties;
this.initializing = true;
LoadSolutionProjects.AddJob(Initialize, "Loading " + project.Name + "...", GetInitializationWorkAmount());
}
readonly IProject project;
public override object Project {
get {
return project;
public void Dispose()
{
lock (lockObj) {
ProjectService.ProjectItemAdded -= OnProjectItemAdded;
ProjectService.ProjectItemRemoved -= OnProjectItemRemoved;
disposed = true;
}
}
public string ProjectName {
get { return project.Name; }
initializing = false;
}
public override string AssemblyName {
get { return project.AssemblyName; }
}
bool initializing;
public override string ToString()
{
return string.Format("[{0}: {1}]", GetType().Name, project.Name);
}
internal void Initialize1(IProgressMonitor progressMonitor)
int GetInitializationWorkAmount()
{
ICollection<ProjectItem> items = project.Items;
ProjectService.ProjectItemAdded += OnProjectItemAdded;
ProjectService.ProjectItemRemoved += OnProjectItemRemoved;
UpdateDefaultImports(items);
// TODO: Translate me
// progressMonitor.TaskName = "Resolving references for " + project.Name + "...";
project.ResolveAssemblyReferences();
foreach (ProjectItem item in items) {
if (!initializing) return; // abort initialization
progressMonitor.CancellationToken.ThrowIfCancellationRequested();
if (ItemType.ReferenceItemTypes.Contains(item.ItemType)) {
ReferenceProjectItem reference = item as ReferenceProjectItem;
if (reference != null) {
// TODO: Translate me
// progressMonitor.TaskName = "Loading " + reference.ShortName + "...";
AddReference(reference, false, progressMonitor.CancellationToken);
}
}
}
UpdateReferenceInterDependencies();
OnReferencedContentsChanged(EventArgs.Empty);
return project.Items.Count + 15;
}
internal void ReInitialize1(IProgressMonitor progressMonitor)
void Initialize(IProgressMonitor progressMonitor)
{
var mscorlib = AssemblyParserService.GetRegistryForReference(new ReferenceProjectItem(project, "mscorlib")).Mscorlib;
// don't fetch mscorlib within lock - finding the correct registry might access the project, causing
// a deadlock between IProject.SyncRoot and the ReferencedContents lock
lock (ReferencedContents) {
ReferencedContents.Clear();
AddReferencedContent(mscorlib);
ICollection<ProjectItem> projectItems = project.Items;
lock (lockObj) {
if (disposed) {
throw new ObjectDisposedException("ParseProjectContent");
}
ProjectService.ProjectItemAdded += OnProjectItemAdded;
ProjectService.ProjectItemRemoved += OnProjectItemRemoved;
}
// prevent adding event handler twice
ProjectService.ProjectItemAdded -= OnProjectItemAdded;
ProjectService.ProjectItemRemoved -= OnProjectItemRemoved;
initializing = true;
try {
Initialize1(progressMonitor);
} finally {
initializing = false;
using (IProgressMonitor initReferencesProgressMonitor = progressMonitor.CreateSubTask(15),
parseProgressMonitor = progressMonitor.CreateSubTask(projectItems.Count))
{
var resolveReferencesTask = ResolveReferencesAsync(projectItems, initReferencesProgressMonitor);
ParseFiles(projectItems, parseProgressMonitor);
resolveReferencesTask.Wait();
}
}
void UpdateReferenceInterDependencies()
void ParseFiles(ICollection<ProjectItem> projectItems, IProgressMonitor progressMonitor)
{
// Use ToArray because the collection could be modified inside the loop
IProjectContent[] referencedContents;
lock (this.ReferencedContents) {
referencedContents = new IProjectContent[this.ReferencedContents.Count];
this.ReferencedContents.CopyTo(referencedContents, 0);
}
foreach (IProjectContent referencedContent in referencedContents) {
if (referencedContent is ReflectionProjectContent) {
((ReflectionProjectContent)referencedContent).InitializeReferences();
ParseableFileContentFinder finder = new ParseableFileContentFinder();
var fileContents = (
from p in projectItems.AsParallel().WithCancellation(progressMonitor.CancellationToken)
where !ItemType.NonFileItemTypes.Contains(p.ItemType) && !String.IsNullOrEmpty(p.FileName)
select FileName.Create(p.FileName)
).ToList();
object progressLock = new object();
double fileCountInverse = 1.0 / fileContents.Count;
Parallel.ForEach(
fileContents,
new ParallelOptions {
MaxDegreeOfParallelism = Environment.ProcessorCount,
CancellationToken = progressMonitor.CancellationToken
},
fileName => {
// Don't read files we don't have a parser for.
// This avoids loading huge files (e.g. sdps) when we have no intention of parsing them.
if (ParserService.GetParser(fileName) != null) {
ITextSource content = finder.Create(fileName);
if (content != null)
ParserService.ParseFile(this, fileName, content);
}
lock (progressLock) {
progressMonitor.Progress += fileCountInverse;
}
}
}
);
}
void AddReference(ReferenceProjectItem reference, bool updateInterDependencies, CancellationToken cancellationToken)
System.Threading.Tasks.Task ResolveReferencesAsync(ICollection<ProjectItem> projectItems, IProgressMonitor progressMonitor)
{
try {
AddReferencedContent(AssemblyParserService.GetProjectContentForReference(reference));
if (updateInterDependencies) {
UpdateReferenceInterDependencies();
}
OnReferencedContentsChanged(EventArgs.Empty);
// Refresh the reference if required.
// If the user removes the reference and then re-adds it, there might be other references
// in the project depending on it, so we do the refresh after the old reference was added.
AssemblyParserService.RefreshProjectContentForReference(reference);
} catch (OperationCanceledException) {
throw;
} catch (ObjectDisposedException e) {
// ObjectDisposedException can happen if project gets disposed while LoadSolutionProjectsThread is running.
// We will ignore the ObjectDisposedException and throw OperationCanceledException instead.
cancellationToken.ThrowIfCancellationRequested();
MessageService.ShowException(e);
} catch (Exception e) {
MessageService.ShowException(e);
}
return System.Threading.Tasks.Task.Factory.StartNew(
delegate {
project.ResolveAssemblyReferences();
}, progressMonitor.CancellationToken);
}
// ensure that com references are built serially because we cannot invoke multiple instances of MSBuild
@ -149,13 +133,13 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -149,13 +133,13 @@ namespace ICSharpCode.SharpDevelop.Parser
project.Save(); // project is not yet saved when ItemAdded fires, so save it here
TaskService.BuildMessageViewCategory.AppendText("\n${res:MainWindow.CompilerMessages.CreatingCOMInteropAssembly}\n");
BuildCallback afterBuildCallback = delegate {
ReparseReferences();
lock (callAfterAddComReference) {
if (callAfterAddComReference.Count > 0) {
// run next enqueued action
callAfterAddComReference.Dequeue()();
} else {
buildingComReference = false;
ParserService.Reparse(project, true, false);
}
}
};
@ -173,18 +157,24 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -173,18 +157,24 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
} else {
ParserService.Reparse(project, true, false);
ReparseReferences();
}
}
if (e.ProjectItem.ItemType == ItemType.Import) {
UpdateDefaultImports(project.Items);
throw new NotImplementedException();
//UpdateDefaultImports(project.Items);
} else if (e.ProjectItem.ItemType == ItemType.Compile) {
if (System.IO.File.Exists(e.ProjectItem.FileName)) {
ParserService.BeginParse(e.ProjectItem.FileName);
ParserService.ParseFileAsync(FileName.Create(e.ProjectItem.FileName));
}
}
}
void ReparseReferences()
{
throw new NotImplementedException();
}
void OnProjectItemRemoved(object sender, ProjectItemEventArgs e)
{
if (e.Project != project) return;
@ -192,25 +182,21 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -192,25 +182,21 @@ namespace ICSharpCode.SharpDevelop.Parser
ReferenceProjectItem reference = e.ProjectItem as ReferenceProjectItem;
if (reference != null) {
try {
IProjectContent referencedContent = AssemblyParserService.GetExistingProjectContentForReference(reference);
if (referencedContent != null) {
lock (ReferencedContents) {
ReferencedContents.Remove(referencedContent);
}
OnReferencedContentsChanged(EventArgs.Empty);
}
ReparseReferences();
} catch (Exception ex) {
MessageService.ShowException(ex);
}
}
if (e.ProjectItem.ItemType == ItemType.Import) {
UpdateDefaultImports(project.Items);
throw new NotImplementedException();
//UpdateDefaultImports(project.Items);
} else if (e.ProjectItem.ItemType == ItemType.Compile) {
ParserService.ClearParseInformation(e.ProjectItem.FileName);
ParserService.ClearParseInformation(FileName.Create(e.ProjectItem.FileName));
}
}
/*
int languageDefaultImportCount = -1;
void UpdateDefaultImports(ICollection<ProjectItem> items)
@ -233,77 +219,6 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -233,77 +219,6 @@ namespace ICSharpCode.SharpDevelop.Parser
DefaultImports.Usings.Add(item.Include);
}
}
}
internal int GetInitializationWorkAmount()
{
return project.Items.Count;
}
internal void ReInitialize2(IProgressMonitor progressMonitor)
{
if (initializing) return;
initializing = true;
Initialize2(progressMonitor);
}
internal void Initialize2(IProgressMonitor progressMonitor)
{
if (!initializing) return;
try {
IProjectContent[] referencedContents;
lock (this.ReferencedContents) {
referencedContents = new IProjectContent[this.ReferencedContents.Count];
this.ReferencedContents.CopyTo(referencedContents, 0);
}
foreach (IProjectContent referencedContent in referencedContents) {
if (referencedContent is ReflectionProjectContent) {
((ReflectionProjectContent)referencedContent).InitializeReferences();
}
}
ParseableFileContentFinder finder = new ParseableFileContentFinder();
var fileContents = (
from p in project.Items.AsParallel().WithCancellation(progressMonitor.CancellationToken)
where !ItemType.NonFileItemTypes.Contains(p.ItemType) && !String.IsNullOrEmpty(p.FileName)
select FileName.Create(p.FileName)
).ToList();
object progressLock = new object();
double fileCountInverse = 1.0 / fileContents.Count;
Parallel.ForEach(
fileContents,
new ParallelOptions {
MaxDegreeOfParallelism = Environment.ProcessorCount * 2,
CancellationToken = progressMonitor.CancellationToken
},
fileName => {
// Don't read files we don't have a parser for.
// This avoids loading huge files (e.g. sdps) when we have no intention of parsing them.
if (ParserService.GetParser(fileName) != null) {
ITextBuffer content = finder.Create(fileName);
if (content != null)
ParserService.ParseFile(this, fileName, content);
}
lock (progressLock) {
progressMonitor.Progress += fileCountInverse;
}
}
);
} finally {
initializing = false;
progressMonitor.Progress = 1;
}
}
public override void Dispose()
{
ProjectService.ProjectItemAdded -= OnProjectItemAdded;
ProjectService.ProjectItemRemoved -= OnProjectItemRemoved;
initializing = false;
base.Dispose();
}
}*/
}
}
*/

3
src/Main/Base/Project/Src/Services/ParserService/ParserService.cs

@ -1033,6 +1033,9 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -1033,6 +1033,9 @@ namespace ICSharpCode.SharpDevelop.Parser
internal static void OnSolutionLoaded()
{
foreach (IProject project in ProjectService.OpenSolution.Projects) {
RegisterProjectContentForAddedProject(project);
}
}
internal static void OnSolutionClosed()

Loading…
Cancel
Save