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; @@ -21,16 +21,31 @@ using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
/// <summary>
/// Description of AssemblyList.
/// Describes a list of assemblies.
/// </summary>
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>();
ConcurrentDictionary<TypeDefinition, TypeTreeNode> typeDict = new ConcurrentDictionary<TypeDefinition, TypeTreeNode>();

66
ILSpy/AssemblyListManager.cs

@ -0,0 +1,66 @@ @@ -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 @@ @@ -1,5 +1,20 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
// 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.Threading;

1
ILSpy/ILSpy.csproj

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

28
ILSpy/ILSpySettings.cs

@ -28,18 +28,36 @@ namespace ICSharpCode.ILSpy @@ -28,18 +28,36 @@ namespace ICSharpCode.ILSpy
/// <summary>
/// Manages IL Spy settings.
/// </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)) {
try {
XDocument doc = XDocument.Load(GetConfigFile());
return doc.Root.Element(section) ?? new XElement(section);
return new ILSpySettings(doc.Root);
} catch (IOException) {
return new XElement(section);
return new ILSpySettings();
} catch (XmlException) {
return new XElement(section);
return new ILSpySettings();
}
}
}

8
ILSpy/MainWindow.xaml

@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@
<MenuItem Header="E_xit" Click="ExitClick" />
</MenuItem>
<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>
<Image Width="16" Height="16" Source="Images/PrivateInternal.png" />
</MenuItem.Icon>
@ -58,13 +58,13 @@ @@ -58,13 +58,13 @@
<Image Width="16" Height="16" Source="Images/Open.png" />
</Button>
<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" />
</CheckBox>
<Separator />
<ComboBox Name="languageComboBox" DisplayMemberPath="Name" Width="100"
ItemsSource="{x:Static local:Languages.AllLanguages}"
SelectedItem="{Binding Language}" />
SelectedItem="{Binding FilterSettings.Language}" />
</ToolBar>
<!-- Main grid separating left pane (treeView) from main pane (textEditor) -->
<Grid>
@ -84,7 +84,7 @@ @@ -84,7 +84,7 @@
</Grid.RowDefinitions>
<!-- Left pane: Search bar + Tree View -->
<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 -->
<tv:SharpTreeView
Name="treeView"

81
ILSpy/MainWindow.xaml.cs

@ -38,64 +38,76 @@ namespace ICSharpCode.ILSpy @@ -38,64 +38,76 @@ namespace ICSharpCode.ILSpy
/// </summary>
public partial class MainWindow : Window
{
AssemblyList assemblyList = new AssemblyList();
SessionSettings sessionSettings;
AssemblyListManager assemblyListManager;
AssemblyList assemblyList;
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()
{
this.DataContext = settings.FilterSettings;
this.Left = settings.WindowBounds.Left;
this.Top = settings.WindowBounds.Top;
this.Width = settings.WindowBounds.Width;
this.Height = settings.WindowBounds.Height;
ILSpySettings spySettings = ILSpySettings.Load();
this.sessionSettings = new SessionSettings(spySettings);
this.assemblyListManager = new AssemblyListManager(spySettings);
this.assemblyList = assemblyListManager.LoadList(spySettings, sessionSettings.ActiveAssemblyList);
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...)
this.WindowState = settings.WindowState;
this.WindowState = sessionSettings.WindowState;
InitializeComponent();
decompilerTextView.mainWindow = this;
assemblyListTreeNode = new AssemblyListTreeNode(assemblyList);
assemblyListTreeNode.FilterSettings = settings.FilterSettings.Clone();
settings.FilterSettings.PropertyChanged += new PropertyChangedEventHandler(filterSettings_PropertyChanged);
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
sessionSettings.FilterSettings.PropertyChanged += new PropertyChangedEventHandler(filterSettings_PropertyChanged);
treeView.Root = assemblyListTreeNode;
assemblyListTreeNode.Select = SelectNode;
foreach (System.Reflection.Assembly asm in initialAssemblies)
assemblyList.OpenAssembly(asm.Location);
string[] args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++) {
assemblyList.OpenAssembly(args[i]);
}
if (assemblyList.Assemblies.Count == 0)
LoadInitialAssemblies();
SelectNode(FindNodeByPath(settings.ActiveTreeViewPath));
SelectNode(FindNodeByPath(sessionSettings.ActiveTreeViewPath));
#if DEBUG
AddDebugItemsToToolbar();
#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)
{
// 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
// mutable instance changes.
assemblyListTreeNode.FilterSettings = settings.FilterSettings.Clone();
assemblyListTreeNode.FilterSettings = sessionSettings.FilterSettings.Clone();
if (e.PropertyName == "Language") {
TreeView_SelectionChanged(null, null);
}
@ -250,7 +262,7 @@ namespace ICSharpCode.ILSpy @@ -250,7 +262,7 @@ namespace ICSharpCode.ILSpy
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)
@ -258,15 +270,16 @@ namespace ICSharpCode.ILSpy @@ -258,15 +270,16 @@ namespace ICSharpCode.ILSpy
base.OnStateChanged(e);
// store window state in settings only if it's not minimized
if (this.WindowState != System.Windows.WindowState.Minimized)
settings.WindowState = this.WindowState;
sessionSettings.WindowState = this.WindowState;
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
settings.ActiveTreeViewPath = GetPathForNode(treeView.SelectedItem as SharpTreeNode);
settings.WindowBounds = this.RestoreBounds;
settings.Save();
sessionSettings.ActiveAssemblyList = assemblyList.ListName;
sessionSettings.ActiveTreeViewPath = GetPathForNode(treeView.SelectedItem as SharpTreeNode);
sessionSettings.WindowBounds = this.RestoreBounds;
sessionSettings.Save();
}
}
}

45
ILSpy/SessionSettings.cs

@ -1,5 +1,20 @@ @@ -1,5 +1,20 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
// 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.ComponentModel;
@ -13,17 +28,19 @@ namespace ICSharpCode.ILSpy @@ -13,17 +28,19 @@ namespace ICSharpCode.ILSpy
/// Per-session setting:
/// Loaded at startup; saved at exit.
/// </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");
if (filterSettings == null) filterSettings = new XElement("FilterSettings");
this.FilterSettings = new FilterSettings(filterSettings);
this.ActiveAssemblyList = (string)doc.Element("ActiveAssemblyList");
XElement activeTreeViewPath = doc.Element("ActiveTreeViewPath");
if (activeTreeViewPath != null) {
this.ActiveTreeViewPath = activeTreeViewPath.Elements().Select(e => (string)e).ToArray();
@ -33,10 +50,20 @@ namespace ICSharpCode.ILSpy @@ -33,10 +50,20 @@ namespace ICSharpCode.ILSpy
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 ActiveAssemblyList;
public WindowState WindowState = WindowState.Normal;
public Rect WindowBounds;
@ -44,11 +71,15 @@ namespace ICSharpCode.ILSpy @@ -44,11 +71,15 @@ namespace ICSharpCode.ILSpy
{
XElement doc = new XElement("SessionSettings");
doc.Add(this.FilterSettings.SaveAsXml());
if (this.ActiveAssemblyList != null) {
doc.Add(new XElement("ActiveAssemblyList", this.ActiveAssemblyList));
}
if (this.ActiveTreeViewPath != null) {
doc.Add(new XElement("ActiveTreeViewPath", ActiveTreeViewPath.Select(p => new XElement("Node", p))));
}
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);
}

Loading…
Cancel
Save