Browse Source

Implement "Refresh reference"

pull/59/merge
Daniel Grunwald 12 years ago
parent
commit
a46af4b4e4
  1. 43
      src/Main/Base/Project/Parser/IAssemblyParserService.cs
  2. 27
      src/Main/Base/Project/Parser/ProjectContentContainer.cs
  3. 4
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs
  4. 22
      src/Main/SharpDevelop/Parser/AssemblyParserService.cs

43
src/Main/Base/Project/Parser/IAssemblyParserService.cs

@ -41,5 +41,48 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -41,5 +41,48 @@ namespace ICSharpCode.SharpDevelop.Parser
/// May return <c>null</c> if on-disk caching is disabled.
/// </summary>
string DomPersistencePath { get; }
/// <summary>
/// Refreshes the specified assembly.
/// Raises the <see cref="AssemblyRefreshed"/> event if the assembly has changed since it was originally loaded.
/// </summary>
/// <remarks>This method has no effect is the specified file is not a loaded assembly.</remarks>
void RefreshAssembly(FileName fileName);
event EventHandler<RefreshAssemblyEventArgs> AssemblyRefreshed;
}
public class RefreshAssemblyEventArgs : EventArgs
{
readonly FileName fileName;
readonly IUnresolvedAssembly oldAssembly;
readonly IUnresolvedAssembly newAssembly;
public RefreshAssemblyEventArgs(FileName fileName, IUnresolvedAssembly oldAssembly, IUnresolvedAssembly newAssembly)
{
if (fileName == null)
throw new ArgumentNullException("fileName");
this.fileName = fileName;
this.oldAssembly = oldAssembly;
this.newAssembly = newAssembly;
}
public FileName FileName {
get {
return fileName;
}
}
public IUnresolvedAssembly OldAssembly {
get {
return oldAssembly;
}
}
public IUnresolvedAssembly NewAssembly {
get {
return newAssembly;
}
}
}
}

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

@ -9,6 +9,7 @@ using System.Runtime.Serialization; @@ -9,6 +9,7 @@ using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@ -44,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -44,7 +45,7 @@ namespace ICSharpCode.SharpDevelop.Parser
// time necessary for loading references, in relation to time for a single C# file
const int LoadingReferencesWorkAmount = 15;
string cacheFileName;
readonly string cacheFileName;
#region Constructor + Dispose
public ProjectContentContainer(MSBuildBasedProject project, IProjectContent initialProjectContent)
@ -58,8 +59,8 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -58,8 +59,8 @@ namespace ICSharpCode.SharpDevelop.Parser
SD.ProjectService.ProjectItemAdded += OnProjectItemAdded;
SD.ProjectService.ProjectItemRemoved += OnProjectItemRemoved;
SD.AssemblyParserService.AssemblyRefreshed += OnAssemblyRefreshed;
var parserService = SD.ParserService;
List<FileName> filesToParse = new List<FileName>();
foreach (var file in project.Items.OfType<FileProjectItem>()) {
if (IsParseableFile(file)) {
@ -78,6 +79,8 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -78,6 +79,8 @@ namespace ICSharpCode.SharpDevelop.Parser
{
SD.ProjectService.ProjectItemAdded -= OnProjectItemAdded;
SD.ProjectService.ProjectItemRemoved -= OnProjectItemRemoved;
SD.AssemblyParserService.AssemblyRefreshed -= OnAssemblyRefreshed;
IProjectContent pc;
bool serializeOnDispose;
lock (lockObj) {
@ -313,7 +316,6 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -313,7 +316,6 @@ namespace ICSharpCode.SharpDevelop.Parser
void ParseFiles(List<FileName> filesToParse, IProgressMonitor progressMonitor)
{
IParserService parserService = SD.ParserService;
IProjectContent cachedPC = TryReadFromCache(cacheFileName);
ParseableFileContentFinder finder = new ParseableFileContentFinder();
@ -391,7 +393,6 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -391,7 +393,6 @@ namespace ICSharpCode.SharpDevelop.Parser
void DoReparseCode(List<FileName> filesToParse, IProgressMonitor progressMonitor)
{
IParserService parserService = SD.ParserService;
ParseableFileContentFinder finder = new ParseableFileContentFinder();
double fileCountInverse = 1.0 / filesToParse.Count;
object progressLock = new object();
@ -424,7 +425,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -424,7 +425,7 @@ namespace ICSharpCode.SharpDevelop.Parser
progressMonitor.Progress += assemblyResolvingProgress;
progressMonitor.CancellationToken.ThrowIfCancellationRequested();
List<string> assemblyFiles = new List<string>();
List<FileName> assemblyFiles = new List<FileName>();
List<IAssemblyReference> newReferences = new List<IAssemblyReference>();
foreach (var reference in referenceItems) {
@ -436,10 +437,10 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -436,10 +437,10 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
foreach (string file in assemblyFiles) {
foreach (var file in assemblyFiles) {
progressMonitor.CancellationToken.ThrowIfCancellationRequested();
if (File.Exists(file)) {
var pc = SD.AssemblyParserService.GetAssembly(FileName.Create(file), progressMonitor.CancellationToken);
var pc = SD.AssemblyParserService.GetAssembly(file, progressMonitor.CancellationToken);
if (pc != null) {
newReferences.Add(pc);
}
@ -468,6 +469,18 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -468,6 +469,18 @@ namespace ICSharpCode.SharpDevelop.Parser
"Loading " + project.Name + "...", LoadingReferencesWorkAmount);
}
}
void OnAssemblyRefreshed(object sender, RefreshAssemblyEventArgs e)
{
lock (lockObj) {
int index = Array.IndexOf(this.references, e.OldAssembly);
if (index >= 0 && e.NewAssembly != null) {
this.references[index] = e.NewAssembly;
projectContent = projectContent.RemoveAssemblyReferences(e.OldAssembly).AddAssemblyReferences(e.NewAssembly);
SD.ParserService.InvalidateCurrentSolutionSnapshot();
}
}
}
#endregion
#region Project Item Added/Removed

4
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs

@ -226,9 +226,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -226,9 +226,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
if (node != null) {
ReferenceProjectItem item = node.ReferenceProjectItem;
if (item != null) {
#warning Reimplement RefreshReference
throw new NotImplementedException();
//AssemblyParserService.RefreshProjectContentForReference(item);
SD.AssemblyParserService.RefreshAssembly(item.FileName);
}
}
}

22
src/Main/SharpDevelop/Parser/AssemblyParserService.cs

@ -305,5 +305,27 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -305,5 +305,27 @@ namespace ICSharpCode.SharpDevelop.Parser
}
}
#endregion
#region Refresh
public event EventHandler<RefreshAssemblyEventArgs> AssemblyRefreshed;
public void RefreshAssembly(FileName fileName)
{
LoadedAssembly asm;
lock (projectContentDictionary) {
if (!projectContentDictionary.TryGetValue(fileName, out asm)) {
// Assembly is not loaded; nothing to refresh
return;
}
}
var oldAssembly = asm.ProjectContent.Result;
var newAssembly = GetAssembly(fileName);
if (oldAssembly != newAssembly) {
var handler = AssemblyRefreshed;
if (handler != null)
handler(this, new RefreshAssemblyEventArgs(fileName, oldAssembly, newAssembly));
}
}
#endregion
}
}

Loading…
Cancel
Save