diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs b/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs index 4eda0ba10..8d414f2db 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs @@ -203,6 +203,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms #region EnsureExpressionStatementsAreValid void EnsureExpressionStatementsAreValid(AstNode rootNode) { + string[] reservedNames = null; foreach (var stmt in rootNode.DescendantsAndSelf.OfType()) { if (!IsValidInStatementExpression(stmt.Expression)) @@ -218,6 +219,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms } else { + reservedNames ??= rootNode.DescendantsAndSelf.OfType().Select(i => i.Name).ToArray(); // assign result to dummy variable var type = stmt.Expression.GetResolveResult().Type; var v = function.RegisterVariable( @@ -226,7 +228,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms AssignVariableNames.GenerateVariableName(function, type, stmt.Expression.Annotations.OfType() .Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault(), - mustResolveConflicts: true) + reservedNames: reservedNames) ); 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 da8730287..a440725eb 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs @@ -53,7 +53,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms }; ILTransformContext context; - List currentLowerCaseTypeOrMemberNames; Dictionary reservedVariableNames; Dictionary localFunctionMapping; HashSet loopCounters; @@ -64,16 +63,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms this.context = context; reservedVariableNames = new Dictionary(); - 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()) @@ -157,24 +146,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms } } - 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)) - yield return item.Name; - } - } - static bool IsLowerCase(string name) { return name.Length > 0 && char.ToLower(name[0]) == name[0]; @@ -425,7 +396,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms var proposedNameForAddress = variable.AddressInstructions.OfType() .Select(arg => arg.Parent is CallInstruction c ? c.GetParameter(arg.ChildIndex)?.Name : null) .Where(arg => !string.IsNullOrWhiteSpace(arg)) - .Except(currentLowerCaseTypeOrMemberNames).ToList(); + .ToList(); if (proposedNameForAddress.Count > 0) { proposedName = proposedNameForAddress[0]; @@ -435,7 +406,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms { var proposedNameForStores = variable.StoreInstructions.OfType() .Select(expr => GetNameFromInstruction(expr.Value)) - .Except(currentLowerCaseTypeOrMemberNames).ToList(); + .ToList(); if (proposedNameForStores.Count == 1) { proposedName = proposedNameForStores[0]; @@ -445,7 +416,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms { var proposedNameForLoads = variable.LoadInstructions .Select(arg => GetNameForArgument(arg.Parent, arg.ChildIndex)) - .Except(currentLowerCaseTypeOrMemberNames).ToList(); + .ToList(); if (proposedNameForLoads.Count == 1) { proposedName = proposedNameForLoads[0]; @@ -455,7 +426,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms { var proposedNameForStoresFromNewObj = variable.StoreInstructions.OfType() .Select(expr => GetNameByType(GuessType(variable.Type, expr.Value, context))) - .Except(currentLowerCaseTypeOrMemberNames).ToList(); + .ToList(); if (proposedNameForStoresFromNewObj.Count == 1) { proposedName = proposedNameForStoresFromNewObj[0]; @@ -689,35 +660,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms return variableType; } - static Dictionary CollectReservedVariableNames(ILFunction function, - ILVariable existingVariable, bool mustResolveConflicts) - { - var reservedVariableNames = new Dictionary(); - var rootFunction = function.Ancestors.OfType().Single(f => f.Parent == null); - foreach (var f in rootFunction.Descendants.OfType()) - { - foreach (var p in rootFunction.Parameters) - { - AddExistingName(reservedVariableNames, p.Name); - } - foreach (var v in f.Variables.Where(v => v.Kind != VariableKind.Parameter)) - { - if (v != existingVariable) - AddExistingName(reservedVariableNames, v.Name); - } - } - 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, bool mustResolveConflicts = false) + ILVariable existingVariable = null, string[] reservedNames = null) { if (function == null) throw new ArgumentNullException(nameof(function)); @@ -725,7 +669,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms { return existingVariable.Name; } - var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts); + + var reservedVariableNames = new Dictionary(); + foreach (var name in reservedNames ?? Array.Empty()) + { + reservedVariableNames[name] = 1; + } string baseName = GetNameFromInstruction(valueContext); if (string.IsNullOrEmpty(baseName)) @@ -777,11 +726,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms internal static string GenerateVariableName(ILFunction function, IType type, ILInstruction valueContext = null, ILVariable existingVariable = null, - bool mustResolveConflicts = false) + string[] reservedNames = null) { if (function == null) throw new ArgumentNullException(nameof(function)); - var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts); + + var reservedVariableNames = new Dictionary(); + foreach (var name in reservedNames ?? Array.Empty()) + { + reservedVariableNames[name] = 1; + } string baseName = valueContext != null ? GetNameFromInstruction(valueContext) ?? GetNameByType(type) : GetNameByType(type); string proposedName = "obj";