Browse Source

Fix LoadSolutionProjects-Thread.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
ebceccdaa9
  1. 1
      TODOnewNR.txt
  2. 4
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpSemanticHighlighter.cs
  3. 9
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs
  4. 9
      src/AddIns/BackendBindings/CppBinding/CppBinding/Project/CppProject.cs
  5. 9
      src/AddIns/BackendBindings/FSharpBinding/FSharpProject.cs
  6. 2
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParsedFile.cs
  7. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/EditorActionsProvider.cs
  8. 2
      src/AddIns/VersionControl/GitAddIn/Src/OverlayIconManager.cs
  9. 2
      src/AddIns/VersionControl/SubversionAddIn/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs
  10. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  11. 3
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  12. 4
      src/Main/Base/Project/Src/Gui/Dialogs/GotoDialog.cs
  13. 9
      src/Main/Base/Project/Src/Internal/Templates/Project/ProjectCreateInformation.cs
  14. 22
      src/Main/Base/Project/Src/Project/CompilableProject.cs
  15. 1
      src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs
  16. 2
      src/Main/Base/Project/Src/Project/MSBuildInternals.cs
  17. 9
      src/Main/Base/Project/Src/Project/ProjectLoadInformation.cs
  18. 3
      src/Main/Base/Project/Src/Project/Solution/Solution.cs
  19. 4
      src/Main/Base/Project/Src/Services/File/FileService.cs
  20. 2
      src/Main/Base/Project/Src/Services/NavigationService/NavigationService.cs
  21. 37
      src/Main/Base/Project/Src/Services/ParserService/IAssemblyParserService.cs
  22. 51
      src/Main/Base/Project/Src/Services/ParserService/IParserService.cs
  23. 99
      src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs
  24. 2
      src/Main/Base/Project/Src/Services/RefactoringService/FindReferenceService.cs
  25. 4
      src/Main/Base/Project/Src/Services/SD.cs
  26. 5
      src/Main/Base/Test/WebReferences/WebReferenceTestHelper.cs
  27. 33
      src/Main/SharpDevelop/Parser/AssemblyParserService.cs
  28. 83
      src/Main/SharpDevelop/Parser/LoadSolutionProjects.cs
  29. 21
      src/Main/SharpDevelop/Parser/ParserService.cs
  30. 3
      src/Main/SharpDevelop/Sda/CallHelper.cs
  31. 6
      src/Main/SharpDevelop/SharpDevelop.csproj

1
TODOnewNR.txt

@ -22,6 +22,7 @@ Stuff that was renamed/moved: @@ -22,6 +22,7 @@ Stuff that was renamed/moved:
IReturnType -> ITypeReference (unresolved) or IType (resolved)
Location -> TextLocation in ICSharpCode.NRefactory
TextLocation -> moved to ICSharpCode.NRefactory
ParserService -> SD.ParserService
Functionality changes:
The result of a parser run (ParseInformation) now may contain a fully parsed AST.

4
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpSemanticHighlighter.cs

@ -62,14 +62,14 @@ namespace CSharpBinding @@ -62,14 +62,14 @@ namespace CSharpBinding
this.parameterModifierColor = highlightingDefinition.GetNamedColor("ParameterModifiers");
SD.ParserService.ParseInformationUpdated += ParserService_ParseInformationUpdated;
SD.ParserService.LoadSolutionProjectsThreadEnded += ParserService_LoadSolutionProjectsThreadEnded;
SD.ParserService.LoadSolutionProjectsThread.Finished += ParserService_LoadSolutionProjectsThreadEnded;
syntaxHighlighter.VisibleDocumentLinesChanged += syntaxHighlighter_VisibleDocumentLinesChanged;
}
public void Dispose()
{
SD.ParserService.ParseInformationUpdated -= ParserService_ParseInformationUpdated;
SD.ParserService.LoadSolutionProjectsThreadEnded -= ParserService_LoadSolutionProjectsThreadEnded;
SD.ParserService.LoadSolutionProjectsThread.Finished -= ParserService_LoadSolutionProjectsThreadEnded;
syntaxHighlighter.VisibleDocumentLinesChanged -= syntaxHighlighter_VisibleDocumentLinesChanged;
}
#endregion

9
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Project/CSharpProject.cs

@ -52,6 +52,7 @@ namespace CSharpBinding @@ -52,6 +52,7 @@ namespace CSharpBinding
: base(loadInformation)
{
Init();
InitializeProjectContent(new CSharpProjectContent());
}
public const string DefaultTargetsFile = @"$(MSBuildBinPath)\Microsoft.CSharp.Targets";
@ -73,6 +74,9 @@ namespace CSharpBinding @@ -73,6 +74,9 @@ namespace CSharpBinding
PropertyStorageLocations.ConfigurationSpecific, false);
SetProperty("Release", null, "DefineConstants", "TRACE",
PropertyStorageLocations.ConfigurationSpecific, false);
if (info.InitializeTypeSystem)
InitializeProjectContent(new CSharpProjectContent());
}
public override void StartBuild(ProjectBuildOptions options, IBuildFeedbackSink feedbackSink)
@ -157,11 +161,6 @@ namespace CSharpBinding @@ -157,11 +161,6 @@ namespace CSharpBinding
}
*/
protected override IProjectContent CreateProjectContent()
{
return new CSharpProjectContent();
}
protected override ProjectBehavior CreateDefaultBehavior()
{
return new CSharpProjectBehavior(this, base.CreateDefaultBehavior());

9
src/AddIns/BackendBindings/CppBinding/CppBinding/Project/CppProject.cs

@ -185,15 +185,6 @@ namespace ICSharpCode.CppBinding.Project @@ -185,15 +185,6 @@ namespace ICSharpCode.CppBinding.Project
{
return new CppProjectBehavior(this, base.CreateDefaultBehavior());
}
public override ICSharpCode.NRefactory.TypeSystem.IProjectContent ProjectContent {
get { return null; }
}
protected override ICSharpCode.NRefactory.TypeSystem.IProjectContent CreateProjectContent()
{
throw new NotSupportedException();
}
}
public class CppProjectBehavior : ProjectBehavior

9
src/AddIns/BackendBindings/FSharpBinding/FSharpProject.cs

@ -41,15 +41,6 @@ namespace FSharpBinding @@ -41,15 +41,6 @@ namespace FSharpBinding
{
return new FSharpProjectBehavior(this, base.CreateDefaultBehavior());
}
public override ICSharpCode.NRefactory.TypeSystem.IProjectContent ProjectContent {
get { return null; }
}
protected override ICSharpCode.NRefactory.TypeSystem.IProjectContent CreateProjectContent()
{
throw new NotSupportedException();
}
}
public class FSharpProjectBehavior : ProjectBehavior

2
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParsedFile.cs

@ -148,7 +148,7 @@ namespace ICSharpCode.XamlBinding @@ -148,7 +148,7 @@ namespace ICSharpCode.XamlBinding
element.GetAttributeValue("Name");
string modifier = element.GetAttributeValue(XamlBehavior.XamlNamespace, "FieldModifier");
if (name != null) {
if (name != null && TypeDefinition != null) {
var field = new DefaultUnresolvedField(TypeDefinition, name);
field.Accessibility = Accessibility.Internal;
field.Region = new DomRegion(file.FileName, textDocument.GetLocation(element.StartOffset), textDocument.GetLocation(element.EndOffset));

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ContextActions/EditorActionsProvider.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions @@ -83,7 +83,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.ContextActions
/// </summary>
async Task<IEnumerable<IContextAction>> GetActionsAsync(IEnumerable<IContextActionProvider> providers, CancellationToken cancellationToken)
{
if (SD.ParserService.LoadSolutionProjectsThreadRunning)
if (SD.ParserService.LoadSolutionProjectsThread.IsRunning)
return EmptyList<IContextAction>.Instance;
var providerList = providers.ToList();
var actions = await Task.WhenAll(providerList.Select(p => p.GetAvailableActionsAsync(this.EditorContext, cancellationToken)));

2
src/AddIns/VersionControl/GitAddIn/Src/OverlayIconManager.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.GitAddIn @@ -83,7 +83,7 @@ namespace ICSharpCode.GitAddIn
// sleep a tiny bit to give main thread time to add more jobs to the queue
Thread.Sleep(100);
while (true) {
if (SD.ParserService.LoadSolutionProjectsThreadRunning) {
if (SD.ParserService.LoadSolutionProjectsThread.IsRunning) {
// Run OverlayIconManager much more slowly while solution is being loaded.
// This prevents the disk from seeking too much
Thread.Sleep(100);

2
src/AddIns/VersionControl/SubversionAddIn/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs

@ -139,7 +139,7 @@ namespace ICSharpCode.Svn @@ -139,7 +139,7 @@ namespace ICSharpCode.Svn
// sleep a tiny bit to give main thread time to add more jobs to the queue
Thread.Sleep(2);
while (true) {
if (SD.ParserService.LoadSolutionProjectsThreadRunning) {
if (SD.ParserService.LoadSolutionProjectsThread.IsRunning) {
// Run OverlayIconManager much more slowly while solution is being loaded.
// This prevents the disk from seeking too much
Thread.Sleep(100);

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -58,6 +58,8 @@ @@ -58,6 +58,8 @@
class="ICSharpCode.SharpDevelop.Parser.GlobalAssemblyCacheService"/>
<Service id="ICSharpCode.SharpDevelop.Parser.IParserService"
class="ICSharpCode.SharpDevelop.Parser.ParserService"/>
<Service id="ICSharpCode.SharpDevelop.Parser.IAssemblyParserService"
class="ICSharpCode.SharpDevelop.Parser.AssemblyParserService"/>
<Service id="ICSharpCode.SharpDevelop.IFileService"
class="ICSharpCode.SharpDevelop.Workbench.FileService"/>
</Path>

3
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -372,13 +372,12 @@ @@ -372,13 +372,12 @@
<Compile Include="Src\Services\File\FileService.cs" />
<Compile Include="Src\Services\File\FileEventArgs.cs" />
<Compile Include="Src\Services\MimeTypeDetection.cs" />
<Compile Include="Src\Services\ParserService\AssemblyParserService.cs" />
<Compile Include="Src\Services\ParserService\DomAssemblyName.cs" />
<Compile Include="Src\Services\ParserService\IAssemblyParserService.cs" />
<Compile Include="Src\Services\ParserService\IGlobalAssemblyCacheService.cs" />
<Compile Include="Src\Services\ParserService\IParserService.cs" />
<Compile Include="Src\Services\ParserService\IParser.cs" />
<Compile Include="Src\Services\ParserService\ParseInformation.cs" />
<Compile Include="Src\Services\ParserService\LoadSolutionProjects.cs" />
<Compile Include="Src\Services\ParserService\SharpDevelopSolutionSnapshot.cs" />
<Compile Include="Src\Services\ProjectService\CompileModifiedProjectsOnly.cs" />
<Compile Include="Src\Services\ProjectService\SolutionConfigurationEventHandler.cs" />

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

@ -38,14 +38,14 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -38,14 +38,14 @@ namespace ICSharpCode.SharpDevelop.Gui
{
InitializeComponent();
FormLocationHelper.ApplyWindow(this, "ICSharpCode.SharpDevelop.Gui.GotoDialog.Bounds", true);
SD.ParserService.LoadSolutionProjectsThreadEnded += ParserService_LoadSolutionProjectsThreadEnded;
SD.ParserService.LoadSolutionProjectsThread.Finished += ParserService_LoadSolutionProjectsThreadEnded;
textBox.Focus();
}
protected override void OnClosed(EventArgs e)
{
Instance = null;
SD.ParserService.LoadSolutionProjectsThreadEnded -= ParserService_LoadSolutionProjectsThreadEnded;
SD.ParserService.LoadSolutionProjectsThread.Finished -= ParserService_LoadSolutionProjectsThreadEnded;
base.OnClosed(e);
}

9
src/Main/Base/Project/Src/Internal/Templates/Project/ProjectCreateInformation.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -31,7 +31,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
createdProjects.AddRange(projects);
}
public ReadOnlyCollection<IProject> CreatedProjects {
public IReadOnlyList<IProject> CreatedProjects {
get { return createdProjects.AsReadOnly(); }
}
@ -44,5 +44,12 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates @@ -44,5 +44,12 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates
public string ProjectBasePath { get; set; }
public TargetFramework TargetFramework { get; set; }
public Solution Solution { get; set; }
/// <summary>
/// Whether to initialize the type system for the newly created project.
/// The default is <c>false</c> because SharpDevelop saves and re-loads newly created projects,
/// so we don't need a type system if we're going to re-load it anyways.
/// </summary>
public bool InitializeTypeSystem { get; set; }
}
}

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

@ -360,29 +360,27 @@ namespace ICSharpCode.SharpDevelop.Project @@ -360,29 +360,27 @@ namespace ICSharpCode.SharpDevelop.Project
#region Type System
volatile ParseProjectContentContainer parseProjectContentContainer;
protected abstract IProjectContent CreateProjectContent();
ParseProjectContentContainer GetParseProjectContentContainer()
protected void InitializeProjectContent(IProjectContent initialProjectContent)
{
if (parseProjectContentContainer == null) {
lock (SyncRoot) {
if (parseProjectContentContainer == null) {
parseProjectContentContainer = new ParseProjectContentContainer(this, CreateProjectContent());
}
}
lock (SyncRoot) {
if (parseProjectContentContainer != null)
throw new InvalidOperationException("Already initialized.");
parseProjectContentContainer = new ParseProjectContentContainer(this, initialProjectContent);
}
return parseProjectContentContainer;
}
public override IProjectContent ProjectContent {
get {
return GetParseProjectContentContainer().ProjectContent;
var c = parseProjectContentContainer;
return c != null ? c.ProjectContent : null;
}
}
public override void OnParseInformationUpdated(ParseInformationEventArgs args)
{
GetParseProjectContentContainer().ParseInformationUpdated(args.OldParsedFile, args.NewParsedFile);
var c = parseProjectContentContainer;
if (c != null)
c.ParseInformationUpdated(args.OldParsedFile, args.NewParsedFile);
// OnParseInformationUpdated is called inside a lock, but we don't want to raise the event inside that lock.
// To ensure events are raised in the same order, we always invoke on the main thread.
SD.MainThread.InvokeAsync(

1
src/Main/Base/Project/Src/Project/MSBuildBasedProject.cs

@ -1210,6 +1210,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -1210,6 +1210,7 @@ namespace ICSharpCode.SharpDevelop.Project
{
this.projectCollection = loadInformation.ParentSolution.MSBuildProjectCollection;
this.FileName = loadInformation.FileName;
this.ActiveConfiguration = loadInformation.Configuration;
this.ActivePlatform = loadInformation.Platform;
projectFile = ProjectRootElement.Open(loadInformation.FileName, projectCollection);

2
src/Main/Base/Project/Src/Project/MSBuildInternals.cs

@ -234,7 +234,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -234,7 +234,7 @@ namespace ICSharpCode.SharpDevelop.Project
List<ReferenceProjectItem> resolvedAssemblies = new List<ReferenceProjectItem>();
List<ReferenceProjectItem> handledReferenceItems = new List<ReferenceProjectItem>();
foreach (var assembly in query) {
LoggingService.Debug("Got information about " + assembly.OriginalInclude + "; fullpath=" + assembly.FullPath);
//LoggingService.Debug("Got information about " + assembly.OriginalInclude + "; fullpath=" + assembly.FullPath);
foreach (var referenceItem in assembly.ReferenceItems) {
referenceItem.AssemblyName = assembly.AssemblyName;
referenceItem.FileName = assembly.FullPath;

9
src/Main/Base/Project/Src/Project/ProjectLoadInformation.cs

@ -13,10 +13,18 @@ namespace ICSharpCode.SharpDevelop.Project @@ -13,10 +13,18 @@ namespace ICSharpCode.SharpDevelop.Project
{
public Solution ParentSolution { get; private set; }
public string FileName { get; private set; }
public string Configuration { get; internal set; }
public string Platform { get; internal set; }
public string ProjectName { get; private set; }
public string TypeGuid { get; set; }
public IList<ProjectSection> ProjectSections {get; set;}
/// <summary>
/// Whether to initialize the type system for the newly loaded project.
/// The default is <c>true</c>.
/// </summary>
public bool InitializeTypeSystem { get; set; }
internal string Guid { get; set; }
internal bool? upgradeToolsVersion;
@ -47,6 +55,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -47,6 +55,7 @@ namespace ICSharpCode.SharpDevelop.Project
this.ParentSolution = parentSolution;
this.FileName = fileName;
this.ProjectName = projectName;
this.InitializeTypeSystem = true;
}
}
}

3
src/Main/Base/Project/Src/Project/Solution/Solution.cs

@ -587,7 +587,8 @@ namespace ICSharpCode.SharpDevelop.Project @@ -587,7 +587,8 @@ namespace ICSharpCode.SharpDevelop.Project
// set the target platform
SolutionItem projectConfig = newSolution.GetProjectConfiguration(loadInfo.Guid);
loadInfo.Platform = AbstractProject.GetPlatformNameFromKey(projectConfig.Location);
loadInfo.Configuration = AbstractProject.GetConfigurationNameFromKey(projectConfig.Location);
loadInfo.Platform = FixPlatformNameForProject(AbstractProject.GetPlatformNameFromKey(projectConfig.Location));
loadInfo.ProgressMonitor = progressMonitor;
progressMonitor.Progress = (double)i / projectsToLoad.Count;

4
src/Main/Base/Project/Src/Services/File/FileService.cs

@ -22,14 +22,14 @@ namespace ICSharpCode.SharpDevelop @@ -22,14 +22,14 @@ namespace ICSharpCode.SharpDevelop
internal static void Unload()
{
SD.ParserService.LoadSolutionProjectsThreadEnded -= ParserServiceLoadSolutionProjectsThreadEnded;
SD.ParserService.LoadSolutionProjectsThread.Finished -= ParserServiceLoadSolutionProjectsThreadEnded;
serviceInitialized = false;
}
internal static void InitializeService()
{
if (!serviceInitialized) {
SD.ParserService.LoadSolutionProjectsThreadEnded += ParserServiceLoadSolutionProjectsThreadEnded;
SD.ParserService.LoadSolutionProjectsThread.Finished += ParserServiceLoadSolutionProjectsThreadEnded;
serviceInitialized = true;
}
}

2
src/Main/Base/Project/Src/Services/NavigationService/NavigationService.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.SharpDevelop @@ -70,7 +70,7 @@ namespace ICSharpCode.SharpDevelop
// ignore files opened as part of loading a solution.
ProjectService.SolutionLoading += ProjectService_SolutionLoading;
SD.ParserService.LoadSolutionProjectsThreadEnded += LoadSolutionProjectsThreadEnded;
SD.ParserService.LoadSolutionProjectsThread.Finished += LoadSolutionProjectsThreadEnded;
FileService.FileRenamed += FileService_FileRenamed;
ProjectService.SolutionClosed += ProjectService_SolutionClosed;

37
src/Main/Base/Project/Src/Services/ParserService/IAssemblyParserService.cs

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.SharpDevelop.Parser
{
/// <summary>
/// Portions of parser service that deal with loading external assemblies for code completion.
/// </summary>
public interface IAssemblyParserService
{
IUnresolvedAssembly GetAssembly(FileName fileName, CancellationToken cancellationToken = default(CancellationToken));
Task<IUnresolvedAssembly> GetAssemblyAsync(FileName fileName, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// <code>using (AssemblyParserService.AvoidRedundantChecks())</code>
/// Within the using block, the AssemblyParserService will only check once per assembly if the
/// existing cached project content (if any) is up to date.
/// Any additional accesses will return that cached project content without causing an update check.
/// This applies only to the thread that called AvoidRedundantChecks() - other threads will
/// perform update checks as usual.
/// </summary>
IDisposable AvoidRedundantChecks();
/// <summary>
/// Gets the directory for cached project contents.
/// </summary>
string DomPersistencePath { get; }
}
}

51
src/Main/Base/Project/Src/Services/ParserService/IParserService.cs

@ -12,6 +12,7 @@ using ICSharpCode.NRefactory.Editor; @@ -12,6 +12,7 @@ using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Refactoring;
@ -29,26 +30,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -29,26 +30,7 @@ namespace ICSharpCode.SharpDevelop.Parser
/// </summary>
IReadOnlyList<string> TaskListTokens { get; set; }
#region Load Solution Projects Thread
/// <summary>
/// Gets whether the solution is being loaded, or a major re-parse is happening
/// (e.g. after adding a project).
/// </summary>
/// <remarks>This property is only changed by the main thread.</remarks>
bool LoadSolutionProjectsThreadRunning { get; }
/// <summary>
/// This event is raised when the LoadSolutionProjectsThreadRunning property changes to <c>true</c>.
/// This always happens on the main thread.
/// </summary>
event EventHandler LoadSolutionProjectsThreadStarted;
/// <summary>
/// This event is raised when the LoadSolutionProjectsThreadRunning property changes to <c>false</c>.
/// This always happens on the main thread.
/// </summary>
event EventHandler LoadSolutionProjectsThreadEnded; // TODO: rename to finished
#endregion
ILoadSolutionProjectsThread LoadSolutionProjectsThread { get; }
#region GetCompilation
/// <summary>
@ -288,4 +270,33 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -288,4 +270,33 @@ namespace ICSharpCode.SharpDevelop.Parser
event EventHandler<ParseInformationEventArgs> ParseInformationUpdated;
#endregion
}
public interface ILoadSolutionProjectsThread
{
/// <summary>
/// Gets whether the solution is being loaded, or a major re-parse is happening
/// (e.g. after adding a project).
/// </summary>
bool IsRunning { get; }
/// <summary>
/// This event is raised when the IsRunning property changes to <c>true</c>.
/// This always happens on the main thread.
/// </summary>
event EventHandler Started;
/// <summary>
/// This event is raised when the IsRunning property changes to <c>false</c>.
/// This always happens on the main thread.
/// </summary>
event EventHandler Finished;
/// <summary>
/// Adds a new task to the job queue, and starts the LoadSolutionProjects thread (if its not already running).
/// </summary>
/// <param name="action">The action to run. Parameter: a nested progress monitor for the action.</param>
/// <param name="name">Name of the action - shown in the status bar</param>
/// <param name="cost">Cost of the action</param>
void AddJob(Action<IProgressMonitor> action, string name, double cost);
}
}

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

@ -5,8 +5,8 @@ using System; @@ -5,8 +5,8 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
@ -28,9 +28,11 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -28,9 +28,11 @@ namespace ICSharpCode.SharpDevelop.Parser
IProjectContent projectContent;
IAssemblyReference[] references = { MinimalCorlib.Instance };
bool initializing;
bool disposed;
// time necessary for loading references, in relation to time for a single C# file
const int LoadingReferencesWorkAmount = 15;
public ParseProjectContentContainer(MSBuildBasedProject project, IProjectContent initialProjectContent)
{
if (project == null)
@ -38,18 +40,22 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -38,18 +40,22 @@ namespace ICSharpCode.SharpDevelop.Parser
this.project = project;
this.projectContent = initialProjectContent.SetAssemblyName(project.AssemblyName);
this.initializing = true;
LoadSolutionProjects.AddJob(Initialize, "Loading " + project.Name + "...", GetInitializationWorkAmount());
}
ProjectService.ProjectItemAdded += OnProjectItemAdded;
ProjectService.ProjectItemRemoved += OnProjectItemRemoved;
public void ParseInformationUpdated(IParsedFile oldFile, IParsedFile newFile)
{
// This method is called by the parser service within the parser service lock.
lock (lockObj) {
if (!disposed)
projectContent = projectContent.UpdateProjectContent(oldFile, newFile);
SD.ParserService.InvalidateCurrentSolutionSnapshot();
var parserService = SD.ParserService;
List<FileName> filesToParse = new List<FileName>();
foreach (var file in project.Items.OfType<FileProjectItem>()) {
if (IsParseableFile(file)) {
var fileName = FileName.Create(file.FileName);
parserService.AddOwnerProject(fileName, project, startAsyncParse: false, isLinkedFile: file.IsLink);
filesToParse.Add(fileName);
}
}
SD.ParserService.LoadSolutionProjectsThread.AddJob(
monitor => Initialize(monitor, filesToParse),
"Loading " + project.Name + "...", filesToParse.Count + LoadingReferencesWorkAmount);
}
public void Dispose()
@ -61,10 +67,9 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -61,10 +67,9 @@ namespace ICSharpCode.SharpDevelop.Parser
return;
disposed = true;
}
foreach (var fileName in GetFilesToParse(project.Items)) {
SD.ParserService.RemoveOwnerProject(fileName.Item1, project);
foreach (var parsedFile in projectContent.Files) {
SD.ParserService.RemoveOwnerProject(FileName.Create(parsedFile.FileName), project);
}
initializing = false;
}
public IProjectContent ProjectContent {
@ -75,14 +80,24 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -75,14 +80,24 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
const int LoadingReferencesWorkAmount = 15; // time necessary for loading references, in relation to time for a single C# file
public void ParseInformationUpdated(IParsedFile oldFile, IParsedFile newFile)
{
// This method is called by the parser service within the parser service (per-file) lock.
lock (lockObj) {
if (!disposed)
projectContent = projectContent.UpdateProjectContent(oldFile, newFile);
SD.ParserService.InvalidateCurrentSolutionSnapshot();
}
}
int GetInitializationWorkAmount()
bool IsParseableFile(FileProjectItem projectItem)
{
return project.Items.Count + LoadingReferencesWorkAmount;
if (projectItem == null || string.IsNullOrEmpty(projectItem.FileName))
return false;
return projectItem.ItemType == ItemType.Compile || projectItem.ItemType == ItemType.Page;
}
void Initialize(IProgressMonitor progressMonitor)
void Initialize(IProgressMonitor progressMonitor, List<FileName> filesToParse)
{
ICollection<ProjectItem> projectItems = project.Items;
lock (lockObj) {
@ -90,56 +105,35 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -90,56 +105,35 @@ namespace ICSharpCode.SharpDevelop.Parser
throw new ObjectDisposedException("ParseProjectContent");
}
}
ProjectService.ProjectItemAdded += OnProjectItemAdded;
ProjectService.ProjectItemRemoved += OnProjectItemRemoved;
double scalingFactor = 1.0 / (project.Items.Count + LoadingReferencesWorkAmount);
using (IProgressMonitor initReferencesProgressMonitor = progressMonitor.CreateSubTask(LoadingReferencesWorkAmount * scalingFactor),
parseProgressMonitor = progressMonitor.CreateSubTask(projectItems.Count * scalingFactor))
{
var resolveReferencesTask = ResolveReferencesAsync(projectItems, initReferencesProgressMonitor);
ParseFiles(projectItems, parseProgressMonitor);
ParseFiles(filesToParse, parseProgressMonitor);
resolveReferencesTask.Wait();
}
initializing = false;
}
static readonly ItemType[] compilableItemTypes = { ItemType.Compile, ItemType.Page };
IEnumerable<Tuple<FileName, bool>> GetFilesToParse(IEnumerable<ProjectItem> projectItems)
{
return
from p in projectItems.OfType<FileProjectItem>()
where compilableItemTypes.Contains(p.ItemType) && !String.IsNullOrEmpty(p.FileName)
select Tuple.Create(FileName.Create(p.FileName), p.IsLink);
}
void ParseFiles(ICollection<ProjectItem> projectItems, IProgressMonitor progressMonitor)
void ParseFiles(IReadOnlyList<FileName> filesToParse, IProgressMonitor progressMonitor)
{
ParseableFileContentFinder finder = new ParseableFileContentFinder();
var fileList = GetFilesToParse(projectItems).ToList();
object progressLock = new object();
double fileCountInverse = 1.0 / fileList.Count;
double fileCountInverse = 1.0 / filesToParse.Count;
Parallel.ForEach(
fileList,
filesToParse,
new ParallelOptions {
MaxDegreeOfParallelism = Environment.ProcessorCount,
CancellationToken = progressMonitor.CancellationToken
},
tuple => {
var fileName = tuple.Item1;
// 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 (SD.ParserService.HasParser(fileName)) {
// We don't start an asynchronous parse operation since we want to
// parse on this thread.
SD.ParserService.AddOwnerProject(fileName, project, startAsyncParse: false, isLinkedFile: tuple.Item2);
ITextSource content = finder.Create(fileName);
if (content != null) {
SD.ParserService.ParseFile(fileName, content, project);
}
fileName => {
ITextSource content = finder.Create(fileName);
if (content != null) {
SD.ParserService.ParseFile(fileName, content, project);
}
lock (progressLock) {
progressMonitor.Progress += fileCountInverse;
@ -172,7 +166,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -172,7 +166,7 @@ namespace ICSharpCode.SharpDevelop.Parser
foreach (string file in assemblyFiles) {
progressMonitor.CancellationToken.ThrowIfCancellationRequested();
if (File.Exists(file)) {
var pc = AssemblyParserService.GetAssembly(FileName.Create(file), progressMonitor.CancellationToken);
var pc = SD.AssemblyParserService.GetAssembly(FileName.Create(file), progressMonitor.CancellationToken);
if (pc != null) {
newReferences.Add(pc);
}
@ -232,7 +226,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -232,7 +226,7 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
FileProjectItem fileProjectItem = e.ProjectItem as FileProjectItem;
if (fileProjectItem != null && compilableItemTypes.Contains(fileProjectItem.ItemType)) {
if (IsParseableFile(fileProjectItem)) {
var fileName = FileName.Create(e.ProjectItem.FileName);
SD.ParserService.AddOwnerProject(fileName, project, startAsyncParse: true, isLinkedFile: fileProjectItem.IsLink);
}
@ -256,7 +250,8 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -256,7 +250,8 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
if (e.ProjectItem.ItemType == ItemType.Compile) {
FileProjectItem fileProjectItem = e.ProjectItem as FileProjectItem;
if (IsParseableFile(fileProjectItem)) {
SD.ParserService.RemoveOwnerProject(FileName.Create(e.ProjectItem.FileName), project);
}
}

2
src/Main/Base/Project/Src/Services/RefactoringService/FindReferenceService.cs

@ -68,7 +68,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -68,7 +68,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
if (callback == null)
throw new ArgumentNullException("callback");
SD.MainThread.VerifyAccess();
if (SD.ParserService.LoadSolutionProjectsThreadRunning) {
if (SD.ParserService.LoadSolutionProjectsThread.IsRunning) {
progressMonitor.ShowingDialog = true;
MessageService.ShowMessage("${res:SharpDevelop.Refactoring.LoadSolutionProjectsThreadRunning}");
progressMonitor.ShowingDialog = false;

4
src/Main/Base/Project/Src/Services/SD.cs

@ -93,6 +93,10 @@ namespace ICSharpCode.SharpDevelop @@ -93,6 +93,10 @@ namespace ICSharpCode.SharpDevelop
get { return GetRequiredService<IParserService>(); }
}
public static IAssemblyParserService AssemblyParserService {
get { return GetRequiredService<IAssemblyParserService>(); }
}
public static IFileService FileService {
get { return GetRequiredService<IFileService>(); }
}

5
src/Main/Base/Test/WebReferences/WebReferenceTestHelper.cs

@ -44,11 +44,6 @@ namespace ICSharpCode.SharpDevelop.Tests.WebReferences @@ -44,11 +44,6 @@ namespace ICSharpCode.SharpDevelop.Tests.WebReferences
get { return readOnly; }
}
protected override IProjectContent CreateProjectContent()
{
throw new NotImplementedException();
}
protected override ProjectBehavior CreateDefaultBehavior()
{
return new DotNetStartBehavior(this, null);

33
src/Main/Base/Project/Src/Services/ParserService/AssemblyParserService.cs → src/Main/SharpDevelop/Parser/AssemblyParserService.cs

@ -11,13 +11,13 @@ using System.Runtime.Serialization; @@ -11,13 +11,13 @@ using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop.Project;
using Microsoft.Build.Tasks;
using Mono.Cecil;
namespace ICSharpCode.SharpDevelop.Parser
@ -25,7 +25,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -25,7 +25,7 @@ namespace ICSharpCode.SharpDevelop.Parser
/// <summary>
/// Portions of parser service that deal with loading external assemblies for code completion.
/// </summary>
public static class AssemblyParserService
sealed class AssemblyParserService : IAssemblyParserService
{
#region Get Assembly By File Name
sealed class LoadedAssembly
@ -41,11 +41,11 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -41,11 +41,11 @@ namespace ICSharpCode.SharpDevelop.Parser
}
// TODO: use weak reference to IProjectContent (not to LoadedAssembly!) so that unused assemblies can be unloaded
static Dictionary<FileName, LoadedAssembly> projectContentDictionary = new Dictionary<FileName, LoadedAssembly>();
Dictionary<FileName, LoadedAssembly> projectContentDictionary = new Dictionary<FileName, LoadedAssembly>();
[ThreadStatic] static Dictionary<FileName, LoadedAssembly> up2dateProjectContents;
public static IUnresolvedAssembly GetAssembly(FileName fileName, CancellationToken cancellationToken = default(CancellationToken))
public IUnresolvedAssembly GetAssembly(FileName fileName, CancellationToken cancellationToken = default(CancellationToken))
{
// We currently do not support cancelling the load operation itself, because another GetAssembly() call
// with a different cancellation token might request the same assembly.
@ -58,7 +58,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -58,7 +58,7 @@ namespace ICSharpCode.SharpDevelop.Parser
return asm.ProjectContent.Result;
}
public static Task<IUnresolvedAssembly> GetAssemblyAsync(FileName fileName, CancellationToken cancellationToken = default(CancellationToken))
public Task<IUnresolvedAssembly> GetAssemblyAsync(FileName fileName, CancellationToken cancellationToken = default(CancellationToken))
{
bool isNewTask;
LoadedAssembly asm = GetLoadedAssembly(fileName, out isNewTask);
@ -75,7 +75,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -75,7 +75,7 @@ namespace ICSharpCode.SharpDevelop.Parser
/// This applies only to the thread that called AvoidRedundantChecks() - other threads will
/// perform update checks as usual.
/// </summary>
public static IDisposable AvoidRedundantChecks()
public IDisposable AvoidRedundantChecks()
{
if (up2dateProjectContents != null)
return null;
@ -89,7 +89,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -89,7 +89,7 @@ namespace ICSharpCode.SharpDevelop.Parser
});
}
static void CleanWeakDictionary()
void CleanWeakDictionary()
{
List<FileName> removed = new List<FileName>();
foreach (var pair in projectContentDictionary) {
@ -100,7 +100,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -100,7 +100,7 @@ namespace ICSharpCode.SharpDevelop.Parser
projectContentDictionary.Remove(key);
}
static LoadedAssembly GetLoadedAssembly(FileName fileName, out bool isNewTask)
LoadedAssembly GetLoadedAssembly(FileName fileName, out bool isNewTask)
{
isNewTask = false;
LoadedAssembly asm;
@ -132,7 +132,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -132,7 +132,7 @@ namespace ICSharpCode.SharpDevelop.Parser
#endregion
#region Load Assembly
static IUnresolvedAssembly LoadAssembly(FileName fileName, CancellationToken cancellationToken)
IUnresolvedAssembly LoadAssembly(FileName fileName, CancellationToken cancellationToken)
{
DateTime lastWriteTime = File.GetLastWriteTimeUtc(fileName);
string cacheFileName = GetCacheFileName(fileName);
@ -229,9 +229,9 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -229,9 +229,9 @@ namespace ICSharpCode.SharpDevelop.Parser
/// <summary>
/// Gets/Sets the directory for cached project contents.
/// </summary>
public static string DomPersistencePath { get; set; }
public string DomPersistencePath { get; set; }
static string GetCacheFileName(FileName assemblyFileName)
string GetCacheFileName(FileName assemblyFileName)
{
if (DomPersistencePath == null)
return null;
@ -271,7 +271,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -271,7 +271,7 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
static void SaveToCache(string cacheFileName, DateTime lastWriteTime, IUnresolvedAssembly pc)
void SaveToCache(string cacheFileName, DateTime lastWriteTime, IUnresolvedAssembly pc)
{
if (cacheFileName == null)
return;
@ -323,14 +323,5 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -323,14 +323,5 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
#endregion
internal static string FindReferenceAssembly(string shortName)
{
string path = Path.Combine(referenceAssembliesPath, @".NETFramework\v4.0", shortName + ".dll");
if (File.Exists(path))
return path;
else
return null;
}
}
}

83
src/Main/Base/Project/Src/Services/ParserService/LoadSolutionProjects.cs → src/Main/SharpDevelop/Parser/LoadSolutionProjects.cs

@ -6,6 +6,7 @@ using System.Collections.Concurrent; @@ -6,6 +6,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Windows.Threading;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Gui;
@ -16,35 +17,45 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -16,35 +17,45 @@ namespace ICSharpCode.SharpDevelop.Parser
/// <summary>
/// The background task that initializes the projects in the solution.
/// </summary>
static class LoadSolutionProjects
sealed class LoadSolutionProjects : ILoadSolutionProjectsThread
{
static JobQueue jobs = new JobQueue();
readonly JobQueue jobs;
/// <summary>
/// Gets whether the LoadSolutionProjects thread is currently running.
/// </summary>
public static bool IsThreadRunning {
get {
return jobs.IsThreadRunningOrWaitingToStart;
}
public LoadSolutionProjects()
{
jobs = new JobQueue(this);
}
/// <summary>
/// Occurs when the 'load solution projects' thread has finished.
/// This event is not raised when the 'load solution projects' is aborted because the solution was closed.
/// This event is raised on the main thread.
/// </summary>
public static event EventHandler ThreadEnded = delegate {};
/// <inheritdoc/>
public bool IsRunning { get; private set; }
/// <inheritdoc/>
public event EventHandler Started = delegate {};
/// <inheritdoc/>
public event EventHandler Finished = delegate {};
Stopwatch threadRunningTime;
static void RaiseThreadEnded()
void RaiseThreadStarted()
{
Gui.WorkbenchSingleton.SafeThreadAsyncCall(
threadRunningTime = Stopwatch.StartNew();
SD.MainThread.InvokeAsync(
delegate {
// only raise the event if the thread wasn't re-started
if (!IsThreadRunning) {
ThreadEnded(null, EventArgs.Empty);
}
});
IsRunning = true;
Started(this, EventArgs.Empty);
}).FireAndForget();
}
void RaiseThreadEnded()
{
if (threadRunningTime != null)
LoggingService.Debug("LoadSolutionProjectsThread finished after " + threadRunningTime.Elapsed);
SD.MainThread.InvokeAsync(
delegate {
IsRunning = false;
Finished(this, EventArgs.Empty);
}).FireAndForget();
}
static string GetLoadReferenceTaskTitle(string projectName)
@ -63,7 +74,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -63,7 +74,7 @@ namespace ICSharpCode.SharpDevelop.Parser
/// <param name="action">The action to run. Parameter: a nested progress monitor for the action.</param>
/// <param name="name">Name of the action - shown in the status bar</param>
/// <param name="cost">Cost of the action</param>
public static void AddJob(Action<IProgressMonitor> action, string name, double cost)
public void AddJob(Action<IProgressMonitor> action, string name, double cost)
{
if (action == null)
throw new ArgumentNullException("action");
@ -73,18 +84,17 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -73,18 +84,17 @@ namespace ICSharpCode.SharpDevelop.Parser
jobs.AddJob(new JobTask(action, name, cost));
// Start the thread with a bit delay so that the SD UI gets responsive first,
// and so that the total cost is known for showing the progress bar.
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Background,
new Action(jobs.StartRunningIfRequired));
SD.MainThread.InvokeAsync(jobs.StartRunningIfRequired, DispatcherPriority.Background).FireAndForget();
}
public static void CancelAllJobs()
public void CancelAllJobs()
{
jobs.Clear();
}
sealed class JobQueue
{
readonly LoadSolutionProjects loadSolutionProjects;
readonly object lockObj = new object();
readonly Queue<JobTask> actions = new Queue<JobTask>();
CancellationTokenSource cancellationSource = new CancellationTokenSource();
@ -93,13 +103,21 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -93,13 +103,21 @@ namespace ICSharpCode.SharpDevelop.Parser
double totalWork;
double workDone;
public JobQueue(LoadSolutionProjects loadSolutionProjects)
{
this.loadSolutionProjects = loadSolutionProjects;
}
public void AddJob(JobTask task)
{
if (task == null)
throw new ArgumentNullException("task");
lock (lockObj) {
bool wasRunning = this.threadIsRunning || this.actions.Count > 0;
this.totalWork += task.cost;
this.actions.Enqueue(task);
if (!wasRunning)
loadSolutionProjects.RaiseThreadStarted();
}
}
@ -117,12 +135,11 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -117,12 +135,11 @@ namespace ICSharpCode.SharpDevelop.Parser
if (!this.threadIsRunning && this.actions.Count > 0) {
this.threadIsRunning = true;
progressMonitor = WorkbenchSingleton.StatusBar.CreateProgressMonitor(cancellationSource.Token);
progressMonitor = SD.StatusBar.CreateProgressMonitor(cancellationSource.Token);
progressMonitor.TaskName = this.actions.Peek().name;
Thread thread = new Thread(new ThreadStart(RunThread));
thread.Name = "LoadSolutionProjects";
thread.Priority = ThreadPriority.BelowNormal;
thread.IsBackground = true;
thread.Start();
}
@ -146,9 +163,13 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -146,9 +163,13 @@ namespace ICSharpCode.SharpDevelop.Parser
// restart if necessary:
if (actions.Count > 0) {
actions.Dequeue(); // dequeue the null
WorkbenchSingleton.SafeThreadAsyncCall(StartRunningIfRequired);
if (actions.Count > 0)
WorkbenchSingleton.SafeThreadAsyncCall(StartRunningIfRequired);
else
loadSolutionProjects.RaiseThreadEnded();
} else {
loadSolutionProjects.RaiseThreadEnded();
}
RaiseThreadEnded();
return;
}
task = this.actions.Dequeue();

21
src/Main/SharpDevelop/Parser/ParserService.cs

@ -31,8 +31,11 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -31,8 +31,11 @@ namespace ICSharpCode.SharpDevelop.Parser
public ParserService()
{
parserDescriptors = AddInTree.BuildItems<ParserDescriptor>("/Workspace/Parser", null, false);
this.LoadSolutionProjectsThread = new LoadSolutionProjects();
}
public ILoadSolutionProjectsThread LoadSolutionProjectsThread { get; private set; }
#region ParseInformationUpdated
public event EventHandler<ParseInformationEventArgs> ParseInformationUpdated = delegate {};
@ -42,14 +45,16 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -42,14 +45,16 @@ namespace ICSharpCode.SharpDevelop.Parser
// To ensure events are raised in the same order, we always invoke on the main thread.
WorkbenchSingleton.SafeThreadAsyncCall(
delegate {
string addition;
if (e.OldParsedFile == null)
addition = " (new)";
else if (e.NewParsedFile == null)
addition = " (removed)";
else
addition = " (updated)";
LoggingService.Debug("ParseInformationUpdated " + e.FileName + addition);
if (!LoadSolutionProjectsThread.IsRunning) {
string addition;
if (e.OldParsedFile == null)
addition = " (new)";
else if (e.NewParsedFile == null)
addition = " (removed)";
else
addition = " (updated)";
LoggingService.Debug("ParseInformationUpdated " + e.FileName + addition);
}
ParseInformationUpdated(null, e);
});
}

3
src/Main/SharpDevelop/Sda/CallHelper.cs

@ -55,7 +55,6 @@ namespace ICSharpCode.SharpDevelop.Sda @@ -55,7 +55,6 @@ namespace ICSharpCode.SharpDevelop.Sda
if (properties.PropertiesName != null) {
startup.PropertiesName = properties.PropertiesName;
}
AssemblyParserService.DomPersistencePath = properties.DomPersistencePath;
if (properties.ApplicationRootPath != null) {
FileUtility.ApplicationRootPath = properties.ApplicationRootPath;
@ -90,6 +89,8 @@ namespace ICSharpCode.SharpDevelop.Sda @@ -90,6 +89,8 @@ namespace ICSharpCode.SharpDevelop.Sda
LoggingService.Info("Loading AddInTree...");
startup.RunInitialization();
((AssemblyParserService)SD.AssemblyParserService).DomPersistencePath = properties.DomPersistencePath;
// Register events to marshal back
Project.ProjectService.BuildStarted += delegate { this.callback.StartBuild(); };
Project.ProjectService.BuildFinished += delegate { this.callback.EndBuild(); };

6
src/Main/SharpDevelop/SharpDevelop.csproj

@ -81,6 +81,8 @@ @@ -81,6 +81,8 @@
<DependentUpon>LoadSaveOptions.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Parser\AssemblyParserService.cs" />
<Compile Include="Parser\LoadSolutionProjects.cs" />
<Compile Include="Startup\App.xaml.cs" />
<Compile Include="Startup\SharpDevelopMain.cs" />
<Compile Include="Startup\SplashScreen.cs" />
@ -144,6 +146,10 @@ @@ -144,6 +146,10 @@
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project>
<Name>ICSharpCode.AvalonEdit</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\Mono.Cecil\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\NRefactory\ICSharpCode.NRefactory.CSharp\ICSharpCode.NRefactory.CSharp.csproj">
<Project>{53DCA265-3C3C-42F9-B647-F72BA678122B}</Project>
<Name>ICSharpCode.NRefactory.CSharp</Name>

Loading…
Cancel
Save