Browse Source

Remove ILFunction.Read; Add AssignVariableNames

pull/832/head
Siegfried Pammer 8 years ago
parent
commit
66394b4e52
  1. 10
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 6
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 21
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  4. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  5. 17
      ICSharpCode.Decompiler/IL/DetectedLoop.cs
  6. 13
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  7. 348
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs
  8. 8
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  9. 5
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

10
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -115,6 +115,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -115,6 +115,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
},
new DelegateConstruction(),
new AssignVariableNames()
};
}
@ -127,11 +128,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -127,11 +128,11 @@ namespace ICSharpCode.Decompiler.CSharp
new ConvertConstructorCallIntoInitializer(), // must run after DeclareVariables
new DecimalConstantTransform(),
new IntroduceUsingDeclarations(),
new FixNameCollisions(),
//new IntroduceExtensionMethods(context), // must run after IntroduceUsingDeclarations
//new IntroduceQueryExpressions(context), // must run after IntroduceExtensionMethods
//new CombineQueryExpressions(context),
//new FlattenSwitchBlocks(),
new FixNameCollisions(),
};
public CancellationToken CancellationToken { get; set; }
@ -612,8 +613,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -612,8 +613,11 @@ namespace ICSharpCode.Decompiler.CSharp
void DecompileBody(MethodDefinition methodDefinition, IMethod method, EntityDeclaration entityDecl, ITypeResolveContext decompilationContext)
{
var specializingTypeSystem = typeSystem.GetSpecializingTypeSystem(decompilationContext);
ILFunction function = ILFunction.Read(specializingTypeSystem, methodDefinition, CancellationToken);
var ilReader = new ILReader(specializingTypeSystem);
ilReader.UseDebugSymbols = settings.UseDebugSymbols;
var function = ilReader.ReadIL(methodDefinition.Body, CancellationToken);
function.CheckInvariant(ILPhase.Normal);
if (entityDecl != null) {
int i = 0;
var parameters = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);

6
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1415,8 +1415,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1415,8 +1415,8 @@ namespace ICSharpCode.Decompiler.CSharp
case BlockType.CollectionInitializer:
case BlockType.ObjectInitializer:
return TranslateObjectAndCollectionInitializer(block);
case BlockType.CompoundOperator:
return TranslateCompoundOperator(block);
case BlockType.PostfixOperator:
return TranslatePostfixOperator(block);
default:
return ErrorExpression("Unknown block type: " + block.Type);
}
@ -1584,7 +1584,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1584,7 +1584,7 @@ namespace ICSharpCode.Decompiler.CSharp
.WithRR(new ArrayCreateResolveResult(new ArrayType(compilation, type, dimensions), newArr.Indices.Select(i => Translate(i).ResolveResult).ToArray(), elementResolveResults));
}
TranslatedExpression TranslateCompoundOperator(Block block)
TranslatedExpression TranslatePostfixOperator(Block block)
{
var targetInst = (block.Instructions.ElementAtOrDefault(0) as StLoc)?.Value;
var inst = (block.Instructions.ElementAtOrDefault(1) as StLoc)?.Value as BinaryNumericInstruction;

21
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -24,6 +24,7 @@ using ICSharpCode.Decompiler.CSharp.Syntax; @@ -24,6 +24,7 @@ using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using System;
using System.Threading;
namespace ICSharpCode.Decompiler.CSharp
@ -307,10 +308,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -307,10 +308,10 @@ namespace ICSharpCode.Decompiler.CSharp
continueStmt.Remove();
return new DoWhileStatement {
EmbeddedStatement = blockStatement,
Condition = exprBuilder.TranslateCondition(loop.Condition)
Condition = exprBuilder.TranslateCondition(CombineConditions(loop.Conditions))
};
case LoopKind.For:
conditionExpr = exprBuilder.TranslateCondition(loop.Condition);
conditionExpr = exprBuilder.TranslateCondition(loop.Conditions[0]);
blockStatement = ConvertAsBlock(loop.Body);
var forBody = ConvertBlockContainer(blockStatement, container, loop.AdditionalBlocks, true);
var forStmt = new ForStatement() {
@ -334,7 +335,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -334,7 +335,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (!loop.Body.HasFlag(InstructionFlags.EndPointUnreachable))
blockStatement.Add(new BreakStatement());
}
if (loop.Condition == null) {
if (loop.Conditions == null) {
conditionExpr = new PrimitiveExpression(true);
Debug.Assert(continueCount < container.EntryPoint.IncomingEdgeCount);
Debug.Assert(blockStatement.Statements.First() is LabelStatement);
@ -343,7 +344,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -343,7 +344,7 @@ namespace ICSharpCode.Decompiler.CSharp
blockStatement.Statements.First().Remove();
}
} else {
conditionExpr = exprBuilder.TranslateCondition(loop.Condition);
conditionExpr = exprBuilder.TranslateCondition(loop.Conditions[0]);
blockStatement = ConvertBlockContainer(blockStatement, container, loop.AdditionalBlocks, true);
}
if (blockStatement.LastOrDefault() is ContinueStatement stmt)
@ -352,6 +353,18 @@ namespace ICSharpCode.Decompiler.CSharp @@ -352,6 +353,18 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
private ILInstruction CombineConditions(ILInstruction[] conditions)
{
ILInstruction condition = null;
foreach (var c in conditions) {
if (condition == null)
condition = new LogicNot(c);
else
condition = IfInstruction.LogicAnd(new LogicNot(c), condition);
}
return condition;
}
BlockStatement ConvertBlockContainer(BlockContainer container, bool isLoop)
{
return ConvertBlockContainer(new BlockStatement(), container, container.Blocks, isLoop);

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -288,6 +288,7 @@ @@ -288,6 +288,7 @@
<Compile Include="IL\Patterns\AnyNode.cs" />
<Compile Include="IL\ControlFlow\YieldReturnDecompiler.cs" />
<Compile Include="IL\DetectedLoop.cs" />
<Compile Include="IL\Transforms\AssignVariableNames.cs" />
<Compile Include="IL\Transforms\NullCoalescingTransform.cs" />
<Compile Include="IL\Transforms\TransformCollectionAndObjectInitializers.cs" />
<Compile Include="Util\UnicodeNewline.cs" />

17
ICSharpCode.Decompiler/IL/DetectedLoop.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.IL @@ -29,7 +29,7 @@ namespace ICSharpCode.Decompiler.IL
{
public BlockContainer Container { get; }
public LoopKind Kind { get; private set; }
public ILInstruction Condition { get; private set; }
public ILInstruction[] Conditions { get; private set; }
public Block IncrementBlock { get; private set; }
public Block ContinueJumpTarget { get; private set; } // jumps to this block are "continue;" jumps
public ILInstruction Body { get; private set; } // null in case of DoWhile
@ -64,19 +64,15 @@ namespace ICSharpCode.Decompiler.IL @@ -64,19 +64,15 @@ namespace ICSharpCode.Decompiler.IL
return new DetectedLoop(container).DetectLoopInternal();
}
private static Block FindDoWhileConditionBlock(BlockContainer container, out ILInstruction condition)
private static Block FindDoWhileConditionBlock(BlockContainer container, List<ILInstruction> conditions)
{
condition = null;
foreach (var b in container.Blocks) {
if (b.Instructions.Last().MatchBranch(container.EntryPoint)) {
// potentially the do-while-condition block
int i = b.Instructions.Count - 2;
while (i >= 0 && b.Instructions[i] is IfInstruction ifInst
&& ifInst.TrueInst.MatchLeave(container) && ifInst.FalseInst.MatchNop()) {
if (condition == null)
condition = new LogicNot(ifInst.Condition);
else
condition = IfInstruction.LogicAnd(new LogicNot(ifInst.Condition), condition);
conditions.Add(ifInst.Condition);
i--;
}
if (i == -1) {
@ -105,7 +101,7 @@ namespace ICSharpCode.Decompiler.IL @@ -105,7 +101,7 @@ namespace ICSharpCode.Decompiler.IL
if (IncrementBlock != null)
ContinueJumpTarget = IncrementBlock;
}
Condition = conditionInst;
Conditions = new[] { conditionInst };
Body = trueInst;
if (IncrementBlock != null) {
// for-loop
@ -117,12 +113,13 @@ namespace ICSharpCode.Decompiler.IL @@ -117,12 +113,13 @@ namespace ICSharpCode.Decompiler.IL
} else {
// do-while or while(true)-loop
if (Container.EntryPoint.IncomingEdgeCount == 2) {
Block conditionBlock = FindDoWhileConditionBlock(Container, out var conditionInst2);
var conditions = new List<ILInstruction>();
Block conditionBlock = FindDoWhileConditionBlock(Container, conditions);
if (conditionBlock != null) {
Kind = LoopKind.DoWhile;
ContinueJumpTarget = conditionBlock;
Body = null;
Condition = conditionInst2;
Conditions = conditions.ToArray();
AdditionalBlocks = Container.Blocks.Where(b => b != conditionBlock).ToArray();
}
}

13
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

@ -151,18 +151,5 @@ namespace ICSharpCode.Decompiler.IL @@ -151,18 +151,5 @@ namespace ICSharpCode.Decompiler.IL
Variables.Add(variable);
return variable;
}
public static ILFunction Read(IDecompilerTypeSystem context, IMethod method, CancellationToken cancellationToken = default(CancellationToken))
{
return Read(context, (MethodDefinition)context.GetCecil(method), cancellationToken);
}
public static ILFunction Read(IDecompilerTypeSystem context, MethodDefinition methodDefinition, CancellationToken cancellationToken = default(CancellationToken))
{
var ilReader = new ILReader(context);
var function = ilReader.ReadIL(methodDefinition.Body, cancellationToken);
function.CheckInvariant(ILPhase.Normal);
return function;
}
}
}

348
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -0,0 +1,348 @@ @@ -0,0 +1,348 @@
// Copyright (c) 2017 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL.Transforms
{
public class AssignVariableNames : IILTransform
{
static readonly Dictionary<string, string> typeNameToVariableNameDict = new Dictionary<string, string> {
{ "System.Boolean", "flag" },
{ "System.Byte", "b" },
{ "System.SByte", "b" },
{ "System.Int16", "num" },
{ "System.Int32", "num" },
{ "System.Int64", "num" },
{ "System.UInt16", "num" },
{ "System.UInt32", "num" },
{ "System.UInt64", "num" },
{ "System.Single", "num" },
{ "System.Double", "num" },
{ "System.Decimal", "num" },
{ "System.String", "text" },
{ "System.Object", "obj" },
{ "System.Char", "c" }
};
ILTransformContext context;
string[] currentFieldNames;
Dictionary<ILVariable, string> mapping;
Dictionary<string, int> reservedVariableNames;
const char maxLoopVariableName = 'n';
public void Run(ILFunction function, ILTransformContext context)
{
this.context = context;
currentFieldNames = function.Method.DeclaringType.Fields.Select(f => f.Name).ToArray();
reservedVariableNames = new Dictionary<string, int>();
foreach (ILFunction f in function.Descendants.OfType<ILFunction>().Reverse()) {
PerformAssignment(f);
}
}
void PerformAssignment(ILFunction function)
{
foreach (var p in function.Method.Parameters)
AddExistingName(p.Name);
foreach (var v in function.Variables) {
switch (v.Kind) {
case VariableKind.Parameter:
case VariableKind.StackSlot: // keep generated names
AddExistingName(v.Name);
break;
default:
string varName = v.Name;
if (context.Settings.UseDebugSymbols) {
if (string.IsNullOrEmpty(varName) || varName.StartsWith("V_", StringComparison.Ordinal) || !IsValidName(varName)) {
// don't use the name from the debug symbols if it looks like a generated name
v.Name = null;
} else {
// use the name from the debug symbols
// (but ensure we don't use the same name for two variables)
v.Name = GetAlternativeName(varName);
}
} else {
v.Name = null;
}
break;
}
}
// Now generate names:
var mapping = new Dictionary<ILVariable, string>(ILVariableEqualityComparer.Instance);
foreach (var inst in function.Descendants.OfType<IInstructionWithVariableOperand>()) {
var v = inst.Variable;
if (!mapping.TryGetValue(v, out string name)) {
if (string.IsNullOrEmpty(v.Name))
v.Name = GenerateNameForVariable(v, function.Body);
mapping.Add(v, v.Name);
} else {
v.Name = name;
}
}
}
static bool IsValidName(string varName)
{
if (string.IsNullOrEmpty(varName))
return false;
if (!(char.IsLetter(varName[0]) || varName[0] == '_'))
return false;
for (int i = 1; i < varName.Length; i++) {
if (!(char.IsLetterOrDigit(varName[i]) || varName[i] == '_'))
return false;
}
return true;
}
public string GetAlternativeName(string oldVariableName)
{
if (oldVariableName.Length == 1 && oldVariableName[0] >= 'i' && oldVariableName[0] <= maxLoopVariableName) {
for (char c = 'i'; c <= maxLoopVariableName; c++) {
if (!reservedVariableNames.ContainsKey(c.ToString())) {
reservedVariableNames.Add(c.ToString(), 1);
return c.ToString();
}
}
}
int number;
string nameWithoutDigits = SplitName(oldVariableName, out number);
if (!reservedVariableNames.ContainsKey(nameWithoutDigits)) {
reservedVariableNames.Add(nameWithoutDigits, number - 1);
}
int count = ++reservedVariableNames[nameWithoutDigits];
if (count != 1) {
return nameWithoutDigits + count.ToString();
} else {
return nameWithoutDigits;
}
}
string GenerateNameForVariable(ILVariable variable, ILInstruction methodBody)
{
string proposedName = null;
if (variable.Type.IsKnownType(KnownTypeCode.Int32)) {
// test whether the variable might be a loop counter
bool isLoopCounter = false;
foreach (BlockContainer possibleLoop in methodBody.Descendants.OfType<BlockContainer>().Reverse()) {
if (possibleLoop.EntryPoint.IncomingEdgeCount == 1) continue;
var loop = DetectedLoop.DetectLoop(possibleLoop);
if (loop.Kind != LoopKind.For) continue;
var condition = loop.Conditions?[0];
while (condition is LogicNot not)
condition = not.Argument;
if (condition is Comp comp) {
switch (comp.Kind) {
case ComparisonKind.GreaterThan:
case ComparisonKind.GreaterThanOrEqual:
case ComparisonKind.LessThan:
case ComparisonKind.LessThanOrEqual:
if (comp.Left.MatchLdLoc(variable)) {
isLoopCounter = true;
}
break;
}
}
}
if (isLoopCounter) {
// For loop variables, use i,j,k,l,m,n
for (char c = 'i'; c <= maxLoopVariableName; c++) {
if (!reservedVariableNames.ContainsKey(c.ToString())) {
proposedName = c.ToString();
break;
}
}
}
}
if (string.IsNullOrEmpty(proposedName)) {
var proposedNameForStores = variable.StoreInstructions.OfType<StLoc>()
.Select(expr => GetNameFromInstruction(expr.Value))
.Except(currentFieldNames).ToList();
if (proposedNameForStores.Count == 1) {
proposedName = proposedNameForStores[0];
}
}
if (string.IsNullOrEmpty(proposedName)) {
var proposedNameForLoads = variable.LoadInstructions
.Select(arg => GetNameForArgument(arg.Parent, arg.ChildIndex))
.Except(currentFieldNames).ToList();
if (proposedNameForLoads.Count == 1) {
proposedName = proposedNameForLoads[0];
}
}
if (string.IsNullOrEmpty(proposedName)) {
proposedName = GetNameByType(variable.Type);
}
// remove any numbers from the proposed name
int number;
proposedName = SplitName(proposedName, out number);
if (!reservedVariableNames.ContainsKey(proposedName)) {
reservedVariableNames.Add(proposedName, 0);
}
int count = ++reservedVariableNames[proposedName];
if (count > 1) {
return proposedName + count.ToString();
} else {
return proposedName;
}
}
static string GetNameFromInstruction(ILInstruction inst)
{
switch (inst) {
case LdObj ldobj:
IField field;
if (ldobj.Target is LdFlda ldflda)
field = ldflda.Field;
else if (ldobj.Target is LdsFlda ldsflda)
field = ldsflda.Field;
else
break;
return CleanUpVariableName(field.Name);
case CallInstruction call:
if (call is NewObj) break;
IMethod m = call.Method;
if (m.Name.StartsWith("get_", StringComparison.OrdinalIgnoreCase) && m.Parameters.Count == 0) {
// use name from properties, but not from indexers
return CleanUpVariableName(m.Name.Substring(4));
} else if (m.Name.StartsWith("Get", StringComparison.OrdinalIgnoreCase) && m.Name.Length >= 4 && char.IsUpper(m.Name[3])) {
// use name from Get-methods
return CleanUpVariableName(m.Name.Substring(3));
}
break;
}
return null;
}
static string GetNameForArgument(ILInstruction parent, int i)
{
switch (parent) {
case StObj stobj:
IField field;
if (stobj.Target is LdFlda ldflda)
field = ldflda.Field;
else if (stobj.Target is LdsFlda ldsflda)
field = ldsflda.Field;
else
break;
return CleanUpVariableName(field.Name);
case CallInstruction call:
IMethod m = call.Method;
if (m.Parameters.Count == 1 && i == call.Arguments.Count - 1) {
// argument might be value of a setter
if (m.Name.StartsWith("set_", StringComparison.OrdinalIgnoreCase)) {
return CleanUpVariableName(m.Name.Substring(4));
} else if (m.Name.StartsWith("Set", StringComparison.OrdinalIgnoreCase) && m.Name.Length >= 4 && char.IsUpper(m.Name[3])) {
return CleanUpVariableName(m.Name.Substring(3));
}
}
var p = m.Parameters.ElementAtOrDefault((!(call is NewObj) && !m.IsStatic) ? i - 1 : i);
if (p != null && !string.IsNullOrEmpty(p.Name))
return CleanUpVariableName(p.Name);
break;
case Return ret:
return "result";
}
return null;
}
string GetNameByType(IType type)
{
var git = type as ParameterizedType;
if (git != null && git.FullName == "System.Nullable`1" && git.TypeArguments.Count == 1) {
type = git.TypeArguments[0];
}
string name;
if (type is ArrayType) {
name = "array";
} else if (type is PointerType) {
name = "ptr";
} else if (type.IsAnonymousType()) {
name = "anon";
} else if (type.Name.EndsWith("Exception", StringComparison.Ordinal)) {
name = "ex";
} else if (!typeNameToVariableNameDict.TryGetValue(type.FullName, out name)) {
name = type.Name;
// remove the 'I' for interfaces
if (name.Length >= 3 && name[0] == 'I' && char.IsUpper(name[1]) && char.IsLower(name[2]))
name = name.Substring(1);
name = CleanUpVariableName(name);
}
return name;
}
void AddExistingName(string name)
{
if (string.IsNullOrEmpty(name))
return;
string nameWithoutDigits = SplitName(name, out int number);
if (reservedVariableNames.TryGetValue(nameWithoutDigits, out int existingNumber)) {
reservedVariableNames[nameWithoutDigits] = Math.Max(number, existingNumber);
} else {
reservedVariableNames.Add(nameWithoutDigits, number);
}
}
static string SplitName(string name, out int number)
{
// First, identify whether the name already ends with a number:
int pos = name.Length;
while (pos > 0 && name[pos - 1] >= '0' && name[pos - 1] <= '9')
pos--;
if (pos < name.Length) {
if (int.TryParse(name.Substring(pos), out number)) {
return name.Substring(0, pos);
}
}
number = 1;
return name;
}
static string CleanUpVariableName(string name)
{
// remove the backtick (generics)
int pos = name.IndexOf('`');
if (pos >= 0)
name = name.Substring(0, pos);
// remove field prefix:
if (name.Length > 2 && name.StartsWith("m_", StringComparison.Ordinal))
name = name.Substring(2);
else if (name.Length > 1 && name[0] == '_' && (char.IsLetter(name[1]) || name[1] == '_'))
name = name.Substring(1);
if (name.Length == 0)
return "obj";
else
return char.ToLower(name[0]) + name.Substring(1);
}
}
}

8
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -139,9 +139,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -139,9 +139,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var targetMethod = ((IInstructionWithMethodOperand)value.Arguments[1]).Method;
if (IsAnonymousMethod(decompilationContext.CurrentTypeDefinition, targetMethod)) {
target = value.Arguments[0];
var methodDefinition = (Mono.Cecil.MethodDefinition)context.TypeSystem.GetCecil(targetMethod);
var localTypeSystem = context.TypeSystem.GetSpecializingTypeSystem(new SimpleTypeResolveContext(targetMethod));
var function = ILFunction.Read(localTypeSystem, targetMethod, context.CancellationToken);
var ilReader = new ILReader(localTypeSystem);
ilReader.UseDebugSymbols = context.Settings.UseDebugSymbols;
var function = ilReader.ReadIL(methodDefinition.Body, context.CancellationToken);
function.CheckInvariant(ILPhase.Normal);
var contextPrefix = targetMethod.Name;
foreach (ILVariable v in function.Variables.Where(v => v.Kind != VariableKind.Parameter)) {
v.Name = contextPrefix + v.Name;

5
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -56,8 +56,9 @@ namespace ILSpy.BamlDecompiler @@ -56,8 +56,9 @@ namespace ILSpy.BamlDecompiler
// decompile method and optimize the switch
var typeSystem = new DecompilerTypeSystem(method.Module);
ILFunction function = ILFunction.Read(typeSystem, method);
var ilReader = new ILReader(typeSystem);
var function = ilReader.ReadIL(method.Body);
var context = new ILTransformContext { Settings = new DecompilerSettings(), TypeSystem = typeSystem };
function.RunTransforms(CSharpDecompiler.GetILTransforms(), context);

Loading…
Cancel
Save