Browse Source

Updates of CompilableProject.AssemblyModel should be handled by ProjectContentContainer to reduce performance impact

pull/80/head
Siegfried Pammer 12 years ago
parent
commit
a881e8d555
  1. 32
      src/Main/Base/Project/Parser/ProjectContentContainer.cs
  2. 41
      src/Main/Base/Project/Src/Project/CompilableProject.cs

32
src/Main/Base/Project/Parser/ProjectContentContainer.cs

@ -14,6 +14,7 @@ using ICSharpCode.NRefactory.Editor; @@ -14,6 +14,7 @@ using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
@ -23,6 +24,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -23,6 +24,7 @@ namespace ICSharpCode.SharpDevelop.Parser
{
readonly IProject project;
readonly IParserService parserService = SD.ParserService;
readonly IUpdateableAssemblyModel assemblyModel;
/// <summary>
/// Lock for accessing mutable fields of this class.
@ -54,7 +56,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -54,7 +56,7 @@ namespace ICSharpCode.SharpDevelop.Parser
throw new ArgumentNullException("project");
this.project = project;
this.projectContent = initialProjectContent.SetAssemblyName(project.AssemblyName).SetLocation(project.OutputAssemblyFullPath);
this.assemblyModel = (IUpdateableAssemblyModel)project.AssemblyModel;
this.cacheFileName = GetCacheFileName(project.FileName);
SD.ProjectService.ProjectItemAdded += OnProjectItemAdded;
@ -242,6 +244,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -242,6 +244,7 @@ namespace ICSharpCode.SharpDevelop.Parser
projectContent = projectContent.RemoveFiles(oldFile.FileName);
serializedProjectContentIsUpToDate = false;
SD.ParserService.InvalidateCurrentSolutionSnapshot();
SD.MainThread.InvokeAsyncAndForget(delegate { assemblyModel.Update(oldFile, newFile); });
}
}
}
@ -253,6 +256,8 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -253,6 +256,8 @@ namespace ICSharpCode.SharpDevelop.Parser
if (projectContent.FullAssemblyName == newAssemblyName)
return;
projectContent = projectContent.SetAssemblyName(newAssemblyName);
assemblyModel.AssemblyName = projectContent.AssemblyName;
assemblyModel.FullAssemblyName = projectContent.FullAssemblyName;
SD.ParserService.InvalidateCurrentSolutionSnapshot();
}
}
@ -361,6 +366,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -361,6 +366,7 @@ namespace ICSharpCode.SharpDevelop.Parser
if (IsSerializable(unresolvedFile))
fileCountParsedAndSerializable++;
}
SD.MainThread.InvokeAsyncAndForget(delegate { assemblyModel.Update(null, unresolvedFile); });
progressMonitor.Progress += fileCountInverse;
}
});
@ -452,6 +458,8 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -452,6 +458,8 @@ namespace ICSharpCode.SharpDevelop.Parser
projectContent = projectContent.RemoveAssemblyReferences(this.references).AddAssemblyReferences(newReferences);
this.references = newReferences.ToArray();
SD.ParserService.InvalidateCurrentSolutionSnapshot();
assemblyModel.References = projectContent.AssemblyReferences
.Select(ResolveReferenceForAssemblyModel).Where(r => r != null).ToList();
}
}
}
@ -478,8 +486,26 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -478,8 +486,26 @@ namespace ICSharpCode.SharpDevelop.Parser
this.references[index] = e.NewAssembly;
projectContent = projectContent.RemoveAssemblyReferences(e.OldAssembly).AddAssemblyReferences(e.NewAssembly);
SD.ParserService.InvalidateCurrentSolutionSnapshot();
assemblyModel.References = projectContent.AssemblyReferences
.Select(ResolveReferenceForAssemblyModel).Where(r => r != null).ToList();
}
}
}
DomAssemblyName ResolveReferenceForAssemblyModel(IAssemblyReference reference)
{
if (reference is IUnresolvedAssembly)
return new DomAssemblyName(((IUnresolvedAssembly)reference).FullAssemblyName);
if (reference is ProjectReferenceProjectItem) {
var project = ((ProjectReferenceProjectItem)reference).ReferencedProject;
if (project == null) return null;
if (project.ProjectContent == null) {
SD.Log.InfoFormatted("ResolveReference: ProjectContent for project '{0}', language {1} was not found. Cannot resolve reference!", project.Name, project.Language);
return null;
}
return new DomAssemblyName(project.ProjectContent.FullAssemblyName);
}
return null;
}
#endregion
@ -518,5 +544,9 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -518,5 +544,9 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
#endregion
public IAssemblyModel AssembyModel {
get { return assemblyModel; }
}
}
}

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

@ -327,7 +327,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -327,7 +327,7 @@ namespace ICSharpCode.SharpDevelop.Project
#region Type System
volatile ProjectContentContainer projectContentContainer;
IAssemblyModel assemblyModel;
IUpdateableAssemblyModel assemblyModel;
protected void InitializeProjectContent(IProjectContent initialProjectContent)
{
@ -354,45 +354,13 @@ namespace ICSharpCode.SharpDevelop.Project @@ -354,45 +354,13 @@ namespace ICSharpCode.SharpDevelop.Project
public override IAssemblyModel AssemblyModel {
get {
SD.MainThread.VerifyAccess();
var pc = ProjectContent;
if (assemblyModel == null) {
assemblyModel = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(new ProjectEntityModelContext(this, ".cs"));
if (pc != null && assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).AssemblyName = AssemblyName;
((IUpdateableAssemblyModel)assemblyModel).FullAssemblyName = ProjectContent.FullAssemblyName;
// Add the already loaded files into the model
foreach (var file in pc.Files) {
((IUpdateableAssemblyModel)assemblyModel).Update(null, file);
}
}
}
// Update references on every access
if (pc != null && assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).References = pc.AssemblyReferences
.Select(ResolveReference).Where(r => r != null).ToList();
}
return assemblyModel;
}
}
DomAssemblyName ResolveReference(IAssemblyReference reference)
{
if (reference is IUnresolvedAssembly)
return new DomAssemblyName(((IUnresolvedAssembly)reference).FullAssemblyName);
if (reference is ProjectReferenceProjectItem) {
var project = ((ProjectReferenceProjectItem)reference).ReferencedProject;
if (project == null) return null;
if (project.ProjectContent == null) {
SD.Log.InfoFormatted("ResolveReference: ProjectContent for project '{0}', language {1} was not found. Cannot resolve reference!", project.Name, project.Language);
return null;
}
return new DomAssemblyName(project.ProjectContent.FullAssemblyName);
}
return null;
}
public override void OnParseInformationUpdated(ParseInformationEventArgs args)
{
var c = projectContentContainer;
@ -400,12 +368,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -400,12 +368,7 @@ namespace ICSharpCode.SharpDevelop.Project
c.ParseInformationUpdated(args.OldUnresolvedFile, args.NewUnresolvedFile);
// 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.InvokeAsyncAndForget(delegate {
if (assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).Update(args.OldUnresolvedFile, args.NewUnresolvedFile);
}
ParseInformationUpdated(null, args);
});
SD.MainThread.InvokeAsyncAndForget(delegate { ParseInformationUpdated(null, args); });
}
public override event EventHandler<ParseInformationEventArgs> ParseInformationUpdated = delegate {};

Loading…
Cancel
Save