|
|
|
@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
ILTransformContext context; |
|
|
|
|
string[] currentFieldNames; |
|
|
|
|
string[] currentLowerCaseTypeOrMemberNames; |
|
|
|
|
Dictionary<string, int> reservedVariableNames; |
|
|
|
|
Dictionary<MethodDefinitionHandle, string> localFunctionMapping; |
|
|
|
|
HashSet<ILVariable> loopCounters; |
|
|
|
@ -61,8 +61,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -61,8 +61,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
public void Run(ILFunction function, ILTransformContext context) |
|
|
|
|
{ |
|
|
|
|
this.context = context; |
|
|
|
|
currentFieldNames = function.Method.DeclaringTypeDefinition.Fields.Select(f => f.Name).ToArray(); |
|
|
|
|
|
|
|
|
|
reservedVariableNames = new Dictionary<string, int>(); |
|
|
|
|
currentLowerCaseTypeOrMemberNames = CollectAllLowerCaseTypeOrMemberNames(function.Method.DeclaringTypeDefinition).ToArray(); |
|
|
|
|
localFunctionMapping = new Dictionary<MethodDefinitionHandle, string>(); |
|
|
|
|
loopCounters = CollectLoopCounters(function); |
|
|
|
|
foreach (var f in function.Descendants.OfType<ILFunction>()) |
|
|
|
@ -146,6 +147,28 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -146,6 +147,28 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
IEnumerable<string> CollectAllLowerCaseTypeOrMemberNames(ITypeDefinition type) |
|
|
|
|
{ |
|
|
|
|
foreach (var item in type.GetMembers(m => IsLowerCase(m.Name))) |
|
|
|
|
yield return item.Name; |
|
|
|
|
|
|
|
|
|
foreach (var item in type.ParentModule.TopLevelTypeDefinitions) |
|
|
|
|
{ |
|
|
|
|
if (item.Namespace != type.Namespace) |
|
|
|
|
continue; |
|
|
|
|
if (IsLowerCase(item.Name)) |
|
|
|
|
{ |
|
|
|
|
AddExistingName(reservedVariableNames, item.Name); |
|
|
|
|
yield return item.Name; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool IsLowerCase(string name) |
|
|
|
|
{ |
|
|
|
|
return name.Length > 0 && char.IsLower(name[0]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool IsSetOrEventAccessor(IMethod method) |
|
|
|
|
{ |
|
|
|
|
switch (method.AccessorKind) |
|
|
|
@ -273,10 +296,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -273,10 +296,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
{ |
|
|
|
|
switch (arg) |
|
|
|
|
{ |
|
|
|
|
case LdObj ldobj: |
|
|
|
|
case LdFlda ldflda: |
|
|
|
|
case LdsFlda ldsflda: |
|
|
|
|
case CallInstruction call: |
|
|
|
|
case LdObj _: |
|
|
|
|
case LdFlda _: |
|
|
|
|
case LdsFlda _: |
|
|
|
|
case CallInstruction _: |
|
|
|
|
return true; |
|
|
|
|
default: |
|
|
|
|
return false; |
|
|
|
@ -391,7 +414,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -391,7 +414,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
var proposedNameForAddress = variable.AddressInstructions.OfType<LdLoca>() |
|
|
|
|
.Select(arg => arg.Parent is CallInstruction c ? c.GetParameter(arg.ChildIndex)?.Name : null) |
|
|
|
|
.Where(arg => !string.IsNullOrWhiteSpace(arg)) |
|
|
|
|
.Except(currentFieldNames).ToList(); |
|
|
|
|
.Except(currentLowerCaseTypeOrMemberNames).ToList(); |
|
|
|
|
if (proposedNameForAddress.Count > 0) |
|
|
|
|
{ |
|
|
|
|
proposedName = proposedNameForAddress[0]; |
|
|
|
@ -401,7 +424,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -401,7 +424,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
{ |
|
|
|
|
var proposedNameForStores = variable.StoreInstructions.OfType<StLoc>() |
|
|
|
|
.Select(expr => GetNameFromInstruction(expr.Value)) |
|
|
|
|
.Except(currentFieldNames).ToList(); |
|
|
|
|
.Except(currentLowerCaseTypeOrMemberNames).ToList(); |
|
|
|
|
if (proposedNameForStores.Count == 1) |
|
|
|
|
{ |
|
|
|
|
proposedName = proposedNameForStores[0]; |
|
|
|
@ -411,7 +434,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -411,7 +434,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
{ |
|
|
|
|
var proposedNameForLoads = variable.LoadInstructions |
|
|
|
|
.Select(arg => GetNameForArgument(arg.Parent, arg.ChildIndex)) |
|
|
|
|
.Except(currentFieldNames).ToList(); |
|
|
|
|
.Except(currentLowerCaseTypeOrMemberNames).ToList(); |
|
|
|
|
if (proposedNameForLoads.Count == 1) |
|
|
|
|
{ |
|
|
|
|
proposedName = proposedNameForLoads[0]; |
|
|
|
@ -421,7 +444,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -421,7 +444,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
{ |
|
|
|
|
var proposedNameForStoresFromNewObj = variable.StoreInstructions.OfType<StLoc>() |
|
|
|
|
.Select(expr => GetNameByType(GuessType(variable.Type, expr.Value, context))) |
|
|
|
|
.Except(currentFieldNames).ToList(); |
|
|
|
|
.Except(currentLowerCaseTypeOrMemberNames).ToList(); |
|
|
|
|
if (proposedNameForStoresFromNewObj.Count == 1) |
|
|
|
|
{ |
|
|
|
|
proposedName = proposedNameForStoresFromNewObj[0]; |
|
|
|
|