Browse Source

Merge remote-tracking branch 'origin/master' into newdecompiler

pull/728/head
Daniel Grunwald 10 years ago
parent
commit
ce05af885c
  1. 3
      BuildTools/UpdateAssemblyInfo/Main.cs
  2. 2
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  3. 6
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  4. 106
      ICSharpCode.Decompiler/Ast/TextTokenWriter.cs
  5. 6
      ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs
  6. 231
      ICSharpCode.Decompiler/CodeMappings.cs
  7. 2
      ICSharpCode.Decompiler/DecompilerException.cs
  8. 18
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  9. 2
      ICSharpCode.Decompiler/ILAst/AsyncDecompiler.cs
  10. 2
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  11. 149
      ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs
  12. 52
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  13. 5
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  14. 19
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_AssemblyCustomAttribute.cs
  15. 19
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs
  16. 21
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributes.cs
  17. 39
      ICSharpCode.Decompiler/Tests/QueryExpressions.cs
  18. 2
      ICSharpCode.Decompiler/Tests/TestCases/Generics.cs
  19. 2
      ICSharpCode.Decompiler/Tests/TestCases/HelloWorld.cs
  20. 19
      ICSharpCode.Decompiler/Tests/Types/S_EnumSamples.cs
  21. 19
      ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs
  22. 27
      ICSharpCode.Decompiler/Tests/UnsafeCode.cs
  23. 48
      ILSpy/AboutPage.cs
  24. 35
      ILSpy/MainWindow.xaml.cs
  25. 1
      ILSpy/Options/DecompilerSettings.cs
  26. 42
      ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs
  27. 29
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  28. 2
      ILSpy/VB/ILSpyEnvironmentProvider.cs
  29. 2
      ILSpy/VB/VBLanguage.cs
  30. 27
      packages/ICSharpCode.Decompiler.nuspec
  31. 5
      packages/build_decompiler_package.cmd

3
BuildTools/UpdateAssemblyInfo/Main.cs

@ -224,7 +224,8 @@ namespace UpdateAssemblyInfo @@ -224,7 +224,8 @@ namespace UpdateAssemblyInfo
string line;
int revNum = BaseCommitRev;
while ((line = p.StandardOutput.ReadLine()) != null) {
if (gitCommitHash == null) {
//keep only line that contains git hash
if (gitCommitHash == null && line != null && line.Length == BaseCommit.Length) {
// first entry is HEAD
gitCommitHash = line;
}

2
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -160,7 +160,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -160,7 +160,7 @@ namespace ICSharpCode.Decompiler.Ast
RunTransformations();
syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
var outputFormatter = new TextOutputFormatter(output, context) { FoldBraces = context.Settings.FoldBraces };
var outputFormatter = new TextTokenWriter(output, context) { FoldBraces = context.Settings.FoldBraces };
var formattingPolicy = context.Settings.CSharpFormattingOptions;
syntaxTree.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy));
}

6
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -126,7 +126,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -126,7 +126,7 @@ namespace ICSharpCode.Decompiler.Ast
astBlock.Statements.InsertBefore(insertionPoint, newVarDecl);
}
astBlock.AddAnnotation(new MemberMapping(methodDef) { LocalVariables = localVariables });
astBlock.AddAnnotation(new MethodDebugSymbols(methodDef) { LocalVariables = localVariables.ToList() });
return astBlock;
}
@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.Ast
if (node is ILLabel) {
yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name };
} else if (node is ILExpression) {
List<ILRange> ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
List<ILRange> ilRanges = ILRange.OrderAndJoin(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
AstNode codeExpr = TransformExpression((ILExpression)node);
if (codeExpr != null) {
codeExpr = codeExpr.WithAnnotation(ilRanges);
@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.Ast
Expression astExpr = node as Expression;
// get IL ranges - used in debugger
List<ILRange> ilRanges = ILRange.OrderAndJoint(expr.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
List<ILRange> ilRanges = ILRange.OrderAndJoin(expr.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
AstNode result;
if (astExpr != null)

106
ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs → ICSharpCode.Decompiler/Ast/TextTokenWriter.cs

@ -27,7 +27,7 @@ using Mono.Cecil; @@ -27,7 +27,7 @@ using Mono.Cecil;
namespace ICSharpCode.Decompiler.Ast
{
public class TextOutputFormatter : IOutputFormatter
public class TextTokenWriter : TokenWriter
{
readonly ITextOutput output;
readonly DecompilerContext context;
@ -37,9 +37,11 @@ namespace ICSharpCode.Decompiler.Ast @@ -37,9 +37,11 @@ namespace ICSharpCode.Decompiler.Ast
bool firstUsingDeclaration;
bool lastUsingDeclaration;
TextLocation? lastEndOfLine;
public bool FoldBraces = false;
public TextOutputFormatter(ITextOutput output, DecompilerContext context)
public TextTokenWriter(ITextOutput output, DecompilerContext context)
{
if (output == null)
throw new ArgumentNullException("output");
@ -49,30 +51,30 @@ namespace ICSharpCode.Decompiler.Ast @@ -49,30 +51,30 @@ namespace ICSharpCode.Decompiler.Ast
this.context = context;
}
public void WriteIdentifier(string identifier)
public override void WriteIdentifier(Identifier identifier)
{
var definition = GetCurrentDefinition();
if (definition != null) {
output.WriteDefinition(identifier, definition, false);
output.WriteDefinition(identifier.Name, definition, false);
return;
}
object memberRef = GetCurrentMemberReference();
if (memberRef != null) {
output.WriteReference(identifier, memberRef);
output.WriteReference(identifier.Name, memberRef);
return;
}
definition = GetCurrentLocalDefinition();
if (definition != null) {
output.WriteDefinition(identifier, definition);
output.WriteDefinition(identifier.Name, definition);
return;
}
memberRef = GetCurrentLocalReference();
if (memberRef != null) {
output.WriteReference(identifier, memberRef, true);
output.WriteReference(identifier.Name, memberRef, true);
return;
}
@ -81,16 +83,14 @@ namespace ICSharpCode.Decompiler.Ast @@ -81,16 +83,14 @@ namespace ICSharpCode.Decompiler.Ast
firstUsingDeclaration = false;
}
output.Write(identifier);
output.Write(identifier.Name);
}
MemberReference GetCurrentMemberReference()
{
AstNode node = nodeStack.Peek();
MemberReference memberRef = node.Annotation<MemberReference>();
if ((node.Role == Roles.Type && node.Parent is ObjectCreateExpression) ||
(memberRef == null && node.Role == Roles.TargetExpression && (node.Parent is InvocationExpression || node.Parent is ObjectCreateExpression)))
{
if (memberRef == null && node.Role == Roles.TargetExpression && (node.Parent is InvocationExpression || node.Parent is ObjectCreateExpression)) {
memberRef = node.Parent.Annotation<MemberReference>();
}
if (node is IdentifierExpression && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression && memberRef != null) {
@ -182,17 +182,12 @@ namespace ICSharpCode.Decompiler.Ast @@ -182,17 +182,12 @@ namespace ICSharpCode.Decompiler.Ast
return null;
}
public void WriteKeyword(string keyword)
public override void WriteKeyword(Role role, string keyword)
{
MemberReference memberRef = GetCurrentMemberReference();
var node = nodeStack.Peek();
if (memberRef != null && node is ConstructorInitializer)
output.WriteReference(keyword, memberRef);
else
output.Write(keyword);
output.Write(keyword);
}
public void WriteToken(string token)
public override void WriteToken(Role role, string token)
{
// Attach member reference to token only if there's no identifier in the current node.
MemberReference memberRef = GetCurrentMemberReference();
@ -203,7 +198,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -203,7 +198,7 @@ namespace ICSharpCode.Decompiler.Ast
output.Write(token);
}
public void Space()
public override void Space()
{
output.Write(' ');
}
@ -230,26 +225,27 @@ namespace ICSharpCode.Decompiler.Ast @@ -230,26 +225,27 @@ namespace ICSharpCode.Decompiler.Ast
braceLevelWithinType--;
}
public void Indent()
public override void Indent()
{
output.Indent();
}
public void Unindent()
public override void Unindent()
{
output.Unindent();
}
public void NewLine()
public override void NewLine()
{
if (lastUsingDeclaration) {
output.MarkFoldEnd();
lastUsingDeclaration = false;
}
lastEndOfLine = output.Location;
output.WriteLine();
}
public void WriteComment(CommentType commentType, string content)
public override void WriteComment(CommentType commentType, string content)
{
switch (commentType) {
case CommentType.SingleLine:
@ -281,7 +277,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -281,7 +277,7 @@ namespace ICSharpCode.Decompiler.Ast
}
}
public void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument)
public override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument)
{
// pre-processor directive must start on its own line
output.Write('#');
@ -293,11 +289,23 @@ namespace ICSharpCode.Decompiler.Ast @@ -293,11 +289,23 @@ namespace ICSharpCode.Decompiler.Ast
output.WriteLine();
}
public override void WritePrimitiveValue(object value, string literalValue = null)
{
new TextWriterTokenWriter(new TextOutputWriter(output)).WritePrimitiveValue(value, literalValue);
}
public override void WritePrimitiveType(string type)
{
output.Write(type);
if (type == "new") {
output.Write("()");
}
}
Stack<TextLocation> startLocations = new Stack<TextLocation>();
MemberMapping currentMemberMapping;
Stack<MemberMapping> parentMemberMappings = new Stack<MemberMapping>();
Stack<MethodDebugSymbols> symbolsStack = new Stack<MethodDebugSymbols>();
public void StartNode(AstNode node)
public override void StartNode(AstNode node)
{
if (nodeStack.Count == 0) {
if (IsUsingDeclaration(node)) {
@ -313,11 +321,10 @@ namespace ICSharpCode.Decompiler.Ast @@ -313,11 +321,10 @@ namespace ICSharpCode.Decompiler.Ast
if (node is EntityDeclaration && node.Annotation<MemberReference>() != null && node.GetChildByRole(Roles.Identifier).IsNull)
output.WriteDefinition("", node.Annotation<MemberReference>(), false);
MemberMapping mapping = node.Annotation<MemberMapping>();
if (mapping != null) {
parentMemberMappings.Push(currentMemberMapping);
currentMemberMapping = mapping;
if (node.Annotation<MethodDebugSymbols>() != null) {
symbolsStack.Push(node.Annotation<MethodDebugSymbols>());
symbolsStack.Peek().StartLocation = startLocations.Peek();
}
}
@ -326,7 +333,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -326,7 +333,7 @@ namespace ICSharpCode.Decompiler.Ast
return node is UsingDeclaration || node is UsingAliasDeclaration;
}
public void EndNode(AstNode node)
public override void EndNode(AstNode node)
{
if (nodeStack.Pop() != node)
throw new InvalidOperationException();
@ -334,26 +341,21 @@ namespace ICSharpCode.Decompiler.Ast @@ -334,26 +341,21 @@ namespace ICSharpCode.Decompiler.Ast
var startLocation = startLocations.Pop();
// code mappings
if (currentMemberMapping != null) {
var ranges = node.Annotation<List<ILRange>>();
if (ranges != null && ranges.Count > 0) {
// add all ranges
foreach (var range in ranges) {
currentMemberMapping.MemberCodeMappings.Add(
new SourceCodeMapping {
ILInstructionOffset = range,
StartLocation = startLocation,
EndLocation = output.Location,
MemberMapping = currentMemberMapping
});
}
}
var ranges = node.Annotation<List<ILRange>>();
if (symbolsStack.Count > 0 && ranges != null && ranges.Count > 0) {
// Ignore the newline which was printed at the end of the statement
TextLocation endLocation = (node is Statement) ? (lastEndOfLine ?? output.Location) : output.Location;
symbolsStack.Peek().SequencePoints.Add(
new SequencePoint() {
ILRanges = ILRange.OrderAndJoin(ranges).ToArray(),
StartLocation = startLocation,
EndLocation = endLocation
});
}
if (node.Annotation<MemberMapping>() != null) {
output.AddDebuggerMemberMapping(currentMemberMapping);
currentMemberMapping = parentMemberMappings.Pop();
if (node.Annotation<MethodDebugSymbols>() != null) {
symbolsStack.Peek().EndLocation = output.Location;
output.AddDebugSymbols(symbolsStack.Pop());
}
}

6
ICSharpCode.Decompiler/CSharp/Transforms/IntroduceUnsafeModifier.cs

@ -35,7 +35,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -35,7 +35,11 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
protected override bool VisitChildren(AstNode node)
{
bool result = false;
for (AstNode child = node.FirstChild; child != null; child = child.NextSibling) {
AstNode next;
for (AstNode child = node.FirstChild; child != null; child = next) {
// Store next to allow the loop to continue
// if the visitor removes/replaces child.
next = child.NextSibling;
result |= child.AcceptVisitor(this);
}
if (result && node is EntityDeclaration && !(node is Accessor)) {

231
ICSharpCode.Decompiler/CodeMappings.cs

@ -17,240 +17,41 @@ @@ -17,240 +17,41 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
/// <summary>
/// Maps the source code to IL.
/// </summary>
public sealed class SourceCodeMapping
/// <summary> Maps method's source code to IL </summary>
public class MethodDebugSymbols
{
/// <summary>
/// Gets or sets the start location of the instruction.
/// </summary>
public MethodDefinition CecilMethod { get; set; }
public List<ILVariable> LocalVariables { get; set; }
public List<SequencePoint> SequencePoints { get; set; }
public TextLocation StartLocation { get; set; }
/// <summary>
/// Gets or sets the end location of the instruction.
/// </summary>
public TextLocation EndLocation { get; set; }
/// <summary>
/// Gets or sets IL Range offset for the source code line. E.g.: 13-19 &lt;-&gt; 135.
/// </summary>
public ILRange ILInstructionOffset { get; set; }
/// <summary>
/// Gets or sets the member mapping this source code mapping belongs to.
/// </summary>
public MemberMapping MemberMapping { get; set; }
/// <summary>
/// Retrieves the array that contains the IL range and the missing gaps between ranges.
/// </summary>
/// <returns>The array representation of the step aranges.</returns>
public int[] ToArray(bool isMatch)
{
var currentList = new List<ILRange>();
// add list for the current source code line
currentList.AddRange(ILRange.OrderAndJoint(MemberMapping.MemberCodeMappings
.FindAll(m => m.StartLocation.Line == this.StartLocation.Line)
.ConvertAll<ILRange>(m => m.ILInstructionOffset)));
if (!isMatch) {
// add inverted
currentList.AddRange(MemberMapping.InvertedList);
} else {
// if the current list contains the last mapping, add also the last gap
var lastInverted = MemberMapping.InvertedList.LastOrDefault();
if (lastInverted != null && lastInverted.From == currentList[currentList.Count - 1].To)
currentList.Add(lastInverted);
}
// set the output
var resultList = new List<int>();
foreach (var element in ILRange.OrderAndJoint(currentList)) {
resultList.Add(element.From);
resultList.Add(element.To);
}
return resultList.ToArray();
}
}
/// <summary>
/// Stores the member information and its source code mappings.
/// </summary>
public sealed class MemberMapping
{
IEnumerable<ILRange> invertedList;
internal MemberMapping()
{
}
public MemberMapping(MethodDefinition method)
{
this.MetadataToken = method.MetadataToken.ToInt32();
this.MemberCodeMappings = new List<SourceCodeMapping>();
this.MemberReference = method;
this.CodeSize = method.Body.CodeSize;
}
/// <summary>
/// Gets or sets the type of the mapping.
/// </summary>
public MemberReference MemberReference { get; internal set; }
/// <summary>
/// Metadata token of the member.
/// </summary>
public int MetadataToken { get; internal set; }
/// <summary>
/// Gets or sets the code size for the member mapping.
/// </summary>
public int CodeSize { get; internal set; }
/// <summary>
/// Gets or sets the source code mappings.
/// </summary>
public List<SourceCodeMapping> MemberCodeMappings { get; internal set; }
/// <summary>
/// Gets or sets the local variables.
/// </summary>
public IEnumerable<ILVariable> LocalVariables { get; internal set; }
/// <summary>
/// Gets the inverted IL Ranges.<br/>
/// E.g.: for (0-9, 11-14, 14-18, 21-25) => (9-11,18-21).
/// </summary>
/// <returns>IL Range inverted list.</returns>
public IEnumerable<ILRange> InvertedList
public MethodDebugSymbols(MethodDefinition methodDef)
{
get {
if (invertedList == null) {
var list = MemberCodeMappings.ConvertAll<ILRange>(
s => new ILRange { From = s.ILInstructionOffset.From, To = s.ILInstructionOffset.To });
invertedList = ILRange.OrderAndJoint(ILRange.Invert(list, CodeSize));
}
return invertedList;
}
this.CecilMethod = methodDef;
this.LocalVariables = new List<ILVariable>();
this.SequencePoints = new List<SequencePoint>();
}
}
/// <summary>
/// Code mappings helper class.
/// </summary>
public static class CodeMappings
public class SequencePoint
{
/// <summary>
/// Gets source code mapping and metadata token based on type name and line number.
/// </summary>
/// <param name="codeMappings">Code mappings storage.</param>
/// <param name="typeName">Member reference name.</param>
/// <param name="lineNumber">Line number.</param>
/// <param name="metadataToken">Metadata token.</param>
/// <returns></returns>
public static SourceCodeMapping GetInstructionByLineNumber(
this MemberMapping codeMapping,
int lineNumber,
out int metadataToken)
{
if (codeMapping == null)
throw new ArgumentException("CodeMappings storage must be valid!");
var map = codeMapping.MemberCodeMappings.Find(m => m.StartLocation.Line == lineNumber);
if (map != null) {
metadataToken = codeMapping.MetadataToken;
return map;
}
metadataToken = 0;
return null;
}
/// <summary>
/// Gets a mapping given a type, a token and an IL offset.
/// </summary>
/// <param name="codeMappings">Code mappings storage.</param>
/// <param name="token">Token.</param>
/// <param name="ilOffset">IL offset.</param>
/// <param name="isMatch">True, if perfect match.</param>
/// <returns>A code mapping.</returns>
public static SourceCodeMapping GetInstructionByTokenAndOffset(
this MemberMapping codeMapping,
int ilOffset,
out bool isMatch)
{
isMatch = false;
if (codeMapping == null)
throw new ArgumentNullException("CodeMappings storage must be valid!");
// try find an exact match
var map = codeMapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= ilOffset && ilOffset < m.ILInstructionOffset.To);
if (map == null) {
// get the immediate next one
map = codeMapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From > ilOffset);
isMatch = false;
if (map == null)
map = codeMapping.MemberCodeMappings.LastOrDefault(); // get the last
return map;
}
isMatch = true;
return map;
}
public ILRange[] ILRanges { get; set; }
public TextLocation StartLocation { get; set; }
public TextLocation EndLocation { get; set; }
public int ILOffset { get { return this.ILRanges[0].From; } }
/// <summary>
/// Gets the source code and type name from metadata token and offset.
/// </summary>
/// <param name="codeMappings">Code mapping storage.</param>
/// <param name="token">Metadata token.</param>
/// <param name="ilOffset">IL offset.</param>
/// <param name="typeName">Type definition.</param>
/// <param name="line">Line number.</param>
/// <remarks>It is possible to exist to different types from different assemblies with the same metadata token.</remarks>
public static bool GetInstructionByTokenAndOffset(
this MemberMapping mapping,
int ilOffset,
out MemberReference member,
out int line)
public override string ToString()
{
member = null;
line = 0;
if (mapping == null)
throw new ArgumentException("CodeMappings storage must be valid!");
var codeMapping = mapping.MemberCodeMappings.Find(
cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To - 1);
if (codeMapping == null) {
codeMapping = mapping.MemberCodeMappings.Find(cm => cm.ILInstructionOffset.From > ilOffset);
if (codeMapping == null) {
codeMapping = mapping.MemberCodeMappings.LastOrDefault();
if (codeMapping == null)
return false;
}
}
member = mapping.MemberReference;
line = codeMapping.StartLocation.Line;
return true;
return string.Join(" ", this.ILRanges) + " " + this.StartLocation + "-" + this.EndLocation;
}
}
}

2
ICSharpCode.Decompiler/DecompilerException.cs

@ -23,7 +23,7 @@ using Mono.Cecil; @@ -23,7 +23,7 @@ using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
/// <summary>
/// Desctiption of DecompilerException.
/// Description of DecompilerException.
/// </summary>
public class DecompilerException : Exception, ISerializable
{

18
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -68,14 +68,13 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -68,14 +68,13 @@ namespace ICSharpCode.Decompiler.Disassembler
inst.WriteTo(output);
/*
if (methodMapping != null) {
if (debugSymbols != null) {
// add IL code mappings - used in debugger
methodMapping.MemberCodeMappings.Add(
new SourceCodeMapping() {
debugSymbols.SequencePoints.Add(
new SequencePoint() {
StartLocation = output.Location,
EndLocation = output.Location,
ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset },
MemberMapping = methodMapping
ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? method.Body.CodeSize : inst.Next.Offset) }
});
}*/
@ -203,13 +202,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -203,13 +202,12 @@ namespace ICSharpCode.Decompiler.Disassembler
inst.WriteTo(output);
/*// add IL code mappings - used in debugger
if (currentMethodMapping != null) {
currentMethodMapping.MemberCodeMappings.Add(
new SourceCodeMapping() {
if (debugSymbols != null) {
debugSymbols.SequencePoints.Add(
new SequencePoint() {
StartLocation = startLocation,
EndLocation = output.Location,
ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset },
MemberMapping = currentMethodMapping
ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? codeSize : inst.Next.Offset) }
});
}*/

2
ICSharpCode.Decompiler/ILAst/AsyncDecompiler.cs

@ -445,7 +445,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -445,7 +445,7 @@ namespace ICSharpCode.Decompiler.ILAst
var tryBody = tryCatchBlock.TryBlock.Body;
if (tryBody.Count == 0)
throw new SymbolicAnalysisFailedException();
StateRangeAnalysis rangeAnalysis = new StateRangeAnalysis(tryBody[0], StateRangeAnalysisMode.AsyncMoveNext, stateField);
StateRangeAnalysis rangeAnalysis = new StateRangeAnalysis(tryBody[0], StateRangeAnalysisMode.AsyncMoveNext, stateField, cachedStateVar);
int tryBodyLength = tryBody.Count;
int posInTryBody = rangeAnalysis.AssignStateRanges(tryBody, tryBodyLength);
rangeAnalysis.EnsureLabelAtPos(tryBody, ref posInTryBody, ref tryBodyLength);

2
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -743,7 +743,7 @@ namespace ICSharpCode.Decompiler.ILAst @@ -743,7 +743,7 @@ namespace ICSharpCode.Decompiler.ILAst
// Convert stack-based IL code to ILAst tree
foreach(ByteCode byteCode in body) {
ILRange ilRange = new ILRange() { From = byteCode.Offset, To = byteCode.EndOffset };
ILRange ilRange = new ILRange(byteCode.Offset, byteCode.EndOffset);
if (byteCode.StackBefore == null) {
// Unreachable code

149
ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs

@ -349,15 +349,15 @@ namespace ICSharpCode.Decompiler.ILAst @@ -349,15 +349,15 @@ namespace ICSharpCode.Decompiler.ILAst
expr.ILRanges.Clear();
continue;
case ILCode.__Brfalse: op = ILCode.LogicNot; break;
case ILCode.__Beq: op = ILCode.Ceq; break;
case ILCode.__Beq: op = ILCode.Ceq; break;
case ILCode.__Bne_Un: op = ILCode.Cne; break;
case ILCode.__Bgt: op = ILCode.Cgt; break;
case ILCode.__Bgt: op = ILCode.Cgt; break;
case ILCode.__Bgt_Un: op = ILCode.Cgt_Un; break;
case ILCode.__Ble: op = ILCode.Cle; break;
case ILCode.__Ble: op = ILCode.Cle; break;
case ILCode.__Ble_Un: op = ILCode.Cle_Un; break;
case ILCode.__Blt: op = ILCode.Clt; break;
case ILCode.__Blt: op = ILCode.Clt; break;
case ILCode.__Blt_Un: op = ILCode.Clt_Un; break;
case ILCode.__Bge: op = ILCode.Cge; break;
case ILCode.__Bge: op = ILCode.Cge; break;
case ILCode.__Bge_Un: op = ILCode.Cge_Un; break;
default:
continue;
@ -436,9 +436,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -436,9 +436,9 @@ namespace ICSharpCode.Decompiler.ILAst
// Might be 'newobj(SomeDelegate, target, ldvirtftn(F, target))'.
ILVariable target;
if (expr.Arguments[0].Match(ILCode.Ldloc, out target)
&& expr.Arguments[1].Code == ILCode.Ldvirtftn
&& expr.Arguments[1].Arguments.Count == 1
&& expr.Arguments[1].Arguments[0].MatchLdloc(target))
&& expr.Arguments[1].Code == ILCode.Ldvirtftn
&& expr.Arguments[1].Arguments.Count == 1
&& expr.Arguments[1].Arguments[0].MatchLdloc(target))
{
// Remove the 'target' argument from the ldvirtftn instruction.
// It's not needed in the translation to C#, and needs to be eliminated so that the target expression
@ -473,9 +473,9 @@ namespace ICSharpCode.Decompiler.ILAst @@ -473,9 +473,9 @@ namespace ICSharpCode.Decompiler.ILAst
// Start a new basic block if necessary
if (currNode is ILLabel ||
currNode is ILTryCatchBlock || // Counts as label
lastNode.IsConditionalControlFlow() ||
lastNode.IsUnconditionalControlFlow())
currNode is ILTryCatchBlock || // Counts as label
lastNode.IsConditionalControlFlow() ||
lastNode.IsUnconditionalControlFlow())
{
// Try to reuse the label
ILLabel label = currNode as ILLabel ?? new ILLabel() { Name = "Block_" + (nextLabelIndex++).ToString() };
@ -669,32 +669,86 @@ namespace ICSharpCode.Decompiler.ILAst @@ -669,32 +669,86 @@ namespace ICSharpCode.Decompiler.ILAst
});
}
static void HandlePointerArithmetic(ILNode method)
void HandlePointerArithmetic(ILNode method)
{
foreach (ILExpression expr in method.GetSelfAndChildrenRecursive<ILExpression>()) {
List<ILExpression> args = expr.Arguments;
switch (expr.Code) {
case ILCode.Localloc:
args[0] = DivideBySize(args[0], ((PointerType)expr.InferredType).ElementType);
{
PointerType type = expr.InferredType as PointerType;
if (type != null) {
ILExpression arg0 = args[0];
ILExpression expr2 = expr;
DivideOrMultiplyBySize(ref expr2, ref arg0, type.ElementType, true);
// expr shouldn't change
if (expr2 != expr)
throw new InvalidOperationException();
args[0] = arg0;
}
break;
}
case ILCode.Add:
case ILCode.Add_Ovf:
case ILCode.Add_Ovf_Un:
{
ILExpression arg0 = args[0];
ILExpression arg1 = args[1];
if (expr.InferredType is PointerType) {
if (args[0].ExpectedType is PointerType)
args[1] = DivideBySize(args[1], ((PointerType)expr.InferredType).ElementType);
else if (args[1].ExpectedType is PointerType)
args[0] = DivideBySize(args[0], ((PointerType)expr.InferredType).ElementType);
if (arg0.ExpectedType is PointerType) {
DivideOrMultiplyBySize(ref arg0, ref arg1, ((PointerType)expr.InferredType).ElementType, true);
} else if (arg1.ExpectedType is PointerType)
DivideOrMultiplyBySize(ref arg1, ref arg0, ((PointerType)expr.InferredType).ElementType, true);
}
args[0] = arg0;
args[1] = arg1;
break;
}
case ILCode.Sub:
case ILCode.Sub_Ovf:
case ILCode.Sub_Ovf_Un:
{
ILExpression arg0 = args[0];
ILExpression arg1 = args[1];
if (expr.InferredType is PointerType) {
if (args[0].ExpectedType is PointerType)
args[1] = DivideBySize(args[1], ((PointerType)expr.InferredType).ElementType);
if (arg0.ExpectedType is PointerType && !(arg1.InferredType is PointerType))
DivideOrMultiplyBySize(ref arg0, ref arg1, ((PointerType)expr.InferredType).ElementType, true);
}
args[0] = arg0;
args[1] = arg1;
break;
}
case ILCode.Conv_I8:
{
ILExpression arg0 = args[0];
// conv.i8(div:intptr(p0 - p1))
if (arg0.Code == ILCode.Div && arg0.InferredType.FullName == "System.IntPtr")
{
ILExpression dividend = arg0.Arguments[0];
if (dividend.InferredType.FullName == "System.IntPtr" &&
(dividend.Code == ILCode.Sub || dividend.Code == ILCode.Sub_Ovf || dividend.Code == ILCode.Sub_Ovf_Un))
{
PointerType pointerType0 = dividend.Arguments[0].InferredType as PointerType;
PointerType pointerType1 = dividend.Arguments[1].InferredType as PointerType;
if (pointerType0 != null && pointerType1 != null) {
if (pointerType0.ElementType.FullName == "System.Void" ||
pointerType0.ElementType.FullName != pointerType1.ElementType.FullName) {
pointerType0 = pointerType1 = new PointerType(typeSystem.Byte);
dividend.Arguments[0] = Cast(dividend.Arguments[0], pointerType0);
dividend.Arguments[1] = Cast(dividend.Arguments[1], pointerType1);
}
DivideOrMultiplyBySize(ref dividend, ref arg0, pointerType0.ElementType, false);
// dividend shouldn't change
if (args[0].Arguments[0] != dividend)
throw new InvalidOperationException();
}
}
}
args[0] = arg0;
break;
}
}
}
}
@ -720,12 +774,24 @@ namespace ICSharpCode.Decompiler.ILAst @@ -720,12 +774,24 @@ namespace ICSharpCode.Decompiler.ILAst
return expr;
}
static ILExpression DivideBySize(ILExpression expr, TypeReference type)
static ILExpression Cast(ILExpression expr, TypeReference type)
{
return new ILExpression(ILCode.Castclass, type, expr)
{
InferredType = type,
ExpectedType = type
};
}
void DivideOrMultiplyBySize(ref ILExpression pointerExpr, ref ILExpression adjustmentExpr, TypeReference elementType, bool divide)
{
expr = UnwrapIntPtrCast(expr);
adjustmentExpr = UnwrapIntPtrCast(adjustmentExpr);
ILExpression sizeOfExpression;
switch (TypeAnalysis.GetInformationAmount(type)) {
switch (TypeAnalysis.GetInformationAmount(elementType)) {
case 0: // System.Void
pointerExpr = Cast(pointerExpr, new PointerType(typeSystem.Byte));
goto case 1;
case 1:
case 8:
sizeOfExpression = new ILExpression(ILCode.Ldc_I4, 1);
@ -740,34 +806,41 @@ namespace ICSharpCode.Decompiler.ILAst @@ -740,34 +806,41 @@ namespace ICSharpCode.Decompiler.ILAst
sizeOfExpression = new ILExpression(ILCode.Ldc_I4, 8);
break;
default:
sizeOfExpression = new ILExpression(ILCode.Sizeof, type);
sizeOfExpression = new ILExpression(ILCode.Sizeof, elementType);
break;
}
if (expr.Code == ILCode.Mul || expr.Code == ILCode.Mul_Ovf || expr.Code == ILCode.Mul_Ovf_Un) {
ILExpression mulArg = expr.Arguments[1];
if (mulArg.Code == sizeOfExpression.Code && sizeOfExpression.Operand.Equals(mulArg.Operand))
return UnwrapIntPtrCast(expr.Arguments[0]);
if (divide && (adjustmentExpr.Code == ILCode.Mul || adjustmentExpr.Code == ILCode.Mul_Ovf || adjustmentExpr.Code == ILCode.Mul_Ovf_Un) ||
!divide && (adjustmentExpr.Code == ILCode.Div || adjustmentExpr.Code == ILCode.Div_Un)) {
ILExpression mulArg = adjustmentExpr.Arguments[1];
if (mulArg.Code == sizeOfExpression.Code && sizeOfExpression.Operand.Equals(mulArg.Operand)) {
adjustmentExpr = UnwrapIntPtrCast(adjustmentExpr.Arguments[0]);
return;
}
}
if (expr.Code == sizeOfExpression.Code) {
if (sizeOfExpression.Operand.Equals(expr.Operand))
return new ILExpression(ILCode.Ldc_I4, 1);
if (adjustmentExpr.Code == sizeOfExpression.Code) {
if (sizeOfExpression.Operand.Equals(adjustmentExpr.Operand)) {
adjustmentExpr = new ILExpression(ILCode.Ldc_I4, 1);
return;
}
if (expr.Code == ILCode.Ldc_I4) {
int offsetInBytes = (int)expr.Operand;
if (adjustmentExpr.Code == ILCode.Ldc_I4) {
int offsetInBytes = (int)adjustmentExpr.Operand;
int elementSize = (int)sizeOfExpression.Operand;
int offsetInElements = offsetInBytes / elementSize;
// ensure integer division
if (offsetInElements * elementSize == offsetInBytes) {
expr.Operand = offsetInElements;
return expr;
if (offsetInBytes % elementSize != 0) {
pointerExpr = Cast(pointerExpr, new PointerType(typeSystem.Byte));
return;
}
adjustmentExpr.Operand = offsetInBytes / elementSize;
return;
}
}
return new ILExpression(ILCode.Div_Un, null, expr, sizeOfExpression);
if (!(sizeOfExpression.Code == ILCode.Ldc_I4 && (int)sizeOfExpression.Operand == 1))
adjustmentExpr = new ILExpression(divide ? ILCode.Div_Un : ILCode.Mul, null, adjustmentExpr, sizeOfExpression);
}
public static void ReplaceVariables(ILNode node, Func<ILVariable, ILVariable> variableMapping)

52
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -221,37 +221,43 @@ namespace ICSharpCode.Decompiler.ILAst @@ -221,37 +221,43 @@ namespace ICSharpCode.Decompiler.ILAst
}
}
public class ILRange
public struct ILRange
{
public int From;
public int To; // Exlusive
public readonly int From;
public readonly int To; // Exlusive
public ILRange(int @from, int to)
{
this.From = @from;
this.To = to;
}
public override string ToString()
{
return string.Format("{0}-{1}", From.ToString("X"), To.ToString("X"));
return string.Format("{0:X2}-{1:X2}", From, To);
}
public static List<ILRange> OrderAndJoint(IEnumerable<ILRange> input)
public static List<ILRange> OrderAndJoin(IEnumerable<ILRange> input)
{
if (input == null)
throw new ArgumentNullException("Input is null!");
List<ILRange> ranges = input.Where(r => r != null).OrderBy(r => r.From).ToList();
for (int i = 0; i < ranges.Count - 1;) {
ILRange curr = ranges[i];
ILRange next = ranges[i + 1];
// Merge consequtive ranges if they intersect
if (curr.From <= next.From && next.From <= curr.To) {
curr.To = Math.Max(curr.To, next.To);
ranges.RemoveAt(i + 1);
} else {
i++;
List<ILRange> result = new List<ILRange>();
foreach(ILRange curr in input.OrderBy(r => r.From)) {
if (result.Count > 0) {
// Merge consequtive ranges if possible
ILRange last = result[result.Count - 1];
if (curr.From <= last.To) {
result[result.Count - 1] = new ILRange(last.From, Math.Max(last.To, curr.To));
continue;
}
}
result.Add(curr);
}
return ranges;
return result;
}
public static IEnumerable<ILRange> Invert(IEnumerable<ILRange> input, int codeSize)
public static List<ILRange> Invert(IEnumerable<ILRange> input, int codeSize)
{
if (input == null)
throw new ArgumentNullException("Input is null!");
@ -259,23 +265,25 @@ namespace ICSharpCode.Decompiler.ILAst @@ -259,23 +265,25 @@ namespace ICSharpCode.Decompiler.ILAst
if (codeSize <= 0)
throw new ArgumentException("Code size must be grater than 0");
var ordered = OrderAndJoint(input);
List<ILRange> ordered = OrderAndJoin(input);
List<ILRange> result = new List<ILRange>(ordered.Count + 1);
if (ordered.Count == 0) {
yield return new ILRange() { From = 0, To = codeSize };
result.Add(new ILRange(0, codeSize));
} else {
// Gap before the first element
if (ordered.First().From != 0)
yield return new ILRange() { From = 0, To = ordered.First().From };
result.Add(new ILRange(0, ordered.First().From));
// Gaps between elements
for (int i = 0; i < ordered.Count - 1; i++)
yield return new ILRange() { From = ordered[i].To, To = ordered[i + 1].From };
result.Add(new ILRange(ordered[i].To, ordered[i + 1].From));
// Gap after the last element
Debug.Assert(ordered.Last().To <= codeSize);
if (ordered.Last().To != codeSize)
yield return new ILRange() { From = ordered.Last().To, To = codeSize };
result.Add(new ILRange(ordered.Last().To, codeSize));
}
return result;
}
}

5
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -1044,7 +1044,10 @@ namespace ICSharpCode.Decompiler.ILAst @@ -1044,7 +1044,10 @@ namespace ICSharpCode.Decompiler.ILAst
TypeReference leftPreferred = DoInferTypeForExpression(left, expectedType);
if (leftPreferred is PointerType) {
left.InferredType = left.ExpectedType = leftPreferred;
InferTypeForExpression(right, null);
TypeReference rightPreferred = InferTypeForExpression(right, null);
// subtracting two pointers is not a pointer
if (rightPreferred is PointerType)
return typeSystem.IntPtr;
return leftPreferred;
}
if (IsEnum(leftPreferred)) {

19
ICSharpCode.Decompiler/Tests/CustomAttributes/S_AssemblyCustomAttribute.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) 2014 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;

19
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.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) 2014 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.
//$CS
using System;

21
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributes.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) 2014 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;
@ -55,4 +70,4 @@ namespace aa @@ -55,4 +70,4 @@ namespace aa
{
}
}
}
}

39
ICSharpCode.Decompiler/Tests/QueryExpressions.cs

@ -52,8 +52,7 @@ public class QueryExpressions @@ -52,8 +52,7 @@ public class QueryExpressions
public object MultipleWhere()
{
return
from c in this.customers
return from c in this.customers
where c.Orders.Count<QueryExpressions.Order>() > 10
where c.Country == "DE"
select c;
@ -61,8 +60,7 @@ public class QueryExpressions @@ -61,8 +60,7 @@ public class QueryExpressions
public object SelectManyFollowedBySelect()
{
return
from c in this.customers
return from c in this.customers
from o in c.Orders
select new
{
@ -74,8 +72,7 @@ public class QueryExpressions @@ -74,8 +72,7 @@ public class QueryExpressions
public object SelectManyFollowedByOrderBy()
{
return
from c in this.customers
return from c in this.customers
from o in c.Orders
orderby o.Total descending
select new
@ -88,8 +85,7 @@ public class QueryExpressions @@ -88,8 +85,7 @@ public class QueryExpressions
public object MultipleSelectManyFollowedBySelect()
{
return
from c in this.customers
return from c in this.customers
from o in c.Orders
from d in o.Details
select new
@ -102,8 +98,7 @@ public class QueryExpressions @@ -102,8 +98,7 @@ public class QueryExpressions
public object MultipleSelectManyFollowedByLet()
{
return
from c in this.customers
return from c in this.customers
from o in c.Orders
from d in o.Details
let x = d.Quantity * d.UnitPrice
@ -117,8 +112,7 @@ public class QueryExpressions @@ -117,8 +112,7 @@ public class QueryExpressions
public object FromLetWhereSelect()
{
return
from o in this.orders
return from o in this.orders
let t = o.Details.Sum((QueryExpressions.OrderDetail d) => d.UnitPrice * d.Quantity)
where t >= 1000m
select new
@ -130,8 +124,7 @@ public class QueryExpressions @@ -130,8 +124,7 @@ public class QueryExpressions
public object MultipleLet()
{
return
from a in this.customers
return from a in this.customers
let b = a.Country
let c = a.Name
select b + c;
@ -139,8 +132,7 @@ public class QueryExpressions @@ -139,8 +132,7 @@ public class QueryExpressions
public object Join()
{
return
from c in this.customers
return from c in this.customers
join o in this.orders on c.CustomerID equals o.CustomerID
select new
{
@ -152,8 +144,7 @@ public class QueryExpressions @@ -152,8 +144,7 @@ public class QueryExpressions
public object JoinInto()
{
return
from c in this.customers
return from c in this.customers
join o in this.orders on c.CustomerID equals o.CustomerID into co
let n = co.Count<QueryExpressions.Order>()
where n >= 10
@ -166,31 +157,27 @@ public class QueryExpressions @@ -166,31 +157,27 @@ public class QueryExpressions
public object OrderBy()
{
return
from o in this.orders
return from o in this.orders
orderby o.Customer.Name, o.Total descending
select o;
}
public object GroupBy()
{
return
from c in this.customers
return from c in this.customers
group c.Name by c.Country;
}
public object ExplicitType()
{
return
from QueryExpressions.Customer c in this.customers
return from QueryExpressions.Customer c in this.customers
where c.City == "London"
select c;
}
public object QueryContinuation()
{
return
from c in this.customers
return from c in this.customers
group c by c.Country into g
select new
{

2
ICSharpCode.Decompiler/Tests/TestCases/Generics.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// Copyright (c) 2010-2013 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

2
ICSharpCode.Decompiler/Tests/TestCases/HelloWorld.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// Copyright (c) 2010-2013 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

19
ICSharpCode.Decompiler/Tests/Types/S_EnumSamples.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) 2014 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.
//$CS
using System;

19
ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.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) 2014 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.
//$CS
using System;

27
ICSharpCode.Decompiler/Tests/UnsafeCode.cs

@ -130,7 +130,7 @@ public class UnsafeCode @@ -130,7 +130,7 @@ public class UnsafeCode
public unsafe byte* PointerArithmetic2(long* p, int y, int x)
{
return (byte*)p + (y * x);
return (byte*)((short*)p + (y * x));
}
public unsafe long* PointerArithmetic3(long* p)
@ -138,6 +138,31 @@ public class UnsafeCode @@ -138,6 +138,31 @@ public class UnsafeCode
return (long*)((byte*)p + 3);
}
public unsafe long* PointerArithmetic4(void* p)
{
return (long*)((byte*)p + 3);
}
public unsafe int PointerArithmetic5(void* p, byte* q, int i)
{
return (int)(q[i] + *(byte*)p);
}
public unsafe int PointerSubtraction(long* p, long* q)
{
return (int)((long)(p - q));
}
public unsafe int PointerSubtraction2(long* p, short* q)
{
return (int)((long)((byte*)p - (byte*)q));
}
public unsafe int PointerSubtraction3(void* p, void* q)
{
return (int)((long)((byte*)p - (byte*)q));
}
unsafe ~UnsafeCode()
{
this.PassPointerAsRefParameter(this.NullPointer);

48
ILSpy/AboutPage.cs

@ -179,30 +179,32 @@ namespace ICSharpCode.ILSpy @@ -179,30 +179,32 @@ namespace ICSharpCode.ILSpy
static Task<AvailableVersionInfo> GetLatestVersionAsync()
{
var tcs = new TaskCompletionSource<AvailableVersionInfo>();
WebClient wc = new WebClient();
IWebProxy systemWebProxy = WebRequest.GetSystemWebProxy();
systemWebProxy.Credentials = CredentialCache.DefaultCredentials;
wc.Proxy = systemWebProxy;
wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) {
if (e.Error != null) {
tcs.SetException(e.Error);
} else {
try {
XDocument doc = XDocument.Load(new MemoryStream(e.Result));
var bands = doc.Root.Elements("band");
var currentBand = bands.FirstOrDefault(b => (string)b.Attribute("id") == band) ?? bands.First();
Version version = new Version((string)currentBand.Element("latestVersion"));
string url = (string)currentBand.Element("downloadUrl");
if (!(url.StartsWith("http://", StringComparison.Ordinal) || url.StartsWith("https://", StringComparison.Ordinal)))
url = null; // don't accept non-urls
latestAvailableVersion = new AvailableVersionInfo { Version = version, DownloadUrl = url };
tcs.SetResult(latestAvailableVersion);
} catch (Exception ex) {
tcs.SetException(ex);
new Action(() => {
WebClient wc = new WebClient();
IWebProxy systemWebProxy = WebRequest.GetSystemWebProxy();
systemWebProxy.Credentials = CredentialCache.DefaultCredentials;
wc.Proxy = systemWebProxy;
wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) {
if (e.Error != null) {
tcs.SetException(e.Error);
} else {
try {
XDocument doc = XDocument.Load(new MemoryStream(e.Result));
var bands = doc.Root.Elements("band");
var currentBand = bands.FirstOrDefault(b => (string)b.Attribute("id") == band) ?? bands.First();
Version version = new Version((string)currentBand.Element("latestVersion"));
string url = (string)currentBand.Element("downloadUrl");
if (!(url.StartsWith("http://", StringComparison.Ordinal) || url.StartsWith("https://", StringComparison.Ordinal)))
url = null; // don't accept non-urls
latestAvailableVersion = new AvailableVersionInfo { Version = version, DownloadUrl = url };
tcs.SetResult(latestAvailableVersion);
} catch (Exception ex) {
tcs.SetException(ex);
}
}
}
};
wc.DownloadDataAsync(UpdateUrl);
};
wc.DownloadDataAsync(UpdateUrl);
}).BeginInvoke(null, null);
return tcs.Task;
}

35
ILSpy/MainWindow.xaml.cs

@ -570,21 +570,40 @@ namespace ICSharpCode.ILSpy @@ -570,21 +570,40 @@ namespace ICSharpCode.ILSpy
public ILSpyTreeNode FindTreeNode(object reference)
{
if (reference is TypeReference) {
if (reference is TypeReference)
{
return assemblyListTreeNode.FindTypeNode(((TypeReference)reference).Resolve());
} else if (reference is MethodReference) {
}
else if (reference is MethodReference)
{
return assemblyListTreeNode.FindMethodNode(((MethodReference)reference).Resolve());
} else if (reference is FieldReference) {
}
else if (reference is FieldReference)
{
return assemblyListTreeNode.FindFieldNode(((FieldReference)reference).Resolve());
} else if (reference is PropertyReference) {
}
else if (reference is PropertyReference)
{
return assemblyListTreeNode.FindPropertyNode(((PropertyReference)reference).Resolve());
} else if (reference is EventReference) {
}
else if (reference is EventReference)
{
return assemblyListTreeNode.FindEventNode(((EventReference)reference).Resolve());
} else if (reference is AssemblyDefinition) {
}
else if (reference is AssemblyDefinition)
{
return assemblyListTreeNode.FindAssemblyNode((AssemblyDefinition)reference);
} else if (reference is ModuleDefinition) {
}
else if (reference is ModuleDefinition)
{
return assemblyListTreeNode.FindAssemblyNode((ModuleDefinition)reference);
} else {
}
else if (reference is Resource)
{
return assemblyListTreeNode.FindResourceNode((Resource)reference);
}
else
{
return null;
}
}

1
ILSpy/Options/DecompilerSettings.cs

@ -321,6 +321,7 @@ namespace ICSharpCode.ILSpy.Options @@ -321,6 +321,7 @@ namespace ICSharpCode.ILSpy.Options
if (csharpFormattingOptions == null) {
csharpFormattingOptions = FormattingOptionsFactory.CreateAllman();
csharpFormattingOptions.IndentSwitchBody = false;
csharpFormattingOptions.ArrayInitializerWrapping = Wrapping.WrapAlways;
}
return csharpFormattingOptions;
}

42
ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs

@ -67,23 +67,31 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -67,23 +67,31 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public static void Analyze(MemberReference member)
{
TypeDefinition type = null;
if (member is TypeReference)
type = ((TypeReference)member).Resolve();
if (type != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedTypeTreeNode(type.Resolve()));
FieldDefinition field = member as FieldDefinition;
if (field != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedFieldTreeNode(field));
MethodDefinition method = member as MethodDefinition;
if (method != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedMethodTreeNode(method));
var propertyAnalyzer = AnalyzedPropertyTreeNode.TryCreateAnalyzer(member);
if (propertyAnalyzer != null)
AnalyzerTreeView.Instance.ShowOrFocus(propertyAnalyzer);
var eventAnalyzer = AnalyzedEventTreeNode.TryCreateAnalyzer(member);
if (eventAnalyzer != null)
AnalyzerTreeView.Instance.ShowOrFocus(eventAnalyzer);
if (member is TypeReference) {
TypeDefinition type = ((TypeReference)member).Resolve();
if (type != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedTypeTreeNode(type));
}
else if (member is FieldReference) {
FieldDefinition field = ((FieldReference)member).Resolve();
if (field != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedFieldTreeNode(field));
}
else if (member is MethodReference) {
MethodDefinition method = ((MethodReference)member).Resolve();
if (method != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedMethodTreeNode(method));
}
else if (member is PropertyReference) {
PropertyDefinition property = ((PropertyReference)member).Resolve();
if (property != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedPropertyTreeNode(property));
}
else if (member is EventReference) {
EventDefinition @event = ((EventReference)member).Resolve();
if (@event != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedEventTreeNode(@event));
}
}
}
}

29
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -130,9 +130,34 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -130,9 +130,34 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
#region Find*Node
#region Find*Node
public AssemblyTreeNode FindAssemblyNode(ModuleDefinition module)
public ILSpyTreeNode FindResourceNode(Resource resource)
{
if (resource == null)
return null;
foreach (AssemblyTreeNode node in this.Children)
{
if (node.LoadedAssembly.IsLoaded)
{
node.EnsureLazyChildren();
foreach (var item in node.Children.OfType<ResourceListTreeNode>())
{
var founded = item.Children.OfType<ResourceTreeNode>().Where(x => x.Resource == resource).FirstOrDefault();
if (founded != null)
return founded;
var foundedResEntry = item.Children.OfType<ResourceEntryNode>().Where(x => resource.Name.Equals(x.Text)).FirstOrDefault();
if (foundedResEntry != null)
return foundedResEntry;
}
}
}
return null;
}
public AssemblyTreeNode FindAssemblyNode(ModuleDefinition module)
{
if (module == null)
return null;

2
ILSpy/VB/ILSpyEnvironmentProvider.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.ILSpy.VB @@ -35,7 +35,7 @@ namespace ICSharpCode.ILSpy.VB
}
}
readonly CecilLoader loader = new CecilLoader();
//readonly CecilLoader loader = new CecilLoader();
public string GetTypeNameForAttribute(ICSharpCode.NRefactory.CSharp.Attribute attribute)
{

2
ILSpy/VB/VBLanguage.cs

@ -80,7 +80,7 @@ namespace ICSharpCode.ILSpy.VB @@ -80,7 +80,7 @@ namespace ICSharpCode.ILSpy.VB
output.WriteLine();
ModuleDefinition mainModule = assembly.ModuleDefinition;
if (mainModule.Types.Count > 0) {
output.Write("// Global type: ");
output.Write("' Global type: ");
output.WriteReference(mainModule.Types[0].FullName, mainModule.Types[0]);
output.WriteLine();
}

27
packages/ICSharpCode.Decompiler.nuspec

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>ICSharpCode.Decompiler</id>
<version>2.3.0</version>
<title>ILSpy Decompiler Engine</title>
<authors>Daniel Grunwald, David Srbecky, Ed Harvey, Siegfried Pammer</authors>
<owners>Daniel Grunwald, SharpDevelop</owners>
<licenseUrl>http://www.opensource.org/licenses/mit-license.php</licenseUrl>
<projectUrl>https://github.com/icsharpcode/ILSpy/</projectUrl>
<iconUrl>http://ilspy.net/images/icon32.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>ICSharpCode.Decompiler is the decompiler engine used in ILSpy.</description>
<!--<releaseNotes></releaseNotes>-->
<copyright>Copyright 2011-2015 AlphaSierraPapa</copyright>
<tags>C# Decompiler ILSpy</tags>
<dependencies>
<dependency id="Mono.Cecil" version="0.9.5.4" />
<dependency id="ICSharpCode.NRefactory" version="5.5.1" />
</dependencies>
</metadata>
<files>
<file src="..\ICSharpCode.Decompiler\bin\NuGet-Release\ICSharpCode.Decompiler.dll" target="lib\Net40" />
<file src="..\ICSharpCode.Decompiler\bin\NuGet-Release\ICSharpCode.Decompiler.pdb" target="lib\Net40" />
<file src="..\ICSharpCode.Decompiler\**\*.cs" target="src\ICSharpCode.Decompiler" />
</files>
</package>

5
packages/build_decompiler_package.cmd

@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
rmdir /s /q %~dp0..\ICSharpCode.Decompiler\bin
rmdir /s /q %~dp0..\ICSharpCode.Decompiler\obj
nuget restore %~dp0..\ILSpy.sln || exit /b 1
%windir%\microsoft.net\framework\v4.0.30319\msbuild %~dp0..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj /p:Configuration=Release "/p:Platform=Any CPU" /p:BuildNuGetPackage=True || exit /b 1
nuget pack %~dp0ICSharpCode.Decompiler.nuspec /Symbols || exit /b 1
Loading…
Cancel
Save