Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
9a876d1e41
  1. 3
      ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs
  2. 11
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  3. 26
      ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs
  4. 6
      ILSpy.sln
  5. 73
      ILSpy/App.xaml.cs
  6. 40
      ILSpy/CommandLineArguments.cs
  7. 122
      ILSpy/ContextMenuEntry.cs
  8. 4
      ILSpy/ExportCommandAttribute.cs
  9. 12
      ILSpy/ILSpy.csproj
  10. 108
      ILSpy/MainWindow.xaml.cs
  11. 72
      ILSpy/NativeMethods.cs
  12. 57
      ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs
  13. 6
      ILSpy/TreeNodes/Analyzer/AnalyzedFieldNode.cs
  14. 6
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs
  15. 36
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  16. 7
      ILSpy/TreeNodes/BaseTypesTreeNode.cs
  17. 8
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  18. 6
      ILSpy/TreeNodes/EventTreeNode.cs
  19. 15
      ILSpy/TreeNodes/FieldTreeNode.cs
  20. 33
      ILSpy/TreeNodes/IMemberTreeNode.cs
  21. 16
      ILSpy/TreeNodes/MethodTreeNode.cs
  22. 6
      ILSpy/TreeNodes/PropertyTreeNode.cs
  23. 6
      ILSpy/TreeNodes/TypeTreeNode.cs
  24. 0
      ILSpy/TreeNodes/XamlResourceNode.cs
  25. 168
      ILSpy/XmlDocKeyProvider.cs
  26. 5
      SharpTreeView/SharpTreeNode.cs
  27. 10
      SharpTreeView/SharpTreeViewItem.cs
  28. 52
      doc/Command Line.txt

3
ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs

@ -176,7 +176,6 @@ namespace ICSharpCode.Decompiler.Ast.Transforms @@ -176,7 +176,6 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
if (varDecl != null && varDecl.Parent is BlockStatement) {
Statement declarationPoint;
if (CanMoveVariableDeclarationIntoStatement(varDecl, usingStatement, out declarationPoint)) {
Debug.Assert(declarationPoint == usingStatement);
// Moving the variable into the UsingStatement is allowed:
usingStatement.ResourceAcquisition = new VariableDeclarationStatement {
Type = (AstType)varDecl.Type.Clone(),
@ -302,7 +301,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms @@ -302,7 +301,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
};
node.ReplaceWith(foreachStatement);
foreach (Statement stmt in m.Get<Statement>("variablesOutsideLoop")) {
((BlockStatement)foreachStatement.Parent).Statements.InsertAfter(null, stmt);
((BlockStatement)foreachStatement.Parent).Statements.InsertAfter(null, stmt.Detach());
}
return foreachStatement;
}

11
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -3,6 +3,7 @@ using System.Collections.Generic; @@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.NRefactory.Utils;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.CSharp;
@ -176,14 +177,8 @@ namespace ICSharpCode.Decompiler.ILAst @@ -176,14 +177,8 @@ namespace ICSharpCode.Decompiler.ILAst
}
if (abortBeforeStep == ILAstOptimizationStep.IntroduceFixedStatements) return;
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
for (int i = block.Body.Count - 1; i >= 0; i--) {
// TODO: Move before loops
if (i < block.Body.Count)
IntroduceFixedStatements(block.Body, i);
}
}
foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>()) {
// we need post-order traversal, not pre-order, for "fixed" to work correctly
foreach (ILBlock block in TreeTraversal.PostOrder<ILNode>(method, n => n.GetChildren()).OfType<ILBlock>()) {
for (int i = block.Body.Count - 1; i >= 0; i--) {
// TODO: Move before loops
if (i < block.Body.Count)

26
ICSharpCode.Decompiler/ILAst/PeepholeTransform.cs

@ -641,6 +641,17 @@ namespace ICSharpCode.Decompiler.ILAst @@ -641,6 +641,17 @@ namespace ICSharpCode.Decompiler.ILAst
&& falseValue.Arguments[0].Match(ILCode.Ldloc, out loadedVariable) && loadedVariable == arrayVariable
&& IsNullOrZero(falseValue.Arguments[1]))
{
// OK, we detected the pattern for fixing an array.
// Now check whether the loading expression was a store ot a temp. var
// that can be eliminated.
if (arrayLoadingExpr.Code == ILCode.Stloc) {
ILInlining inlining = new ILInlining(method);
if (inlining.numLdloc.GetOrDefault(arrayVariable) == 2 &&
inlining.numStloc.GetOrDefault(arrayVariable) == 1 && inlining.numLdloca.GetOrDefault(arrayVariable) == 0)
{
arrayLoadingExpr = arrayLoadingExpr.Arguments[0];
}
}
initValue = new ILExpression(ILCode.Stloc, pinnedVar, arrayLoadingExpr);
nextPos = i + 1;
return true;
@ -657,16 +668,17 @@ namespace ICSharpCode.Decompiler.ILAst @@ -657,16 +668,17 @@ namespace ICSharpCode.Decompiler.ILAst
bool MatchFixedArrayInitializerCondition(ILExpression condition, out ILExpression initValue)
{
ILExpression logicAnd;
ILVariable arrayVar1, arrayVar2;
ILVariable arrayVar;
if (condition.Match(ILCode.LogicNot, out logicAnd) && logicAnd.Code == ILCode.LogicAnd) {
initValue = UnpackDoubleNegation(logicAnd.Arguments[0]);
if (initValue.Match(ILCode.Ldloc, out arrayVar1)) {
ILExpression arrayVarInitializer;
if (initValue.Match(ILCode.Ldloc, out arrayVar)
|| initValue.Match(ILCode.Stloc, out arrayVar, out arrayVarInitializer))
{
ILExpression arrayLength = logicAnd.Arguments[1];
if (arrayLength.Code == ILCode.Conv_I4)
arrayLength = arrayLength.Arguments[0];
if (arrayLength.Code == ILCode.Ldlen && arrayLength.Arguments[0].Match(ILCode.Ldloc, out arrayVar2)) {
return arrayVar1 == arrayVar2;
}
return arrayLength.Code == ILCode.Ldlen && arrayLength.Arguments[0].MatchLdloc(arrayVar);
}
}
initValue = null;
@ -716,7 +728,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -716,7 +728,9 @@ namespace ICSharpCode.Decompiler.ILAst
if (!(ifStmt.TrueBlock.Body[0].Match(ILCode.Stloc, out assignedVar, out assignedExpr) && assignedVar == var2 && assignedExpr.Code == ILCode.Add))
return false;
MethodReference calledMethod;
if (!(assignedExpr.Arguments[0].MatchLdloc(var1) && assignedExpr.Arguments[1].Match(ILCode.Call, out calledMethod)))
if (!(assignedExpr.Arguments[0].MatchLdloc(var1)))
return false;
if (!(assignedExpr.Arguments[1].Match(ILCode.Call, out calledMethod) || assignedExpr.Arguments[1].Match(ILCode.CallGetter, out calledMethod)))
return false;
if (!(calledMethod.Name == "get_OffsetToStringData" && calledMethod.DeclaringType.FullName == "System.Runtime.CompilerServices.RuntimeHelpers"))
return false;

6
ILSpy.sln

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.0.1.7100
# SharpDevelop 4.1.0.7371-alpha
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Debugger", "Debugger", "{1DEB3B4E-03AC-437C-821D-B09FBFCC3E5B}"
ProjectSection(SolutionItems) = postProject
@ -24,6 +25,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory", "N @@ -24,6 +25,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory", "N
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Decompiler.Tests", "ICSharpCode.Decompiler\Tests\ICSharpCode.Decompiler.Tests.csproj", "{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{F45DB999-7E72-4000-B5AD-3A7B485A0896}"
ProjectSection(SolutionItems) = postProject
doc\Command Line.txt = doc\Command Line.txt
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU

73
ILSpy/App.xaml.cs

@ -20,6 +20,8 @@ using System; @@ -20,6 +20,8 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Documents;
@ -39,8 +41,19 @@ namespace ICSharpCode.ILSpy @@ -39,8 +41,19 @@ namespace ICSharpCode.ILSpy
get { return compositionContainer; }
}
internal static CommandLineArguments CommandLineArguments;
public App()
{
var cmdArgs = Environment.GetCommandLineArgs().Skip(1);
App.CommandLineArguments = new CommandLineArguments(cmdArgs);
if (App.CommandLineArguments.SingleInstance ?? true) {
cmdArgs = cmdArgs.Select(FullyQualifyPath);
string message = string.Join(Environment.NewLine, cmdArgs);
if (SendToPreviousInstance("ILSpy:\r\n" + message, !App.CommandLineArguments.NoActivate)) {
Environment.Exit(0);
}
}
InitializeComponent();
var catalog = new AggregateCatalog();
@ -62,7 +75,20 @@ namespace ICSharpCode.ILSpy @@ -62,7 +75,20 @@ namespace ICSharpCode.ILSpy
new RequestNavigateEventHandler(Window_RequestNavigate));
}
string FullyQualifyPath(string argument)
{
// Fully qualify the paths before passing them to another process,
// because that process might use a different current directory.
if (string.IsNullOrEmpty(argument) || argument[0] == '/')
return argument;
try {
return Path.Combine(Environment.CurrentDirectory, argument);
} catch (ArgumentException) {
return argument;
}
}
#region Exception Handling
static void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
Debug.WriteLine(e.Exception.ToString());
@ -78,6 +104,53 @@ namespace ICSharpCode.ILSpy @@ -78,6 +104,53 @@ namespace ICSharpCode.ILSpy
MessageBox.Show(ex.ToString(), "Sorry, we crashed");
}
}
#endregion
#region Pass Command Line Arguments to previous instance
bool SendToPreviousInstance(string message, bool activate)
{
bool success = false;
NativeMethods.EnumWindows(
(hWnd, lParam) => {
string windowTitle = NativeMethods.GetWindowText(hWnd, 100);
if (windowTitle.StartsWith("ILSpy", StringComparison.Ordinal)) {
Debug.WriteLine("Found {0:x4}: {1}", hWnd, windowTitle);
IntPtr result = Send(hWnd, message);
Debug.WriteLine("WM_COPYDATA result: {0:x8}", result);
if (result == (IntPtr)1) {
if (activate)
NativeMethods.SetForegroundWindow(hWnd);
success = true;
return false; // stop enumeration
}
}
return true; // continue enumeration
}, IntPtr.Zero);
return success;
}
unsafe static IntPtr Send(IntPtr hWnd, string message)
{
const uint SMTO_NORMAL = 0;
CopyDataStruct lParam;
lParam.Padding = IntPtr.Zero;
lParam.Size = message.Length * 2;
fixed (char *buffer = message) {
lParam.Buffer = (IntPtr)buffer;
IntPtr result;
// SendMessage with 3s timeout (e.g. when the target process is stopped in the debugger)
if (NativeMethods.SendMessageTimeout(
hWnd, NativeMethods.WM_COPYDATA, IntPtr.Zero, ref lParam,
SMTO_NORMAL, 3000, out result) != IntPtr.Zero)
{
return result;
} else {
return IntPtr.Zero;
}
}
}
#endregion
void Window_RequestNavigate(object sender, RequestNavigateEventArgs e)
{

40
ILSpy/CommandLineArguments.cs

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
// 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)
using System;
using System.Collections.Generic;
namespace ICSharpCode.ILSpy
{
sealed class CommandLineArguments
{
// see /doc/Command Line.txt for details
public List<string> AssembliesToLoad = new List<string>();
public bool? SingleInstance;
public string NavigateTo;
public string Language;
public bool NoActivate;
public CommandLineArguments(IEnumerable<string> arguments)
{
foreach (string arg in arguments) {
if (arg.Length == 0)
continue;
if (arg[0] == '/') {
if (arg.Equals("/singleInstance", StringComparison.OrdinalIgnoreCase))
this.SingleInstance = true;
else if (arg.Equals("/separate", StringComparison.OrdinalIgnoreCase))
this.SingleInstance = false;
else if (arg.StartsWith("/navigateTo:", StringComparison.OrdinalIgnoreCase))
this.NavigateTo = arg.Substring("/navigateTo:".Length);
else if (arg.StartsWith("/language:", StringComparison.OrdinalIgnoreCase))
this.Language = arg.Substring("/language:".Length);
else if (arg.Equals("/noActivate", StringComparison.OrdinalIgnoreCase))
this.NoActivate = true;
} else {
this.AssembliesToLoad.Add(arg);
}
}
}
}
}

122
ILSpy/ContextMenuEntry.cs

@ -0,0 +1,122 @@ @@ -0,0 +1,122 @@
// 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.Composition;
using System.Linq;
using System.Windows.Controls;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy
{
public interface IContextMenuEntry
{
bool IsVisible(SharpTreeNode[] selectedNodes);
bool IsEnabled(SharpTreeNode[] selectedNodes);
void Execute(SharpTreeNode[] selectedNodes);
}
public interface IContextMenuEntryMetadata
{
string Icon { get; }
string Header { get; }
string Category { get; }
double Order { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportContextMenuEntryAttribute : ExportAttribute, IContextMenuEntryMetadata
{
public ExportContextMenuEntryAttribute()
: base(typeof(IContextMenuEntry))
{
}
public string Icon { get; set; }
public string Header { get; set; }
public string Category { get; set; }
public double Order { get; set; }
}
internal class ContextMenuProvider
{
/// <summary>
/// Enables extensible context menu support for the specified tree view.
/// </summary>
public static void Add(SharpTreeView treeView)
{
var provider = new ContextMenuProvider(treeView);
treeView.ContextMenuOpening += provider.treeView_ContextMenuOpening;
treeView.ContextMenuClosing -= provider.treeView_ContextMenuClosing;
}
readonly SharpTreeView treeView;
[ImportMany(typeof(IContextMenuEntry))]
Lazy<IContextMenuEntry, IContextMenuEntryMetadata>[] entries = null;
private ContextMenuProvider(SharpTreeView treeView)
{
this.treeView = treeView;
App.CompositionContainer.ComposeParts(this);
}
void treeView_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
SharpTreeNode[] selectedNodes = treeView.GetTopLevelSelection().ToArray();
if (selectedNodes.Length == 0)
return;
ContextMenu menu = new ContextMenu();
foreach (var category in entries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.Category)) {
if (menu.Items.Count > 0) {
menu.Items.Add(new Separator());
}
foreach (var entryPair in category) {
IContextMenuEntry entry = entryPair.Value;
if (entry.IsVisible(selectedNodes)) {
MenuItem menuItem = new MenuItem();
menuItem.Header = entryPair.Metadata.Header;
if (!string.IsNullOrEmpty(entryPair.Metadata.Icon)) {
menuItem.Icon = new Image {
Width = 16,
Height = 16,
Source = Images.LoadImage(entry, entryPair.Metadata.Icon)
};
}
if (entryPair.Value.IsEnabled(selectedNodes)) {
menuItem.Click += delegate {
entry.Execute(selectedNodes);
};
}
menu.Items.Add(menuItem);
}
}
}
if (menu.Items.Count > 0)
treeView.ContextMenu = menu;
}
void treeView_ContextMenuClosing(object sender, ContextMenuEventArgs e)
{
treeView.ContextMenu = null;
}
}
}

4
ILSpy/ExportCommandAttribute.cs

@ -19,7 +19,7 @@ namespace ICSharpCode.ILSpy @@ -19,7 +19,7 @@ namespace ICSharpCode.ILSpy
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportToolbarCommandAttribute : ExportAttribute
public class ExportToolbarCommandAttribute : ExportAttribute, IToolbarCommandMetadata
{
public ExportToolbarCommandAttribute()
: base("ToolbarCommand", typeof(ICommand))
@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy @@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportMainMenuCommandAttribute : ExportAttribute
public class ExportMainMenuCommandAttribute : ExportAttribute, IMainMenuCommandMetadata
{
bool isEnabled = true;

12
ILSpy/ILSpy.csproj

@ -12,11 +12,12 @@ @@ -12,11 +12,12 @@
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<ApplicationIcon>Images\ILSpy.ico</ApplicationIcon>
<RunCodeAnalysis>False</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
@ -39,6 +40,7 @@ @@ -39,6 +40,7 @@
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<StartAction>Project</StartAction>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
@ -89,6 +91,7 @@ @@ -89,6 +91,7 @@
<Compile Include="AssemblyList.cs" />
<Compile Include="AssemblyListManager.cs" />
<Compile Include="BamlDecompiler.cs" />
<Compile Include="CommandLineArguments.cs" />
<Compile Include="Commands.cs" />
<Compile Include="Commands\DebuggerCommands.cs" />
<Compile Include="Controls\SearchBox.cs" />
@ -101,6 +104,7 @@ @@ -101,6 +104,7 @@
<Compile Include="Fusion.cs" />
<Compile Include="GacInterop.cs" />
<Compile Include="GuessFileType.cs" />
<Compile Include="ContextMenuEntry.cs" />
<Compile Include="ILAstLanguage.cs" />
<Compile Include="ILLanguage.cs" />
<Compile Include="ILSpySettings.cs" />
@ -108,6 +112,7 @@ @@ -108,6 +112,7 @@
<Compile Include="Language.cs" />
<Compile Include="Images\Images.cs" />
<Compile Include="LoadedAssembly.cs" />
<Compile Include="NativeMethods.cs" />
<Compile Include="NavigationHistory.cs" />
<Compile Include="OpenFromGacDialog.xaml.cs">
<DependentUpon>OpenFromGacDialog.xaml</DependentUpon>
@ -126,7 +131,10 @@ @@ -126,7 +131,10 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="XamlResourceNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzeContextMenuEntry.cs" />
<Compile Include="TreeNodes\IMemberTreeNode.cs" />
<Compile Include="TreeNodes\XamlResourceNode.cs" />
<Compile Include="XmlDocKeyProvider.cs" />
<EmbeddedResource Include="..\README.txt">
<Link>README.txt</Link>
</EmbeddedResource>

108
ILSpy/MainWindow.xaml.cs

@ -22,11 +22,13 @@ using System.Collections.Specialized; @@ -22,11 +22,13 @@ using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
@ -97,6 +99,8 @@ namespace ICSharpCode.ILSpy @@ -97,6 +99,8 @@ namespace ICSharpCode.ILSpy
InitMainMenu();
InitToolbar();
ContextMenuProvider.Add(treeView);
ContextMenuProvider.Add(analyzerTree);
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
@ -182,6 +186,77 @@ namespace ICSharpCode.ILSpy @@ -182,6 +186,77 @@ namespace ICSharpCode.ILSpy
}
#endregion
#region Message Hook
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;;
if (source != null) {
source.AddHook(WndProc);
}
}
unsafe IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == NativeMethods.WM_COPYDATA) {
CopyDataStruct* copyData = (CopyDataStruct*)lParam;
string data = new string((char*)copyData->Buffer, 0, copyData->Size / sizeof(char));
if (data.StartsWith("ILSpy:\r\n", StringComparison.Ordinal)) {
data = data.Substring(8);
List<string> lines = new List<string>();
using (StringReader r = new StringReader(data)) {
string line;
while ((line = r.ReadLine()) != null)
lines.Add(line);
}
var args = new CommandLineArguments(lines);
if (HandleCommandLineArguments(args)) {
HandleCommandLineArgumentsAfterShowList(args);
handled = true;
return (IntPtr)1;
}
}
}
return IntPtr.Zero;
}
#endregion
List<LoadedAssembly> commandLineLoadedAssemblies = new List<LoadedAssembly>();
bool HandleCommandLineArguments(CommandLineArguments args)
{
foreach (string file in args.AssembliesToLoad) {
commandLineLoadedAssemblies.Add(assemblyList.OpenAssembly(file));
}
if (args.Language != null)
sessionSettings.FilterSettings.Language = Languages.GetLanguage(args.Language);
return true;
}
void HandleCommandLineArgumentsAfterShowList(CommandLineArguments args)
{
if (args.NavigateTo != null) {
bool found = false;
foreach (LoadedAssembly asm in commandLineLoadedAssemblies) {
AssemblyDefinition def = asm.AssemblyDefinition;
if (def != null) {
MemberReference mr = XmlDocKeyProvider.FindMemberByKey(def.MainModule, args.NavigateTo);
if (mr != null) {
found = true;
JumpToReference(mr);
break;
}
}
}
if (!found) {
AvalonEditTextOutput output = new AvalonEditTextOutput();
output.Write("Cannot find " + args.NavigateTo);
decompilerTextView.Show(output);
}
}
commandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
ILSpySettings spySettings = this.spySettings;
@ -191,23 +266,28 @@ namespace ICSharpCode.ILSpy @@ -191,23 +266,28 @@ namespace ICSharpCode.ILSpy
// This makes the UI come up a bit faster.
this.assemblyList = assemblyListManager.LoadList(spySettings, sessionSettings.ActiveAssemblyList);
ShowAssemblyList(this.assemblyList);
HandleCommandLineArguments(App.CommandLineArguments);
string[] args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++) {
assemblyList.OpenAssembly(args[i]);
}
if (assemblyList.GetAssemblies().Length == 0)
if (assemblyList.GetAssemblies().Length == 0
&& assemblyList.ListName == AssemblyListManager.DefaultListName)
{
LoadInitialAssemblies();
}
ShowAssemblyList(this.assemblyList);
SharpTreeNode node = FindNodeByPath(sessionSettings.ActiveTreeViewPath, true);
if (node != null) {
SelectNode(node);
// only if not showing the about page, perform the update check:
ShowMessageIfUpdatesAvailableAsync(spySettings);
} else {
AboutPage.Display(decompilerTextView);
HandleCommandLineArgumentsAfterShowList(App.CommandLineArguments);
if (App.CommandLineArguments.NavigateTo == null) {
SharpTreeNode node = FindNodeByPath(sessionSettings.ActiveTreeViewPath, true);
if (node != null) {
SelectNode(node);
// only if not showing the about page, perform the update check:
ShowMessageIfUpdatesAvailableAsync(spySettings);
} else {
AboutPage.Display(decompilerTextView);
}
}
}

72
ILSpy/NativeMethods.cs

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
// 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.Text;
using System.Runtime.InteropServices;
namespace ICSharpCode.ILSpy
{
static class NativeMethods
{
public const uint WM_COPYDATA = 0x4a;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, [Out] StringBuilder title, int size);
public static string GetWindowText(IntPtr hWnd, int maxLength)
{
StringBuilder b = new StringBuilder(maxLength + 1);
if (GetWindowText(hWnd, b, b.Capacity) != 0)
return b.ToString();
else
return string.Empty;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessageTimeout(
IntPtr hWnd, uint msg, IntPtr wParam, ref CopyDataStruct lParam,
uint flags, uint timeout, out IntPtr result);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool SetForegroundWindow(IntPtr hWnd);
}
[return: MarshalAs(UnmanagedType.Bool)]
delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
struct CopyDataStruct
{
public IntPtr Padding;
public int Size;
public IntPtr Buffer;
public CopyDataStruct(IntPtr padding, int size, IntPtr buffer)
{
this.Padding = padding;
this.Size = size;
this.Buffer = buffer;
}
}
}

57
ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
// 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.Linq;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
[ExportContextMenuEntry(Header = "Analyze", Icon = "images/Search.png")]
sealed class AnalyzeContextMenuEntry : IContextMenuEntry
{
public bool IsVisible(SharpTreeNode[] selectedNodes)
{
return selectedNodes.All(n => n is IMemberTreeNode);
}
public bool IsEnabled(SharpTreeNode[] selectedNodes)
{
foreach (IMemberTreeNode node in selectedNodes) {
if (!(node.Member is FieldDefinition || node.Member is MethodDefinition))
return false;
}
return true;
}
public void Execute(SharpTreeNode[] selectedNodes)
{
// TODO: figure out when equivalent nodes are already present
// and focus those instead.
foreach (IMemberTreeNode node in selectedNodes) {
FieldDefinition field = node.Member as FieldDefinition;
if (field != null)
MainWindow.Instance.AddToAnalyzer(new AnalyzedFieldNode(field));
MethodDefinition method = node.Member as MethodDefinition;
if (method != null)
MainWindow.Instance.AddToAnalyzer(new AnalyzedMethodTreeNode(method));
}
}
}
}

6
ILSpy/TreeNodes/Analyzer/AnalyzedFieldNode.cs

@ -6,7 +6,7 @@ using Mono.Cecil; @@ -6,7 +6,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedFieldNode : AnalyzerTreeNode
class AnalyzedFieldNode : AnalyzerTreeNode, IMemberTreeNode
{
FieldDefinition analyzedField;
@ -41,5 +41,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -41,5 +41,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
if (!analyzedField.IsLiteral)
this.Children.Add(new AnalyzedFieldAccessNode(analyzedField, true));
}
MemberReference IMemberTreeNode.Member {
get { return analyzedField; }
}
}
}

6
ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs

@ -21,7 +21,7 @@ using Mono.Cecil; @@ -21,7 +21,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
class AnalyzedMethodTreeNode : AnalyzerTreeNode
class AnalyzedMethodTreeNode : AnalyzerTreeNode, IMemberTreeNode
{
MethodDefinition analyzedMethod;
@ -55,5 +55,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -55,5 +55,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
if (analyzedMethod.IsVirtual && !analyzedMethod.IsFinal && !analyzedMethod.DeclaringType.IsInterface) // interfaces are temporarly disabled
this.Children.Add(new AnalyzerMethodOverridesTreeNode(analyzedMethod));
}
MemberReference IMemberTreeNode.Member {
get { return analyzedMethod; }
}
}
}

36
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -94,21 +94,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -94,21 +94,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
public override ContextMenu GetContextMenu()
{
// specific to AssemblyTreeNode
var menu = new ContextMenu();
MenuItem item = new MenuItem() {
Header = "Remove assembly",
Icon = new Image() { Source = Images.Delete }
};
item.Click += delegate { Delete(); };
menu.Items.Add(item);
return menu;
}
Dictionary<TypeDefinition, TypeTreeNode> typeDict = new Dictionary<TypeDefinition, TypeTreeNode>();
protected override void LoadChildren()
@ -235,4 +220,25 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -235,4 +220,25 @@ namespace ICSharpCode.ILSpy.TreeNodes
return true;
}
}
[ExportContextMenuEntry(Header = "_Remove", Icon = "images/Delete.png")]
sealed class RemoveAssembly : IContextMenuEntry
{
public bool IsVisible(SharpTreeNode[] selectedNodes)
{
return selectedNodes.All(n => n is AssemblyTreeNode);
}
public bool IsEnabled(SharpTreeNode[] selectedNodes)
{
return true;
}
public void Execute(SharpTreeNode[] selectedNodes)
{
foreach (var node in selectedNodes) {
node.Delete();
}
}
}
}

7
ILSpy/TreeNodes/BaseTypesTreeNode.cs

@ -17,7 +17,6 @@ @@ -17,7 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Threading;
@ -71,7 +70,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -71,7 +70,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
sealed class BaseTypesEntryNode : ILSpyTreeNode
sealed class BaseTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
{
TypeReference tr;
TypeDefinition def;
@ -139,5 +138,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -139,5 +138,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
language.WriteCommentLine(output, language.TypeToString(tr, true));
}
MemberReference IMemberTreeNode.Member {
get { return tr; }
}
}
}

8
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -3,9 +3,9 @@ @@ -3,9 +3,9 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.Utils;
using Mono.Cecil;
@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
class DerivedTypesEntryNode : ILSpyTreeNode
class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
{
TypeDefinition def;
AssemblyDefinition[] assemblies;
@ -138,5 +138,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -138,5 +138,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
language.WriteCommentLine(output, language.TypeToString(def, true));
}
MemberReference IMemberTreeNode.Member {
get { return def; }
}
}
}

6
ILSpy/TreeNodes/EventTreeNode.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary>
/// Represents an event in the TreeView.
/// </summary>
public sealed class EventTreeNode : ILSpyTreeNode
public sealed class EventTreeNode : ILSpyTreeNode, IMemberTreeNode
{
readonly EventDefinition ev;
@ -73,5 +73,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -73,5 +73,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
language.DecompileEvent(ev, output, options);
}
MemberReference IMemberTreeNode.Member {
get { return ev; }
}
}
}

15
ILSpy/TreeNodes/FieldTreeNode.cs

@ -17,9 +17,7 @@ @@ -17,9 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows.Controls;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.TreeNodes.Analyzer;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
@ -27,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -27,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary>
/// Represents a field in the TreeView.
/// </summary>
public sealed class FieldTreeNode : ILSpyTreeNode
public sealed class FieldTreeNode : ILSpyTreeNode, IMemberTreeNode
{
readonly FieldDefinition field;
@ -71,15 +69,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -71,15 +69,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
language.DecompileField(field, output, options);
}
public override System.Windows.Controls.ContextMenu GetContextMenu()
{
ContextMenu menu = new ContextMenu();
MenuItem item = new MenuItem() { Header = "Analyze", Icon = new Image() { Source = Images.Search } };
item.Click += delegate { MainWindow.Instance.AddToAnalyzer(new AnalyzedFieldNode(field)); };
menu.Items.Add(item);
return menu;
MemberReference IMemberTreeNode.Member {
get { return field; }
}
}
}

33
ILSpy/TreeNodes/IMemberTreeNode.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
// 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 Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
/// <summary>
/// Interface implemented by all tree nodes
/// (both in main tree view and in analyzer)
/// that represent Cecil members.
/// </summary>
public interface IMemberTreeNode
{
MemberReference Member { get; }
}
}

16
ILSpy/TreeNodes/MethodTreeNode.cs

@ -18,10 +18,9 @@ @@ -18,10 +18,9 @@
using System;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.TreeNodes.Analyzer;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
@ -29,7 +28,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -29,7 +28,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary>
/// Tree Node representing a field, method, property, or event.
/// </summary>
public sealed class MethodTreeNode : ILSpyTreeNode
public sealed class MethodTreeNode : ILSpyTreeNode, IMemberTreeNode
{
MethodDefinition method;
@ -96,15 +95,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -96,15 +95,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
return FilterResult.Hidden;
}
public override System.Windows.Controls.ContextMenu GetContextMenu()
{
ContextMenu menu = new ContextMenu();
MenuItem item = new MenuItem() { Header = "Analyze", Icon = new Image() { Source = Images.Search } };
item.Click += delegate { MainWindow.Instance.AddToAnalyzer(new AnalyzedMethodTreeNode(method)); };
menu.Items.Add(item);
return menu;
MemberReference IMemberTreeNode.Member {
get { return method; }
}
}
}

6
ILSpy/TreeNodes/PropertyTreeNode.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary>
/// Represents a property in the TreeView.
/// </summary>
public sealed class PropertyTreeNode : ILSpyTreeNode
public sealed class PropertyTreeNode : ILSpyTreeNode, IMemberTreeNode
{
readonly PropertyDefinition property;
readonly bool isIndexer;
@ -73,5 +73,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -73,5 +73,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
language.DecompileProperty(property, output, options);
}
MemberReference IMemberTreeNode.Member {
get { return property; }
}
}
}

6
ILSpy/TreeNodes/TypeTreeNode.cs

@ -28,7 +28,7 @@ using Mono.Cecil; @@ -28,7 +28,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
public sealed class TypeTreeNode : ILSpyTreeNode
public sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode
{
readonly TypeDefinition type;
readonly AssemblyTreeNode parentAssemblyNode;
@ -210,5 +210,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -210,5 +210,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
#endregion
MemberReference IMemberTreeNode.Member {
get { return type; }
}
}
}

0
ILSpy/XamlResourceNode.cs → ILSpy/TreeNodes/XamlResourceNode.cs

168
ILSpy/XmlDocKeyProvider.cs

@ -0,0 +1,168 @@ @@ -0,0 +1,168 @@
// 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)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
/// <summary>
/// Provides XML documentation tags.
/// </summary>
sealed class XmlDocKeyProvider
{
#region GetKey
public static string GetKey(MemberReference member)
{
StringBuilder b = new StringBuilder();
if (member is TypeReference) {
b.Append("T:");
AppendTypeName(b, (TypeDefinition)member);
} else {
if (member is FieldReference)
b.Append("F:");
else if (member is PropertyDefinition)
b.Append("P:");
else if (member is EventDefinition)
b.Append("E:");
else if (member is MethodReference)
b.Append("M:");
AppendTypeName(b, member.DeclaringType);
b.Append('.');
b.Append(member.Name);
IList<ParameterDefinition> parameters;
if (member is PropertyDefinition) {
parameters = ((PropertyDefinition)member).Parameters;
} else if (member is MethodReference) {
parameters = ((MethodReference)member).Parameters;
} else {
parameters = null;
}
if (parameters != null && parameters.Count > 0) {
b.Append('(');
for (int i = 0; i < parameters.Count; i++) {
if (i > 0) b.Append(',');
AppendTypeName(b, parameters[i].ParameterType);
}
b.Append(')');
}
}
return b.ToString();
}
static void AppendTypeName(StringBuilder b, TypeReference type)
{
if (type is TypeSpecification) {
AppendTypeName(b, ((TypeSpecification)type).ElementType);
ArrayType arrayType = type as ArrayType;
if (arrayType != null) {
b.Append('[');
for (int i = 1; i < arrayType.Dimensions.Count; i++) {
b.Append(',');
}
b.Append(']');
}
ByReferenceType refType = type as ByReferenceType;
if (refType != null) {
b.Append('@');
}
GenericInstanceType giType = type as GenericInstanceType;
if (giType != null) {
b.Append('{');
for (int i = 0; i < giType.GenericArguments.Count; i++) {
if (i > 0) b.Append(',');
AppendTypeName(b, giType.GenericArguments[i]);
}
b.Append('}');
}
PointerType ptrType = type as PointerType;
if (ptrType != null) {
b.Append('*'); // TODO: is this correct?
}
} else {
GenericParameter gp = type as GenericParameter;
if (gp != null) {
b.Append('`');
if (gp.Owner.GenericParameterType == GenericParameterType.Method) {
b.Append('`');
}
b.Append(gp.Position);
} else if (type.DeclaringType != null) {
AppendTypeName(b, type.DeclaringType);
b.Append('.');
b.Append(type.Name);
} else {
b.Append(type.FullName);
}
}
}
#endregion
#region FindMemberByKey
public static MemberReference FindMemberByKey(ModuleDefinition module, string key)
{
if (module == null)
throw new ArgumentNullException("module");
if (key == null || key.Length < 2 || key[1] != ':')
return null;
switch (key[0]) {
case 'T':
return FindType(module, key.Substring(2));
case 'F':
return FindMember(module, key, type => type.Fields);
case 'P':
return FindMember(module, key, type => type.Properties);
case 'E':
return FindMember(module, key, type => type.Events);
case 'M':
return FindMember(module, key, type => type.Methods);
default:
return null;
}
}
static MemberReference FindMember(ModuleDefinition module, string key, Func<TypeDefinition, IEnumerable<MemberReference>> memberSelector)
{
int pos = key.IndexOf('(');
int dotPos;
if (pos > 0) {
dotPos = key.LastIndexOf('.', 0, pos);
} else {
dotPos = key.LastIndexOf('.');
}
TypeDefinition type = FindType(module, key.Substring(2, dotPos - 2));
if (type == null)
return null;
foreach (MemberReference member in memberSelector(type)) {
if (GetKey(member) == key)
return member;
}
return null;
}
static TypeDefinition FindType(ModuleDefinition module, string name)
{
int pos = name.LastIndexOf('.');
string ns;
if (pos >= 0) {
ns = name.Substring(0, pos);
name = name.Substring(pos + 1);
} else {
ns = string.Empty;
}
TypeDefinition type = module.GetType(ns, name);
if (type == null && ns.Length > 0) {
// try if this is a nested type
type = FindType(module, ns);
if (type != null) {
type = type.NestedTypes.FirstOrDefault(t => t.Name == name);
}
}
return type;
}
#endregion
}
}

5
SharpTreeView/SharpTreeNode.cs

@ -157,11 +157,6 @@ namespace ICSharpCode.TreeView @@ -157,11 +157,6 @@ namespace ICSharpCode.TreeView
}
}
public virtual ContextMenu GetContextMenu()
{
return null;
}
#endregion
#region OnChildrenChanged

10
SharpTreeView/SharpTreeViewItem.cs

@ -44,16 +44,6 @@ namespace ICSharpCode.TreeView @@ -44,16 +44,6 @@ namespace ICSharpCode.TreeView
}
}
protected override void OnContextMenuOpening(ContextMenuEventArgs e)
{
ContextMenu = Node.GetContextMenu();
}
protected override void OnContextMenuClosing(ContextMenuEventArgs e)
{
ClearValue(ContextMenuProperty);
}
#region Mouse
Point startPoint;

52
doc/Command Line.txt

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
ILSpy Command Line Arguments
Command line arguments can be either options or file names.
If an argument is a file name, the file will be opened as assembly and added to the current assembly list.
Available options:
/singleInstance If ILSpy is already running, activates the existing instance
and passes command line arguments to that instance.
This is the default value if /list is not used.
/separate Start up a separate ILSpy instance even if it is already running.
/noActivate Do not activate the existing ILSpy instance. This option has no effec
if a new ILSpy instance is being started.
/list:listname Specifies the name of the assembly list that is loaded initially.
When this option is not specified, ILSpy loads the previously opened list.
Specify "/list" (without value) to open the default list.
When this option is used, ILSpy will activate an existing instance
only if it uses the same list as specified.
[Note: Assembly Lists are not yet implemented]
/clearList Clears the assembly list before loading the specified assemblies.
[Note: Assembly Lists are not yet implemented]
/navigateTo:tag Navigates to the member specified by the given XML documentation tag.
The member is searched for only in the assemblies specified on the command line.
Example: 'ILSpy ILSpy.exe /navigateTo:T:ICSharpCode.ILSpy.CommandLineArguments'
/language:name Selects the specified language.
Example: 'ILSpy /language:C#' or 'ILSpy /language:IL'
WM_COPYDATA (SendMessage API):
ILSpy can be controlled by other programs that send a WM_COPYDATA message to its main window.
The message data must be an Unicode (UTF-16) string starting with "ILSpy:\r\n".
All lines except the first ("ILSpy:") in that string are handled as command-line arguments.
There must be exactly one argument per line.
That is, by sending this message:
ILSpy:
C:\Assembly.dll
/navigateTo T:Type
The target ILSpy instance will open C:\Assembly.dll and navigate to the specified type.
ILSpy will return TRUE (1) if it handles the message, and FALSE (0) otherwise.
The /separate option will be ignored; WM_COPYDATA will never start up a new instance.
The /noActivate option has no effect, sending WM_COPYDATA will never activate the window.
Instead, the calling process should use SetForegroundWindow().
If you use /list with WM_COPYDATA, you need to specify /singleInstance as well, otherwise
ILSpy will not handle the message if it has opened a different assembly list.
Loading…
Cancel
Save