mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.1 KiB
91 lines
3.1 KiB
// <file> |
|
// <copyright see="prj:///doc/copyright.txt"/> |
|
// <license see="prj:///doc/license.txt"/> |
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/> |
|
// <version>$Revision$</version> |
|
// </file> |
|
|
|
using System; |
|
using System.Collections.Generic; |
|
using ICSharpCode.NRefactory.Ast; |
|
|
|
namespace ICSharpCode.NRefactory.Visitors |
|
{ |
|
/// <summary> |
|
/// Renames local variables if they conflict with other locals, fields or parameters. |
|
/// </summary> |
|
static class ToVBNetRenameConflictingVariablesVisitor |
|
{ |
|
public static void RenameConflicting(ParametrizedNode method) |
|
{ |
|
// variable name => case sensitive variable name |
|
// value is null if there are multiple casings for the variable -> the variable is conflicting |
|
Dictionary<string, string> caseInsensitive = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); |
|
|
|
LookupTableVisitor ltv = new LookupTableVisitor(SupportedLanguage.CSharp); |
|
method.AcceptVisitor(ltv, null); |
|
|
|
// add method parameters to caseInsensitive |
|
foreach (ParameterDeclarationExpression pde in method.Parameters) { |
|
AddVariableToDict(caseInsensitive, pde.ParameterName, true); |
|
} |
|
|
|
// add local variables to caseInsensitive |
|
foreach (KeyValuePair<string, List<LocalLookupVariable>> var in ltv.Variables) { |
|
AddVariableToDict(caseInsensitive, var.Key, true); |
|
} |
|
|
|
// add used identifiers to caseInsensitive |
|
FindIdentifiersVisitor fvv = new FindIdentifiersVisitor(); |
|
method.AcceptVisitor(fvv, null); |
|
|
|
foreach (KeyValuePair<string, string> pair in fvv.usedIdentifiers) { |
|
AddVariableToDict(caseInsensitive, pair.Key, false); |
|
} |
|
|
|
int index = 0; |
|
foreach (ParameterDeclarationExpression pde in method.Parameters) { |
|
if (caseInsensitive[pde.ParameterName] == null) { |
|
RenameVariable(method, pde.ParameterName, ref index); |
|
} |
|
} |
|
foreach (KeyValuePair<string, List<LocalLookupVariable>> var in ltv.Variables) { |
|
if (caseInsensitive[var.Key] == null) { |
|
RenameVariable(method, var.Key, ref index); |
|
} |
|
} |
|
} |
|
|
|
static void RenameVariable(INode method, string from, ref int index) |
|
{ |
|
index += 1; |
|
method.AcceptVisitor(new RenameLocalVariableVisitor(from, from + "__" + index, StringComparer.InvariantCulture), null); |
|
} |
|
|
|
static void AddVariableToDict(Dictionary<string, string> caseInsensitive, string varName, bool hasDeclaration) |
|
{ |
|
string existing; |
|
if (caseInsensitive.TryGetValue(varName, out existing)) { |
|
if (existing != null && existing != varName) { |
|
caseInsensitive[varName] = null; |
|
} |
|
} else { |
|
if (hasDeclaration) { |
|
caseInsensitive.Add(varName, varName); |
|
} |
|
} |
|
} |
|
|
|
sealed class FindIdentifiersVisitor : AbstractAstVisitor |
|
{ |
|
// use dictionary as HashSet to remember used identifiers |
|
internal readonly Dictionary<string, string> usedIdentifiers = new Dictionary<string, string>(); |
|
|
|
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data) |
|
{ |
|
usedIdentifiers[identifierExpression.Identifier] = null; |
|
return null; |
|
} |
|
} |
|
} |
|
}
|
|
|