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

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

@ -327,7 +327,7 @@ namespace ICSharpCode.SharpDevelop.Project
#region Type System #region Type System
volatile ProjectContentContainer projectContentContainer; volatile ProjectContentContainer projectContentContainer;
IAssemblyModel assemblyModel; IUpdateableAssemblyModel assemblyModel;
protected void InitializeProjectContent(IProjectContent initialProjectContent) protected void InitializeProjectContent(IProjectContent initialProjectContent)
{ {
@ -354,45 +354,13 @@ namespace ICSharpCode.SharpDevelop.Project
public override IAssemblyModel AssemblyModel { public override IAssemblyModel AssemblyModel {
get { get {
SD.MainThread.VerifyAccess(); SD.MainThread.VerifyAccess();
var pc = ProjectContent;
if (assemblyModel == null) { if (assemblyModel == null) {
assemblyModel = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(new ProjectEntityModelContext(this, ".cs")); 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; 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) public override void OnParseInformationUpdated(ParseInformationEventArgs args)
{ {
var c = projectContentContainer; var c = projectContentContainer;
@ -400,12 +368,7 @@ namespace ICSharpCode.SharpDevelop.Project
c.ParseInformationUpdated(args.OldUnresolvedFile, args.NewUnresolvedFile); c.ParseInformationUpdated(args.OldUnresolvedFile, args.NewUnresolvedFile);
// OnParseInformationUpdated is called inside a lock, but we don't want to raise the event inside that lock. // 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. // To ensure events are raised in the same order, we always invoke on the main thread.
SD.MainThread.InvokeAsyncAndForget(delegate { SD.MainThread.InvokeAsyncAndForget(delegate { ParseInformationUpdated(null, args); });
if (assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).Update(args.OldUnresolvedFile, args.NewUnresolvedFile);
}
ParseInformationUpdated(null, args);
});
} }
public override event EventHandler<ParseInformationEventArgs> ParseInformationUpdated = delegate {}; public override event EventHandler<ParseInformationEventArgs> ParseInformationUpdated = delegate {};

Loading…
Cancel
Save