Browse Source

add support for Assembly References to IAssemblyModel

newNRILSpyDebugger
Siegfried Pammer 12 years ago
parent
commit
0f47b3c711
  1. 22
      src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs
  2. 21
      src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs
  3. 8
      src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs
  4. 12
      src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs
  5. 13
      src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs
  6. 5
      src/Main/Base/Project/Dom/IAssemblyModel.cs
  7. 27
      src/Main/Base/Project/Dom/ModelFactoryExtensions.cs
  8. 2
      src/Main/Base/Project/Parser/ProjectContentContainer.cs
  9. 15
      src/Main/Base/Project/Src/Project/CompilableProject.cs
  10. 5
      src/Main/SharpDevelop/Dom/AssemblyModel.cs
  11. 15
      src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs

22
src/AddIns/Debugger/Debugger.AddIn/Pads/ClassBrowserSupport.cs

@ -10,6 +10,7 @@ using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.ClassBrowser; using ICSharpCode.SharpDevelop.Dom.ClassBrowser;
using System.Linq; using System.Linq;
using ICSharpCode.SharpDevelop.Parser;
namespace ICSharpCode.SharpDevelop.Gui.Pads namespace ICSharpCode.SharpDevelop.Gui.Pads
{ {
@ -81,6 +82,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
DebuggerModuleModel model = new DebuggerModuleModel(e.Module); DebuggerModuleModel model = new DebuggerModuleModel(e.Module);
moduleModels.Add(model); moduleModels.Add(model);
Assemblies.Add(model.AssemblyModel); Assemblies.Add(model.AssemblyModel);
foreach (var module in moduleModels)
module.UpdateReferences();
} }
void ModuleUnloaded(object sender, ModuleEventArgs e) void ModuleUnloaded(object sender, ModuleEventArgs e)
@ -89,6 +92,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
if (deletedModel != null) { if (deletedModel != null) {
moduleModels.Remove(deletedModel); moduleModels.Remove(deletedModel);
Assemblies.Remove(deletedModel.AssemblyModel); Assemblies.Remove(deletedModel.AssemblyModel);
foreach (var module in moduleModels)
module.UpdateReferences();
} }
} }
@ -181,14 +186,23 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
} }
} }
public void UpdateReferences()
{
var model = assemblyModel as IUpdateableAssemblyModel;
if (model == null) return;
// this could be totally wrong ...
model.References = module.AppDomain.Compilation.Assemblies.Where(a => a.FullAssemblyName != module.UnresolvedAssembly.FullAssemblyName).Select(a => new DomAssemblyName(a.FullAssemblyName)).ToList();
}
static IAssemblyModel CreateAssemblyModel(Module module) static IAssemblyModel CreateAssemblyModel(Module module)
{ {
// references?? // references??
IEntityModelContext context = new AssemblyEntityModelContext(module.Assembly.UnresolvedAssembly); IEntityModelContext context = new AssemblyEntityModelContext(module.Assembly.UnresolvedAssembly);
IAssemblyModel model = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(context); IUpdateableAssemblyModel model = SD.GetRequiredService<IModelFactory>().CreateAssemblyModel(context);
if (model is IUpdateableAssemblyModel) { var types = module.Assembly.TopLevelTypeDefinitions.SelectMany(td => td.Parts).ToList();
((IUpdateableAssemblyModel)model).Update(EmptyList<IUnresolvedTypeDefinition>.Instance, module.Assembly.TopLevelTypeDefinitions.SelectMany(td => td.Parts).ToList()); model.AssemblyName = module.UnresolvedAssembly.AssemblyName;
} model.Update(EmptyList<IUnresolvedTypeDefinition>.Instance, types);
return model; return model;
} }
} }

21
src/Main/Base/Project/Dom/ClassBrowser/ClassBrowserTreeView.cs

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Controls; using System.Windows.Controls;
using ICSharpCode.Core;
using ICSharpCode.TreeView; using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
@ -11,14 +12,21 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public class ClassBrowserTreeView : SharpTreeView, IClassBrowserTreeView public class ClassBrowserTreeView : SharpTreeView, IClassBrowserTreeView
{ {
#region IClassBrowser implementation #region IClassBrowser implementation
WorkspaceModel workspace;
public ICollection<IAssemblyList> AssemblyLists { public ICollection<IAssemblyList> AssemblyLists {
get { return ((WorkspaceTreeNode)Root).AssemblyLists; } get { return workspace.AssemblyLists; }
} }
public IAssemblyList MainAssemblyList { public IAssemblyList MainAssemblyList {
get { return ((WorkspaceTreeNode)Root).AssemblyList; } get { return workspace.MainAssemblyList; }
set { ((WorkspaceTreeNode)Root).AssemblyList = value; } set { workspace.MainAssemblyList = value; }
}
public IAssemblyModel FindAssemblyModel(FileName fileName)
{
return workspace.FindAssemblyModel(fileName);
} }
#endregion #endregion
@ -26,12 +34,13 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public ClassBrowserTreeView() public ClassBrowserTreeView()
{ {
WorkspaceTreeNode root = new WorkspaceTreeNode(); WorkspaceTreeNode root = new WorkspaceTreeNode();
this.workspace = root.Workspace;
ClassBrowserTreeView instance = this; ClassBrowserTreeView instance = this;
root.AssemblyLists.CollectionChanged += delegate { root.Workspace.AssemblyLists.CollectionChanged += delegate {
instance.ShowRoot = root.AssemblyLists.Count > 0; instance.ShowRoot = root.Workspace.AssemblyLists.Count > 0;
}; };
root.PropertyChanged += delegate { root.PropertyChanged += delegate {
instance.ShowRoot = root.AssemblyLists.Count > 0; instance.ShowRoot = root.Workspace.AssemblyLists.Count > 0;
}; };
this.Root = root; this.Root = root;
} }

8
src/Main/Base/Project/Dom/ClassBrowser/IClassBrowser.cs

@ -3,7 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ICSharpCode.TreeView; using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{ {
@ -11,10 +11,6 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{ {
IAssemblyList MainAssemblyList { get; set; } IAssemblyList MainAssemblyList { get; set; }
ICollection<IAssemblyList> AssemblyLists { get; } ICollection<IAssemblyList> AssemblyLists { get; }
IAssemblyModel FindAssemblyModel(FileName fileName);
/*
IAssemblyList MainAssemblyList { get; set; }
ICollection<IAssemblyList> AssemblyLists { get; }
*/
} }
} }

12
src/Main/Base/Project/Dom/ClassBrowser/WorkspaceModel.cs

@ -3,7 +3,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using ICSharpCode.Core;
using ICSharpCode.TreeView; using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
@ -41,6 +43,16 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
} }
} }
public IAssemblyModel FindAssemblyModel(FileName fileName)
{
foreach (var list in assemblyLists) {
var model = list.Assemblies.FirstOrDefault(m => m.Location == fileName);
if (model != null)
return model;
}
return mainAssemblyList.Assemblies.FirstOrDefault(m => m.Location == fileName);
}
public WorkspaceModel() public WorkspaceModel()
{ {
this.assemblyLists = new SimpleModelCollection<IAssemblyList>(); this.assemblyLists = new SimpleModelCollection<IAssemblyList>();

13
src/Main/Base/Project/Dom/ClassBrowser/WorkspaceTreeNode.cs

@ -36,16 +36,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
} }
WorkspaceModel workspace; WorkspaceModel workspace;
protected static readonly IComparer<SharpTreeNode> ChildNodeComparer = new WorkspaceChildComparer(); public WorkspaceModel Workspace {
get { return workspace; }
public IMutableModelCollection<IAssemblyList> AssemblyLists {
get { return workspace.AssemblyLists; }
} }
public IAssemblyList AssemblyList { protected static readonly IComparer<SharpTreeNode> ChildNodeComparer = new WorkspaceChildComparer();
get { return workspace.MainAssemblyList; }
set { workspace.MainAssemblyList = value; }
}
public WorkspaceTreeNode() public WorkspaceTreeNode()
{ {
@ -68,7 +63,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public override object Text { public override object Text {
get { get {
return String.Format(SD.ResourceService.GetString("MainWindow.Windows.ClassBrowser.Workspace"), AssemblyList.Name); return String.Format(SD.ResourceService.GetString("MainWindow.Windows.ClassBrowser.Workspace"), Workspace.MainAssemblyList.Name);
} }
} }

5
src/Main/Base/Project/Dom/IAssemblyModel.cs

@ -85,6 +85,11 @@ namespace ICSharpCode.SharpDevelop.Dom
/// Gets the assembly name (short name). /// Gets the assembly name (short name).
/// </summary> /// </summary>
new string AssemblyName { get; set; } new string AssemblyName { get; set; }
/// <summary>
/// Returns the assembly references.
/// </summary>
new IReadOnlyList<DomAssemblyName> References { get; set; }
} }
public sealed class EmptyAssemblyModel : IAssemblyModel public sealed class EmptyAssemblyModel : IAssemblyModel

27
src/Main/Base/Project/Dom/ModelFactoryExtensions.cs

@ -4,35 +4,16 @@
using System; using System;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using ICSharpCode.Core;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using Mono.Cecil;
using ICSharpCode.SharpDevelop.Parser;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
public static class ModelFactoryExtensions public static class ModelFactoryExtensions
{ {
/// <summary>
/// Creates an <see cref="ICSharpCode.SharpDevelop.Dom.IAssemblyModel"/> from a file name.
/// </summary>
/// <param name="modelFactory">Model factory.</param>
/// <param name="fileName">Assembly file name.</param>
/// <returns>Created <see cref="ICSharpCode.SharpDevelop.Dom.IAssemblyModel"/>.</returns>
public static IAssemblyModel CreateAssemblyModelFromFile(this IModelFactory modelFactory, string fileName)
{
var loader = new CecilLoader();
loader.IncludeInternalMembers = true;
loader.LazyLoad = true;
var assembly = loader.LoadAssemblyFile(fileName);
IEntityModelContext context = new AssemblyEntityModelContext(assembly);
IAssemblyModel model = modelFactory.CreateAssemblyModel(context);
if (model is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)model).Update(EmptyList<IUnresolvedTypeDefinition>.Instance, assembly.TopLevelTypeDefinitions.ToList());
((IUpdateableAssemblyModel) model).AssemblyName = assembly.AssemblyName;
}
return model;
}
/// <summary> /// <summary>
/// Creates an <see cref="ICSharpCode.SharpDevelop.Dom.IAssemblyModel"/> from a file name and catches /// Creates an <see cref="ICSharpCode.SharpDevelop.Dom.IAssemblyModel"/> from a file name and catches
/// errors by showing messages to user. /// errors by showing messages to user.
@ -46,7 +27,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public static IAssemblyModel SafelyCreateAssemblyModelFromFile(this IModelFactory modelFactory, string fileName) public static IAssemblyModel SafelyCreateAssemblyModelFromFile(this IModelFactory modelFactory, string fileName)
{ {
try { try {
return modelFactory.CreateAssemblyModelFromFile(fileName); return SD.AssemblyParserService.GetAssemblyModel(new FileName(fileName), true, modelFactory);
} catch (BadImageFormatException) { } catch (BadImageFormatException) {
SD.MessageService.ShowWarningFormatted("${res:ICSharpCode.SharpDevelop.Dom.AssemblyInvalid}", Path.GetFileName(fileName)); SD.MessageService.ShowWarningFormatted("${res:ICSharpCode.SharpDevelop.Dom.AssemblyInvalid}", Path.GetFileName(fileName));
} catch (FileNotFoundException) { } catch (FileNotFoundException) {

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

@ -439,7 +439,7 @@ namespace ICSharpCode.SharpDevelop.Parser
foreach (string file in assemblyFiles) { foreach (string file in assemblyFiles) {
progressMonitor.CancellationToken.ThrowIfCancellationRequested(); progressMonitor.CancellationToken.ThrowIfCancellationRequested();
if (File.Exists(file)) { if (File.Exists(file)) {
var pc = SD.AssemblyParserService.GetAssembly(FileName.Create(file), progressMonitor.CancellationToken); var pc = SD.AssemblyParserService.GetAssembly(FileName.Create(file), false, progressMonitor.CancellationToken);
if (pc != null) { if (pc != null) {
newReferences.Add(pc); newReferences.Add(pc);
} }

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

@ -359,6 +359,8 @@ namespace ICSharpCode.SharpDevelop.Project
var pc = ProjectContent; var pc = ProjectContent;
if (pc != null && assemblyModel is IUpdateableAssemblyModel) { if (pc != null && assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).AssemblyName = AssemblyName; ((IUpdateableAssemblyModel)assemblyModel).AssemblyName = AssemblyName;
((IUpdateableAssemblyModel)assemblyModel).References = pc.AssemblyReferences
.Select(ResolveReference).Where(r => r != null).ToList();
// Add the already loaded files into the model // Add the already loaded files into the model
foreach (var file in pc.Files) { foreach (var file in pc.Files) {
((IUpdateableAssemblyModel)assemblyModel).Update(null, file); ((IUpdateableAssemblyModel)assemblyModel).Update(null, file);
@ -369,6 +371,18 @@ namespace ICSharpCode.SharpDevelop.Project
} }
} }
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;
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;
@ -379,6 +393,7 @@ namespace ICSharpCode.SharpDevelop.Project
SD.MainThread.InvokeAsyncAndForget(delegate { SD.MainThread.InvokeAsyncAndForget(delegate {
if (assemblyModel is IUpdateableAssemblyModel) { if (assemblyModel is IUpdateableAssemblyModel) {
((IUpdateableAssemblyModel)assemblyModel).Update(args.OldUnresolvedFile, args.NewUnresolvedFile); ((IUpdateableAssemblyModel)assemblyModel).Update(args.OldUnresolvedFile, args.NewUnresolvedFile);
// TODO : update references as well?
} }
ParseInformationUpdated(null, args); ParseInformationUpdated(null, args);
}); });

5
src/Main/SharpDevelop/Dom/AssemblyModel.cs

@ -19,12 +19,14 @@ namespace ICSharpCode.SharpDevelop.Dom
TopLevelTypeDefinitionModelCollection typeDeclarations; TopLevelTypeDefinitionModelCollection typeDeclarations;
KeyedModelCollection<string, NamespaceModel> namespaces; KeyedModelCollection<string, NamespaceModel> namespaces;
NamespaceModel rootNamespace; NamespaceModel rootNamespace;
IReadOnlyList<DomAssemblyName> references;
public AssemblyModel(IEntityModelContext context) public AssemblyModel(IEntityModelContext context)
{ {
if (context == null) if (context == null)
throw new ArgumentNullException("context"); throw new ArgumentNullException("context");
this.context = context; this.context = context;
this.references = EmptyList<DomAssemblyName>.Instance;
this.rootNamespace = new NamespaceModel(context.Project, null, ""); this.rootNamespace = new NamespaceModel(context.Project, null, "");
this.typeDeclarations = new TopLevelTypeDefinitionModelCollection(context); this.typeDeclarations = new TopLevelTypeDefinitionModelCollection(context);
this.typeDeclarations.CollectionChanged += TypeDeclarationsCollectionChanged; this.typeDeclarations.CollectionChanged += TypeDeclarationsCollectionChanged;
@ -141,7 +143,8 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
public IReadOnlyList<DomAssemblyName> References { public IReadOnlyList<DomAssemblyName> References {
get { throw new NotImplementedException(); } get { return references; }
set { references = value; }
} }
} }
} }

15
src/Main/SharpDevelop/Dom/ClassBrowser/ClassBrowserPad.cs

@ -12,6 +12,7 @@ using ICSharpCode.Core.Presentation;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.TreeView; using ICSharpCode.TreeView;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Workbench; using ICSharpCode.SharpDevelop.Workbench;
@ -87,6 +88,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
set { treeView.MainAssemblyList = value; } set { treeView.MainAssemblyList = value; }
} }
public IAssemblyModel FindAssemblyModel(FileName fileName)
{
return treeView.FindAssemblyModel(fileName);
}
#endregion #endregion
const string PersistedWorkspaceSetting = "ClassBrowser.Workspaces"; const string PersistedWorkspaceSetting = "ClassBrowser.Workspaces";
@ -224,14 +230,13 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
{ {
var modelFactory = SD.GetRequiredService<IModelFactory>(); var modelFactory = SD.GetRequiredService<IModelFactory>();
try { try {
return modelFactory.CreateAssemblyModelFromFile(fileName); return SD.AssemblyParserService.GetAssemblyModel(new FileName(fileName), false, modelFactory);
} catch (Exception) { } catch (Exception) {
// Special AssemblyModel for unresolved file references // Special AssemblyModel for unresolved file references
IEntityModelContext unresolvedContext = new UnresolvedAssemblyEntityModelContext(Path.GetFileName(fileName), fileName); IEntityModelContext unresolvedContext = new UnresolvedAssemblyEntityModelContext(Path.GetFileName(fileName), fileName);
IAssemblyModel unresolvedModel = modelFactory.CreateAssemblyModel(unresolvedContext); IUpdateableAssemblyModel unresolvedModel = modelFactory.CreateAssemblyModel(unresolvedContext);
if (unresolvedModel is IUpdateableAssemblyModel) { unresolvedModel.AssemblyName = unresolvedContext.AssemblyName;
((IUpdateableAssemblyModel) unresolvedModel).AssemblyName = unresolvedContext.AssemblyName; unresolvedModel.References = EmptyList<DomAssemblyName>.Instance;
}
return unresolvedModel; return unresolvedModel;
} }

Loading…
Cancel
Save