Browse Source

Started working on assembly list support.

pull/1/head
Daniel Grunwald 14 years ago
parent
commit
f723440cc4
  1. 19
      ILSpy/AssemblyList.cs
  2. 66
      ILSpy/AssemblyListManager.cs
  3. 19
      ILSpy/DecompilationOptions.cs
  4. 1
      ILSpy/ILSpy.csproj
  5. 28
      ILSpy/ILSpySettings.cs
  6. 8
      ILSpy/MainWindow.xaml
  7. 81
      ILSpy/MainWindow.xaml.cs
  8. 45
      ILSpy/SessionSettings.cs

19
ILSpy/AssemblyList.cs

@ -21,16 +21,31 @@ using System.Collections.Concurrent;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Xml.Linq;
using Mono.Cecil; using Mono.Cecil;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
{ {
/// <summary> /// <summary>
/// Description of AssemblyList. /// Describes a list of assemblies.
/// </summary> /// </summary>
class AssemblyList class AssemblyList
{ {
public AssemblyList(string listName)
{
this.ListName = listName;
}
public AssemblyList(XElement listElement)
{
this.ListName = (string)listElement.Attribute("name");
foreach (var asm in listElement.Elements("Assembly")) {
OpenAssembly((string)asm);
}
}
public string ListName { get; set; }
public readonly ObservableCollection<AssemblyTreeNode> Assemblies = new ObservableCollection<AssemblyTreeNode>(); public readonly ObservableCollection<AssemblyTreeNode> Assemblies = new ObservableCollection<AssemblyTreeNode>();
ConcurrentDictionary<TypeDefinition, TypeTreeNode> typeDict = new ConcurrentDictionary<TypeDefinition, TypeTreeNode>(); ConcurrentDictionary<TypeDefinition, TypeTreeNode> typeDict = new ConcurrentDictionary<TypeDefinition, TypeTreeNode>();

66
ILSpy/AssemblyListManager.cs

@ -0,0 +1,66 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Xml.Linq;
namespace ICSharpCode.ILSpy
{
/// <summary>
/// Manages the available assembly lists.
/// </summary>
sealed class AssemblyListManager
{
public AssemblyListManager(ILSpySettings spySettings)
{
XElement doc = spySettings["AssemblyLists"];
foreach (var list in doc.Elements("List")) {
AssemblyLists.Add((string)list.Attribute("name"));
}
}
public readonly ObservableCollection<string> AssemblyLists = new ObservableCollection<string>();
public AssemblyList LoadList(ILSpySettings spySettings, string listName)
{
AssemblyList list = DoLoadList(spySettings, listName);
if (!AssemblyLists.Contains(list.ListName))
AssemblyLists.Add(list.ListName);
return list;
}
AssemblyList DoLoadList(ILSpySettings spySettings, string listName)
{
XElement doc = spySettings["AssemblyLists"];
if (listName != null) {
foreach (var list in doc.Elements("List")) {
if ((string)list.Attribute("name") == listName) {
return new AssemblyList(list);
}
}
}
XElement firstList = doc.Elements("List").FirstOrDefault();
if (firstList != null)
return new AssemblyList(firstList);
else
return new AssemblyList(listName ?? "(Default)");
}
}
}

19
ILSpy/DecompilationOptions.cs

@ -1,5 +1,20 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under MIT X11 license (for details please see \doc\license.txt) //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Threading; using System.Threading;

1
ILSpy/ILSpy.csproj

@ -81,6 +81,7 @@
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="AssemblyList.cs" /> <Compile Include="AssemblyList.cs" />
<Compile Include="AssemblyListManager.cs" />
<Compile Include="CSharpLanguage.cs" /> <Compile Include="CSharpLanguage.cs" />
<Compile Include="CueBannerService.cs" /> <Compile Include="CueBannerService.cs" />
<Compile Include="DecompilationOptions.cs" /> <Compile Include="DecompilationOptions.cs" />

28
ILSpy/ILSpySettings.cs

@ -28,18 +28,36 @@ namespace ICSharpCode.ILSpy
/// <summary> /// <summary>
/// Manages IL Spy settings. /// Manages IL Spy settings.
/// </summary> /// </summary>
public static class ILSpySettings public class ILSpySettings
{ {
public static XElement LoadSettings(string section) readonly XElement root;
ILSpySettings()
{
this.root = new XElement("ILSpy");
}
ILSpySettings(XElement root)
{
this.root = root;
}
public XElement this[string section] {
get {
return root.Element(section) ?? new XElement(section);
}
}
public static ILSpySettings Load()
{ {
using (new MutexProtector(ConfigFileMutex)) { using (new MutexProtector(ConfigFileMutex)) {
try { try {
XDocument doc = XDocument.Load(GetConfigFile()); XDocument doc = XDocument.Load(GetConfigFile());
return doc.Root.Element(section) ?? new XElement(section); return new ILSpySettings(doc.Root);
} catch (IOException) { } catch (IOException) {
return new XElement(section); return new ILSpySettings();
} catch (XmlException) { } catch (XmlException) {
return new XElement(section); return new ILSpySettings();
} }
} }
} }

8
ILSpy/MainWindow.xaml

@ -28,7 +28,7 @@
<MenuItem Header="E_xit" Click="ExitClick" /> <MenuItem Header="E_xit" Click="ExitClick" />
</MenuItem> </MenuItem>
<MenuItem Header="_View"> <MenuItem Header="_View">
<MenuItem Header="Show _internal types and members" IsCheckable="True" IsChecked="{Binding ShowInternalApi}"> <MenuItem Header="Show _internal types and members" IsCheckable="True" IsChecked="{Binding FilterSettings.ShowInternalApi}">
<MenuItem.Icon> <MenuItem.Icon>
<Image Width="16" Height="16" Source="Images/PrivateInternal.png" /> <Image Width="16" Height="16" Source="Images/PrivateInternal.png" />
</MenuItem.Icon> </MenuItem.Icon>
@ -58,13 +58,13 @@
<Image Width="16" Height="16" Source="Images/Open.png" /> <Image Width="16" Height="16" Source="Images/Open.png" />
</Button> </Button>
<Separator /> <Separator />
<CheckBox IsChecked="{Binding ShowInternalApi}" ToolTip="Show internal types and members"> <CheckBox IsChecked="{Binding FilterSettings.ShowInternalApi}" ToolTip="Show internal types and members">
<Image Width="16" Height="16" Source="Images/PrivateInternal.png" /> <Image Width="16" Height="16" Source="Images/PrivateInternal.png" />
</CheckBox> </CheckBox>
<Separator /> <Separator />
<ComboBox Name="languageComboBox" DisplayMemberPath="Name" Width="100" <ComboBox Name="languageComboBox" DisplayMemberPath="Name" Width="100"
ItemsSource="{x:Static local:Languages.AllLanguages}" ItemsSource="{x:Static local:Languages.AllLanguages}"
SelectedItem="{Binding Language}" /> SelectedItem="{Binding FilterSettings.Language}" />
</ToolBar> </ToolBar>
<!-- Main grid separating left pane (treeView) from main pane (textEditor) --> <!-- Main grid separating left pane (treeView) from main pane (textEditor) -->
<Grid> <Grid>
@ -84,7 +84,7 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Left pane: Search bar + Tree View --> <!-- Left pane: Search bar + Tree View -->
<DockPanel> <DockPanel>
<TextBox DockPanel.Dock="Top" local:CueBannerService.CueBanner=" Search" Text="{Binding SearchTerm, UpdateSourceTrigger=PropertyChanged}" /> <TextBox DockPanel.Dock="Top" local:CueBannerService.CueBanner=" Search" Text="{Binding FilterSettings.SearchTerm, UpdateSourceTrigger=PropertyChanged}" />
<!-- Tree View of assemblies and classes --> <!-- Tree View of assemblies and classes -->
<tv:SharpTreeView <tv:SharpTreeView
Name="treeView" Name="treeView"

81
ILSpy/MainWindow.xaml.cs

@ -38,64 +38,76 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
AssemblyList assemblyList = new AssemblyList(); SessionSettings sessionSettings;
AssemblyListManager assemblyListManager;
AssemblyList assemblyList;
AssemblyListTreeNode assemblyListTreeNode; AssemblyListTreeNode assemblyListTreeNode;
SessionSettings settings = new SessionSettings();
static readonly System.Reflection.Assembly[] initialAssemblies = {
typeof(object).Assembly,
typeof(Uri).Assembly,
typeof(System.Linq.Enumerable).Assembly,
typeof(System.Xml.XmlDocument).Assembly,
typeof(System.Windows.Markup.MarkupExtension).Assembly,
typeof(System.Windows.Rect).Assembly,
typeof(System.Windows.UIElement).Assembly,
typeof(System.Windows.FrameworkElement).Assembly,
typeof(ICSharpCode.TreeView.SharpTreeView).Assembly,
typeof(Mono.Cecil.AssemblyDefinition).Assembly,
typeof(MainWindow).Assembly,
typeof(ICSharpCode.Decompiler.GraphVizGraph).Assembly
};
public MainWindow() public MainWindow()
{ {
this.DataContext = settings.FilterSettings; ILSpySettings spySettings = ILSpySettings.Load();
this.Left = settings.WindowBounds.Left; this.sessionSettings = new SessionSettings(spySettings);
this.Top = settings.WindowBounds.Top; this.assemblyListManager = new AssemblyListManager(spySettings);
this.Width = settings.WindowBounds.Width; this.assemblyList = assemblyListManager.LoadList(spySettings, sessionSettings.ActiveAssemblyList);
this.Height = settings.WindowBounds.Height;
this.DataContext = sessionSettings;
this.Left = sessionSettings.WindowBounds.Left;
this.Top = sessionSettings.WindowBounds.Top;
this.Width = sessionSettings.WindowBounds.Width;
this.Height = sessionSettings.WindowBounds.Height;
// TODO: validate bounds (maybe a screen was removed...) // TODO: validate bounds (maybe a screen was removed...)
this.WindowState = settings.WindowState; this.WindowState = sessionSettings.WindowState;
InitializeComponent(); InitializeComponent();
decompilerTextView.mainWindow = this; decompilerTextView.mainWindow = this;
assemblyListTreeNode = new AssemblyListTreeNode(assemblyList); assemblyListTreeNode = new AssemblyListTreeNode(assemblyList);
assemblyListTreeNode.FilterSettings = settings.FilterSettings.Clone(); assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
settings.FilterSettings.PropertyChanged += new PropertyChangedEventHandler(filterSettings_PropertyChanged); sessionSettings.FilterSettings.PropertyChanged += new PropertyChangedEventHandler(filterSettings_PropertyChanged);
treeView.Root = assemblyListTreeNode; treeView.Root = assemblyListTreeNode;
assemblyListTreeNode.Select = SelectNode; assemblyListTreeNode.Select = SelectNode;
foreach (System.Reflection.Assembly asm in initialAssemblies)
assemblyList.OpenAssembly(asm.Location);
string[] args = Environment.GetCommandLineArgs(); string[] args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++) { for (int i = 1; i < args.Length; i++) {
assemblyList.OpenAssembly(args[i]); assemblyList.OpenAssembly(args[i]);
} }
if (assemblyList.Assemblies.Count == 0)
LoadInitialAssemblies();
SelectNode(FindNodeByPath(settings.ActiveTreeViewPath)); SelectNode(FindNodeByPath(sessionSettings.ActiveTreeViewPath));
#if DEBUG #if DEBUG
AddDebugItemsToToolbar(); AddDebugItemsToToolbar();
#endif #endif
} }
void LoadInitialAssemblies()
{
System.Reflection.Assembly[] initialAssemblies = {
typeof(object).Assembly,
typeof(Uri).Assembly,
typeof(System.Linq.Enumerable).Assembly,
typeof(System.Xml.XmlDocument).Assembly,
typeof(System.Windows.Markup.MarkupExtension).Assembly,
typeof(System.Windows.Rect).Assembly,
typeof(System.Windows.UIElement).Assembly,
typeof(System.Windows.FrameworkElement).Assembly,
typeof(ICSharpCode.TreeView.SharpTreeView).Assembly,
typeof(Mono.Cecil.AssemblyDefinition).Assembly,
typeof(ICSharpCode.AvalonEdit.TextEditor).Assembly,
typeof(ICSharpCode.Decompiler.GraphVizGraph).Assembly,
typeof(MainWindow).Assembly
};
foreach (System.Reflection.Assembly asm in initialAssemblies)
assemblyList.OpenAssembly(asm.Location);
}
void filterSettings_PropertyChanged(object sender, PropertyChangedEventArgs e) void filterSettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{ {
// filterSettings is mutable; but the ILSpyTreeNode filtering assumes that filter settings are immutable. // filterSettings is mutable; but the ILSpyTreeNode filtering assumes that filter settings are immutable.
// Thus, the main window will use one mutable instance (for data-binding), and assign a new clone to the ILSpyTreeNodes whenever the main // Thus, the main window will use one mutable instance (for data-binding), and assign a new clone to the ILSpyTreeNodes whenever the main
// mutable instance changes. // mutable instance changes.
assemblyListTreeNode.FilterSettings = settings.FilterSettings.Clone(); assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
if (e.PropertyName == "Language") { if (e.PropertyName == "Language") {
TreeView_SelectionChanged(null, null); TreeView_SelectionChanged(null, null);
} }
@ -250,7 +262,7 @@ namespace ICSharpCode.ILSpy
void TreeView_SelectionChanged(object sender, SelectionChangedEventArgs e) void TreeView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ {
decompilerTextView.Decompile(settings.FilterSettings.Language, treeView.SelectedItems.OfType<ILSpyTreeNodeBase>()); decompilerTextView.Decompile(sessionSettings.FilterSettings.Language, treeView.SelectedItems.OfType<ILSpyTreeNodeBase>());
} }
protected override void OnStateChanged(EventArgs e) protected override void OnStateChanged(EventArgs e)
@ -258,15 +270,16 @@ namespace ICSharpCode.ILSpy
base.OnStateChanged(e); base.OnStateChanged(e);
// store window state in settings only if it's not minimized // store window state in settings only if it's not minimized
if (this.WindowState != System.Windows.WindowState.Minimized) if (this.WindowState != System.Windows.WindowState.Minimized)
settings.WindowState = this.WindowState; sessionSettings.WindowState = this.WindowState;
} }
protected override void OnClosing(CancelEventArgs e) protected override void OnClosing(CancelEventArgs e)
{ {
base.OnClosing(e); base.OnClosing(e);
settings.ActiveTreeViewPath = GetPathForNode(treeView.SelectedItem as SharpTreeNode); sessionSettings.ActiveAssemblyList = assemblyList.ListName;
settings.WindowBounds = this.RestoreBounds; sessionSettings.ActiveTreeViewPath = GetPathForNode(treeView.SelectedItem as SharpTreeNode);
settings.Save(); sessionSettings.WindowBounds = this.RestoreBounds;
sessionSettings.Save();
} }
} }
} }

45
ILSpy/SessionSettings.cs

@ -1,5 +1,20 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under MIT X11 license (for details please see \doc\license.txt) //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System; using System;
using System.ComponentModel; using System.ComponentModel;
@ -13,17 +28,19 @@ namespace ICSharpCode.ILSpy
/// Per-session setting: /// Per-session setting:
/// Loaded at startup; saved at exit. /// Loaded at startup; saved at exit.
/// </summary> /// </summary>
public class SessionSettings public class SessionSettings : INotifyPropertyChanged
{ {
public SessionSettings() public SessionSettings(ILSpySettings spySettings)
{ {
XElement doc = ILSpySettings.LoadSettings("SessionSettings"); XElement doc = spySettings["SessionSettings"];
XElement filterSettings = doc.Element("FilterSettings"); XElement filterSettings = doc.Element("FilterSettings");
if (filterSettings == null) filterSettings = new XElement("FilterSettings"); if (filterSettings == null) filterSettings = new XElement("FilterSettings");
this.FilterSettings = new FilterSettings(filterSettings); this.FilterSettings = new FilterSettings(filterSettings);
this.ActiveAssemblyList = (string)doc.Element("ActiveAssemblyList");
XElement activeTreeViewPath = doc.Element("ActiveTreeViewPath"); XElement activeTreeViewPath = doc.Element("ActiveTreeViewPath");
if (activeTreeViewPath != null) { if (activeTreeViewPath != null) {
this.ActiveTreeViewPath = activeTreeViewPath.Elements().Select(e => (string)e).ToArray(); this.ActiveTreeViewPath = activeTreeViewPath.Elements().Select(e => (string)e).ToArray();
@ -33,10 +50,20 @@ namespace ICSharpCode.ILSpy
this.WindowBounds = FromString((string)doc.Element("WindowBounds"), new Rect(10, 10, 750, 550)); this.WindowBounds = FromString((string)doc.Element("WindowBounds"), new Rect(10, 10, 750, 550));
} }
public FilterSettings FilterSettings; public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public readonly FilterSettings FilterSettings;
public string[] ActiveTreeViewPath; public string[] ActiveTreeViewPath;
public string ActiveAssemblyList;
public WindowState WindowState = WindowState.Normal; public WindowState WindowState = WindowState.Normal;
public Rect WindowBounds; public Rect WindowBounds;
@ -44,11 +71,15 @@ namespace ICSharpCode.ILSpy
{ {
XElement doc = new XElement("SessionSettings"); XElement doc = new XElement("SessionSettings");
doc.Add(this.FilterSettings.SaveAsXml()); doc.Add(this.FilterSettings.SaveAsXml());
if (this.ActiveAssemblyList != null) {
doc.Add(new XElement("ActiveAssemblyList", this.ActiveAssemblyList));
}
if (this.ActiveTreeViewPath != null) { if (this.ActiveTreeViewPath != null) {
doc.Add(new XElement("ActiveTreeViewPath", ActiveTreeViewPath.Select(p => new XElement("Node", p)))); doc.Add(new XElement("ActiveTreeViewPath", ActiveTreeViewPath.Select(p => new XElement("Node", p))));
} }
doc.Add(new XElement("WindowState", ToString(this.WindowState))); doc.Add(new XElement("WindowState", ToString(this.WindowState)));
doc.Add(new XElement("WindowBounds", ToString(this.WindowBounds))); doc.Add(new XElement("WindowState", ToString(this.WindowState)));
ILSpySettings.SaveSettings(doc); ILSpySettings.SaveSettings(doc);
} }

Loading…
Cancel
Save