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

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

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

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

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

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

@ -3,7 +3,9 @@ @@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using ICSharpCode.Core;
using ICSharpCode.TreeView;
namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
@ -41,6 +43,16 @@ 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()
{
this.assemblyLists = new SimpleModelCollection<IAssemblyList>();

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

@ -36,16 +36,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -36,16 +36,11 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
}
WorkspaceModel workspace;
protected static readonly IComparer<SharpTreeNode> ChildNodeComparer = new WorkspaceChildComparer();
public IMutableModelCollection<IAssemblyList> AssemblyLists {
get { return workspace.AssemblyLists; }
public WorkspaceModel Workspace {
get { return workspace; }
}
public IAssemblyList AssemblyList {
get { return workspace.MainAssemblyList; }
set { workspace.MainAssemblyList = value; }
}
protected static readonly IComparer<SharpTreeNode> ChildNodeComparer = new WorkspaceChildComparer();
public WorkspaceTreeNode()
{
@ -68,7 +63,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser @@ -68,7 +63,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ClassBrowser
public override object Text {
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 @@ -85,6 +85,11 @@ namespace ICSharpCode.SharpDevelop.Dom
/// Gets the assembly name (short name).
/// </summary>
new string AssemblyName { get; set; }
/// <summary>
/// Returns the assembly references.
/// </summary>
new IReadOnlyList<DomAssemblyName> References { get; set; }
}
public sealed class EmptyAssemblyModel : IAssemblyModel

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

@ -4,35 +4,16 @@ @@ -4,35 +4,16 @@
using System;
using System.Linq;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem;
using Mono.Cecil;
using ICSharpCode.SharpDevelop.Parser;
namespace ICSharpCode.SharpDevelop.Dom
{
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>
/// Creates an <see cref="ICSharpCode.SharpDevelop.Dom.IAssemblyModel"/> from a file name and catches
/// errors by showing messages to user.
@ -46,7 +27,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -46,7 +27,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public static IAssemblyModel SafelyCreateAssemblyModelFromFile(this IModelFactory modelFactory, string fileName)
{
try {
return modelFactory.CreateAssemblyModelFromFile(fileName);
return SD.AssemblyParserService.GetAssemblyModel(new FileName(fileName), true, modelFactory);
} catch (BadImageFormatException) {
SD.MessageService.ShowWarningFormatted("${res:ICSharpCode.SharpDevelop.Dom.AssemblyInvalid}", Path.GetFileName(fileName));
} catch (FileNotFoundException) {

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

@ -439,7 +439,7 @@ namespace ICSharpCode.SharpDevelop.Parser @@ -439,7 +439,7 @@ namespace ICSharpCode.SharpDevelop.Parser
foreach (string 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(FileName.Create(file), false, progressMonitor.CancellationToken);
if (pc != null) {
newReferences.Add(pc);
}

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

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

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

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

Loading…
Cancel
Save