diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs b/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs index 71ab425bb..5964caf42 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs @@ -202,7 +202,10 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms var v = function.RegisterVariable( VariableKind.StackSlot, type, - AssignVariableNames.GenerateVariableName(function, type, stmt.Expression.Annotations.OfType().Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault()) + AssignVariableNames.GenerateVariableName(function, type, + stmt.Expression.Annotations.OfType() + .Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault(), + mustResolveConflicts: true) ); stmt.Expression = new AssignmentExpression( new IdentifierExpression(v.Name).WithRR(new ILVariableResolveResult(v, v.Type)), diff --git a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs index 1c3c6df0e..2c31c7ed6 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms }; ILTransformContext context; - string[] currentLowerCaseTypeOrMemberNames; + List currentLowerCaseTypeOrMemberNames; Dictionary reservedVariableNames; Dictionary localFunctionMapping; HashSet loopCounters; @@ -63,7 +63,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms this.context = context; reservedVariableNames = new Dictionary(); - currentLowerCaseTypeOrMemberNames = CollectAllLowerCaseTypeOrMemberNames(function.Method.DeclaringTypeDefinition).ToArray(); + currentLowerCaseTypeOrMemberNames = new List(); + var currentLowerCaseMemberNames = CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition); + foreach (var name in currentLowerCaseMemberNames) + currentLowerCaseTypeOrMemberNames.Add(name); + var currentLowerCaseTypeNames = CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition); + foreach (var name in currentLowerCaseTypeNames) + { + currentLowerCaseTypeOrMemberNames.Add(name); + AddExistingName(reservedVariableNames, name); + } localFunctionMapping = new Dictionary(); loopCounters = CollectLoopCounters(function); foreach (var f in function.Descendants.OfType()) @@ -147,26 +156,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms } } - IEnumerable CollectAllLowerCaseTypeOrMemberNames(ITypeDefinition type) + static IEnumerable CollectAllLowerCaseMemberNames(ITypeDefinition type) { foreach (var item in type.GetMembers(m => IsLowerCase(m.Name))) yield return item.Name; + } + + static IEnumerable CollectAllLowerCaseTypeNames(ITypeDefinition type) + { 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.ToLower(name[0]) == name[0]; - } + static bool IsLowerCase(string name) + { + return name.Length > 0 && char.ToLower(name[0]) == name[0]; } bool IsSetOrEventAccessor(IMethod method) @@ -678,7 +688,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms return variableType; } - static Dictionary CollectReservedVariableNames(ILFunction function, ILVariable existingVariable) + static Dictionary CollectReservedVariableNames(ILFunction function, + ILVariable existingVariable, bool mustResolveConflicts) { var reservedVariableNames = new Dictionary(); var rootFunction = function.Ancestors.OfType().Single(f => f.Parent == null); @@ -694,12 +705,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms AddExistingName(reservedVariableNames, v.Name); } } - foreach (var f in rootFunction.Method.DeclaringTypeDefinition.GetFields().Select(f => f.Name)) - AddExistingName(reservedVariableNames, f); + if (mustResolveConflicts) + { + var memberNames = CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition) + .Concat(CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition)); + foreach (var name in memberNames) + AddExistingName(reservedVariableNames, name); + } return reservedVariableNames; } - internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, ILVariable existingVariable = null) + internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, + ILVariable existingVariable = null, bool mustResolveConflicts = false) { if (function == null) throw new ArgumentNullException(nameof(function)); @@ -707,7 +724,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms { return existingVariable.Name; } - var reservedVariableNames = CollectReservedVariableNames(function, existingVariable); + var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts); string baseName = GetNameFromInstruction(valueContext); if (string.IsNullOrEmpty(baseName)) @@ -756,11 +773,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms } } - internal static string GenerateVariableName(ILFunction function, IType type, ILInstruction valueContext = null, ILVariable existingVariable = null) + internal static string GenerateVariableName(ILFunction function, IType type, + ILInstruction valueContext = null, ILVariable existingVariable = null, + bool mustResolveConflicts = false) { if (function == null) throw new ArgumentNullException(nameof(function)); - var reservedVariableNames = CollectReservedVariableNames(function, existingVariable); + var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts); string baseName = valueContext != null ? GetNameFromInstruction(valueContext) ?? GetNameByType(type) : GetNameByType(type); string proposedName = "obj";