Browse Source

ICSharpCode.Decompiler: Merge changes from SharpDevelop to ILSpy.

pull/596/merge
Daniel Grunwald 11 years ago
parent
commit
02a500e762
  1. 2
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 6
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  3. 106
      ICSharpCode.Decompiler/Ast/TextTokenWriter.cs
  4. 8
      ICSharpCode.Decompiler/Ast/Transforms/IntroduceUsingDeclarations.cs
  5. 231
      ICSharpCode.Decompiler/CodeMappings.cs
  6. 2
      ICSharpCode.Decompiler/DecompilerException.cs
  7. 4
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  8. 26
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  9. 23
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  10. 2
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  11. 2
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  12. 52
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  13. 2
      ICSharpCode.Decompiler/ITextOutput.cs
  14. 2
      ICSharpCode.Decompiler/PlainTextOutput.cs
  15. 19
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_AssemblyCustomAttribute.cs
  16. 19
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs
  17. 21
      ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributes.cs
  18. 2
      ICSharpCode.Decompiler/Tests/DoubleConstants.cs
  19. 19
      ICSharpCode.Decompiler/Tests/Types/S_EnumSamples.cs
  20. 19
      ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs

2
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -160,7 +160,7 @@ namespace ICSharpCode.Decompiler.Ast
RunTransformations(); RunTransformations();
syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); 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; var formattingPolicy = context.Settings.CSharpFormattingOptions;
syntaxTree.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy)); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy));
} }

6
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

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

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

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

8
ICSharpCode.Decompiler/Ast/Transforms/IntroduceUsingDeclarations.cs

@ -114,8 +114,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
{ {
string oldNamespace = currentNamespace; string oldNamespace = currentNamespace;
foreach (Identifier ident in namespaceDeclaration.Identifiers) { foreach (string ident in namespaceDeclaration.Identifiers) {
currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident.Name); currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident);
transform.declaredNamespaces.Add(currentNamespace); transform.declaredNamespaces.Add(currentNamespace);
} }
base.VisitNamespaceDeclaration(namespaceDeclaration, data); base.VisitNamespaceDeclaration(namespaceDeclaration, data);
@ -153,8 +153,8 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
{ {
string oldNamespace = currentNamespace; string oldNamespace = currentNamespace;
foreach (Identifier ident in namespaceDeclaration.Identifiers) { foreach (string ident in namespaceDeclaration.Identifiers) {
currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident.Name); currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident);
} }
base.VisitNamespaceDeclaration(namespaceDeclaration, data); base.VisitNamespaceDeclaration(namespaceDeclaration, data);
currentNamespace = oldNamespace; currentNamespace = oldNamespace;

231
ICSharpCode.Decompiler/CodeMappings.cs

@ -17,240 +17,41 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.ILAst; using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil; using Mono.Cecil;
namespace ICSharpCode.Decompiler namespace ICSharpCode.Decompiler
{ {
/// <summary> /// <summary> Maps method's source code to IL </summary>
/// Maps the source code to IL. public class MethodDebugSymbols
/// </summary>
public sealed class SourceCodeMapping
{ {
/// <summary> public MethodDefinition CecilMethod { get; set; }
/// Gets or sets the start location of the instruction. public List<ILVariable> LocalVariables { get; set; }
/// </summary> public List<SequencePoint> SequencePoints { get; set; }
public TextLocation StartLocation { get; set; } public TextLocation StartLocation { get; set; }
/// <summary>
/// Gets or sets the end location of the instruction.
/// </summary>
public TextLocation EndLocation { get; set; } public TextLocation EndLocation { get; set; }
/// <summary> public MethodDebugSymbols(MethodDefinition methodDef)
/// 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
{ {
get { this.CecilMethod = methodDef;
if (invertedList == null) { this.LocalVariables = new List<ILVariable>();
var list = MemberCodeMappings.ConvertAll<ILRange>( this.SequencePoints = new List<SequencePoint>();
s => new ILRange { From = s.ILInstructionOffset.From, To = s.ILInstructionOffset.To });
invertedList = ILRange.OrderAndJoint(ILRange.Invert(list, CodeSize));
}
return invertedList;
}
} }
} }
/// <summary> public class SequencePoint
/// Code mappings helper class.
/// </summary>
public static class CodeMappings
{ {
/// <summary> public ILRange[] ILRanges { get; set; }
/// Gets source code mapping and metadata token based on type name and line number. public TextLocation StartLocation { get; set; }
/// </summary> public TextLocation EndLocation { get; set; }
/// <param name="codeMappings">Code mappings storage.</param> public int ILOffset { get { return this.ILRanges[0].From; } }
/// <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;
}
/// <summary> public override string ToString()
/// 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)
{ {
member = null; return string.Join(" ", this.ILRanges) + " " + this.StartLocation + "-" + this.EndLocation;
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;
} }
} }
} }

2
ICSharpCode.Decompiler/DecompilerException.cs

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

4
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -222,7 +222,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} else { } else {
// The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence, // The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence,
// but we follow Microsoft's ILDasm and use \'. // but we follow Microsoft's ILDasm and use \'.
return "'" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(identifier).Replace("'", "\\'") + "'"; return "'" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(identifier).Replace("'", "\\'") + "'";
} }
} }
@ -353,7 +353,7 @@ namespace ICSharpCode.Decompiler.Disassembler
string s = operand as string; string s = operand as string;
if (s != null) { if (s != null) {
writer.Write("\"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(s) + "\""); writer.Write("\"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(s) + "\"");
} else if (operand is char) { } else if (operand is char) {
writer.Write(((int)(char)operand).ToString()); writer.Write(((int)(char)operand).ToString());
} else if (operand is float) { } else if (operand is float) {

26
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.Disassembler
this.cancellationToken = cancellationToken; this.cancellationToken = cancellationToken;
} }
public void Disassemble(MethodBody body, MemberMapping methodMapping) public void Disassemble(MethodBody body, MethodDebugSymbols debugSymbols)
{ {
// start writing IL code // start writing IL code
MethodDefinition method = body.Method; MethodDefinition method = body.Method;
@ -82,20 +82,19 @@ namespace ICSharpCode.Decompiler.Disassembler
if (detectControlStructure && body.Instructions.Count > 0) { if (detectControlStructure && body.Instructions.Count > 0) {
Instruction inst = body.Instructions[0]; Instruction inst = body.Instructions[0];
HashSet<int> branchTargets = GetBranchTargets(body.Instructions); HashSet<int> branchTargets = GetBranchTargets(body.Instructions);
WriteStructureBody(new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize); WriteStructureBody(new ILStructure(body), branchTargets, ref inst, debugSymbols, method.Body.CodeSize);
} else { } else {
foreach (var inst in method.Body.Instructions) { foreach (var inst in method.Body.Instructions) {
var startLocation = output.Location; var startLocation = output.Location;
inst.WriteTo(output); inst.WriteTo(output);
if (methodMapping != null) { if (debugSymbols != null) {
// add IL code mappings - used in debugger // add IL code mappings - used in debugger
methodMapping.MemberCodeMappings.Add( debugSymbols.SequencePoints.Add(
new SourceCodeMapping() { new SequencePoint() {
StartLocation = output.Location, StartLocation = output.Location,
EndLocation = output.Location, EndLocation = output.Location,
ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset }, ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? method.Body.CodeSize : inst.Next.Offset) }
MemberMapping = methodMapping
}); });
} }
@ -174,7 +173,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Indent(); output.Indent();
} }
void WriteStructureBody(ILStructure s, HashSet<int> branchTargets, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize) void WriteStructureBody(ILStructure s, HashSet<int> branchTargets, ref Instruction inst, MethodDebugSymbols debugSymbols, int codeSize)
{ {
bool isFirstInstructionInStructure = true; bool isFirstInstructionInStructure = true;
bool prevInstructionWasBranch = false; bool prevInstructionWasBranch = false;
@ -184,7 +183,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) { if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) {
ILStructure child = s.Children[childIndex++]; ILStructure child = s.Children[childIndex++];
WriteStructureHeader(child); WriteStructureHeader(child);
WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize); WriteStructureBody(child, branchTargets, ref inst, debugSymbols, codeSize);
WriteStructureFooter(child); WriteStructureFooter(child);
} else { } else {
if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) { if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) {
@ -194,13 +193,12 @@ namespace ICSharpCode.Decompiler.Disassembler
inst.WriteTo(output); inst.WriteTo(output);
// add IL code mappings - used in debugger // add IL code mappings - used in debugger
if (currentMethodMapping != null) { if (debugSymbols != null) {
currentMethodMapping.MemberCodeMappings.Add( debugSymbols.SequencePoints.Add(
new SourceCodeMapping() { new SequencePoint() {
StartLocation = startLocation, StartLocation = startLocation,
EndLocation = output.Location, EndLocation = output.Location,
ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset }, ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? codeSize : inst.Next.Offset) }
MemberMapping = currentMethodMapping
}); });
} }

23
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -22,6 +22,7 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using ICSharpCode.NRefactory;
using Mono.Cecil; using Mono.Cecil;
using Mono.Collections.Generic; using Mono.Collections.Generic;
@ -114,6 +115,8 @@ namespace ICSharpCode.Decompiler.Disassembler
// instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed // instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed
// //
TextLocation startLocation = output.Location;
//emit flags //emit flags
WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility); WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility);
WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags); WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags);
@ -123,10 +126,10 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write("pinvokeimpl"); output.Write("pinvokeimpl");
if (method.HasPInvokeInfo && method.PInvokeInfo != null) { if (method.HasPInvokeInfo && method.PInvokeInfo != null) {
PInvokeInfo info = method.PInvokeInfo; PInvokeInfo info = method.PInvokeInfo;
output.Write("(\"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(info.Module.Name) + "\""); output.Write("(\"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(info.Module.Name) + "\"");
if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != method.Name) if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != method.Name)
output.Write(" as \"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(info.EntryPoint) + "\""); output.Write(" as \"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(info.EntryPoint) + "\"");
if (info.IsNoMangle) if (info.IsNoMangle)
output.Write(" nomangle"); output.Write(" nomangle");
@ -217,9 +220,11 @@ namespace ICSharpCode.Decompiler.Disassembler
if (method.HasBody) { if (method.HasBody) {
// create IL code mappings - used in debugger // create IL code mappings - used in debugger
MemberMapping methodMapping = new MemberMapping(method); MethodDebugSymbols debugSymbols = new MethodDebugSymbols(method);
methodBodyDisassembler.Disassemble(method.Body, methodMapping); debugSymbols.StartLocation = startLocation;
output.AddDebuggerMemberMapping(methodMapping); methodBodyDisassembler.Disassemble(method.Body, debugSymbols);
debugSymbols.EndLocation = output.Location;
output.AddDebugSymbols(debugSymbols);
} }
CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name)); CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name));
@ -341,7 +346,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(" = "); output.Write(" = ");
if (na.Argument.Value is string) { if (na.Argument.Value is string) {
// secdecls use special syntax for strings // secdecls use special syntax for strings
output.Write("string('{0}')", NRefactory.CSharp.CSharpOutputVisitor.ConvertString((string)na.Argument.Value).Replace("'", "\'")); output.Write("string('{0}')", NRefactory.CSharp.TextWriterTokenWriter.ConvertString((string)na.Argument.Value).Replace("'", "\'"));
} else { } else {
WriteConstant(na.Argument.Value); WriteConstant(na.Argument.Value);
} }
@ -569,10 +574,10 @@ namespace ICSharpCode.Decompiler.Disassembler
if (cmi == null) if (cmi == null)
goto default; goto default;
output.Write("custom(\"{0}\", \"{1}\"", output.Write("custom(\"{0}\", \"{1}\"",
NRefactory.CSharp.CSharpOutputVisitor.ConvertString(cmi.ManagedType.FullName), NRefactory.CSharp.TextWriterTokenWriter.ConvertString(cmi.ManagedType.FullName),
NRefactory.CSharp.CSharpOutputVisitor.ConvertString(cmi.Cookie)); NRefactory.CSharp.TextWriterTokenWriter.ConvertString(cmi.Cookie));
if (cmi.Guid != Guid.Empty || !string.IsNullOrEmpty(cmi.UnmanagedType)) { if (cmi.Guid != Guid.Empty || !string.IsNullOrEmpty(cmi.UnmanagedType)) {
output.Write(", \"{0}\", \"{1}\"", cmi.Guid.ToString(), NRefactory.CSharp.CSharpOutputVisitor.ConvertString(cmi.UnmanagedType)); output.Write(", \"{0}\", \"{1}\"", cmi.Guid.ToString(), NRefactory.CSharp.TextWriterTokenWriter.ConvertString(cmi.UnmanagedType));
} }
output.Write(')'); output.Write(')');
break; break;

2
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -65,7 +65,7 @@
<Compile Include="Ast\DecompilerContext.cs" /> <Compile Include="Ast\DecompilerContext.cs" />
<Compile Include="Ast\NameVariables.cs" /> <Compile Include="Ast\NameVariables.cs" />
<Compile Include="Ast\NRefactoryExtensions.cs" /> <Compile Include="Ast\NRefactoryExtensions.cs" />
<Compile Include="Ast\TextOutputFormatter.cs" /> <Compile Include="Ast\TextTokenWriter.cs" />
<Compile Include="Ast\Transforms\AddCheckedBlocks.cs" /> <Compile Include="Ast\Transforms\AddCheckedBlocks.cs" />
<Compile Include="Ast\Transforms\CombineQueryExpressions.cs" /> <Compile Include="Ast\Transforms\CombineQueryExpressions.cs" />
<Compile Include="Ast\Transforms\ContextTrackingVisitor.cs" /> <Compile Include="Ast\Transforms\ContextTrackingVisitor.cs" />

2
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -743,7 +743,7 @@ namespace ICSharpCode.Decompiler.ILAst
// Convert stack-based IL code to ILAst tree // Convert stack-based IL code to ILAst tree
foreach(ByteCode byteCode in body) { 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) { if (byteCode.StackBefore == null) {
// Unreachable code // Unreachable code

52
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

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

2
ICSharpCode.Decompiler/ITextOutput.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.Decompiler
void WriteDefinition(string text, object definition, bool isLocal = true); void WriteDefinition(string text, object definition, bool isLocal = true);
void WriteReference(string text, object reference, bool isLocal = false); void WriteReference(string text, object reference, bool isLocal = false);
void AddDebuggerMemberMapping(MemberMapping memberMapping); void AddDebugSymbols(MethodDebugSymbols methodDebugSymbols);
void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false); void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false);
void MarkFoldEnd(); void MarkFoldEnd();

2
ICSharpCode.Decompiler/PlainTextOutput.cs

@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler
{ {
} }
void ITextOutput.AddDebuggerMemberMapping(MemberMapping memberMapping) void ITextOutput.AddDebugSymbols(MethodDebugSymbols methodDebugSymbols)
{ {
} }
} }

19
ICSharpCode.Decompiler/Tests/CustomAttributes/S_AssemblyCustomAttribute.cs

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

19
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs

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

21
ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributes.cs

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

2
ICSharpCode.Decompiler/Tests/DoubleConstants.cs

@ -1,4 +1,4 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team // Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this // 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 // software and associated documentation files (the "Software"), to deal in the Software

19
ICSharpCode.Decompiler/Tests/Types/S_EnumSamples.cs

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

19
ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs

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

Loading…
Cancel
Save