/*
Copyright (C) 2011 de4dot@gmail.com
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see .
*/
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Mono.Cecil;
using de4dot.blocks;
using de4dot.deobfuscators;
namespace de4dot.renamer {
abstract class Ref {
public string NewName { get; set; }
public string OldName { get; private set; }
public string OldFullName { get; private set; }
public int Index { get; private set; }
public MemberReference MemberReference { get; private set; }
public TypeDef Owner { get; set; }
public bool Renamed { get; set; }
public Ref(MemberReference mr, TypeDef owner, int index) {
MemberReference = mr;
NewName = OldName = mr.Name;
OldFullName = mr.FullName;
Owner = owner;
Index = index;
}
public bool gotNewName() {
return NewName != OldName;
}
public abstract bool isSame(MemberReference mr);
public bool rename(string newName) {
if (Renamed)
return false;
Renamed = true;
NewName = newName;
return true;
}
static protected bool isVirtual(MethodDefinition m) {
return m != null && m.IsVirtual;
}
protected static IList createGenericParamDefList(IEnumerable parameters) {
var list = new List();
if (parameters == null)
return list;
int i = 0;
foreach (var param in parameters)
list.Add(new GenericParamDef(param, i++));
return list;
}
}
class FieldDef : Ref {
public FieldDef(FieldDefinition fieldDefinition, TypeDef owner, int index)
: base(fieldDefinition, owner, index) {
}
public FieldDefinition FieldDefinition {
get { return (FieldDefinition)MemberReference; }
}
public override bool isSame(MemberReference mr) {
return MemberReferenceHelper.compareFieldReference(FieldDefinition, mr as FieldReference);
}
}
class EventRef : Ref {
public EventRef(EventReference eventReference, TypeDef owner, int index)
: base(eventReference, owner, index) {
}
public EventReference EventReference {
get { return (EventReference)MemberReference; }
}
public override bool isSame(MemberReference mr) {
return MemberReferenceHelper.compareEventReference(EventReference, mr as EventReference);
}
}
class EventDef : EventRef {
public EventDef(EventDefinition eventDefinition, TypeDef owner, int index)
: base(eventDefinition, owner, index) {
}
public EventDefinition EventDefinition {
get { return (EventDefinition)MemberReference; }
}
public IEnumerable methodDefinitions() {
if (EventDefinition.AddMethod != null)
yield return EventDefinition.AddMethod;
if (EventDefinition.RemoveMethod != null)
yield return EventDefinition.RemoveMethod;
if (EventDefinition.InvokeMethod != null)
yield return EventDefinition.InvokeMethod;
if (EventDefinition.OtherMethods != null) {
foreach (var m in EventDefinition.OtherMethods)
yield return m;
}
}
// Returns one of the overridden methods or null if none found
public MethodReference getOverrideMethod() {
foreach (var method in methodDefinitions()) {
if (method.HasOverrides)
return method.Overrides[0];
}
return null;
}
public bool isVirtual() {
foreach (var method in methodDefinitions()) {
if (isVirtual(method))
return true;
}
return false;
}
}
class PropertyRef : Ref {
public PropertyRef(PropertyReference propertyReference, TypeDef owner, int index)
: base(propertyReference, owner, index) {
}
public PropertyReference PropertyReference {
get { return (PropertyReference)MemberReference; }
}
public override bool isSame(MemberReference mr) {
return MemberReferenceHelper.comparePropertyReference(PropertyReference, mr as PropertyReference);
}
}
class PropertyDef : PropertyRef {
public PropertyDef(PropertyDefinition propertyDefinition, TypeDef owner, int index)
: base(propertyDefinition, owner, index) {
}
public PropertyDefinition PropertyDefinition {
get { return (PropertyDefinition)MemberReference; }
}
public IEnumerable methodDefinitions() {
if (PropertyDefinition.GetMethod != null)
yield return PropertyDefinition.GetMethod;
if (PropertyDefinition.SetMethod != null)
yield return PropertyDefinition.SetMethod;
if (PropertyDefinition.OtherMethods != null) {
foreach (var m in PropertyDefinition.OtherMethods)
yield return m;
}
}
// Returns one of the overridden methods or null if none found
public MethodReference getOverrideMethod() {
foreach (var method in methodDefinitions()) {
if (method.HasOverrides)
return method.Overrides[0];
}
return null;
}
public bool isVirtual() {
foreach (var method in methodDefinitions()) {
if (isVirtual(method))
return true;
}
return false;
}
}
class MethodRef : Ref {
public IList paramDefs = new List();
public IList ParamDefs {
get { return paramDefs; }
}
public MethodRef(MethodReference methodReference, TypeDef owner, int index)
: base(methodReference, owner, index) {
if (methodReference.HasParameters) {
for (int i = 0; i < methodReference.Parameters.Count; i++) {
var param = methodReference.Parameters[i];
paramDefs.Add(new ParamDef(param, i));
}
}
}
public MethodReference MethodReference {
get { return (MethodReference)MemberReference; }
}
public override bool isSame(MemberReference mr) {
return MemberReferenceHelper.compareMethodReference(MethodReference, mr as MethodReference);
}
}
class MethodDef : MethodRef {
IList genericParams;
public IList GenericParams {
get { return genericParams; }
}
public PropertyDef Property { get; set; }
public EventDef Event { get; set; }
public MethodDef(MethodDefinition methodDefinition, TypeDef owner, int index)
: base(methodDefinition, owner, index) {
genericParams = createGenericParamDefList(MethodDefinition.GenericParameters);
}
public MethodDefinition MethodDefinition {
get { return (MethodDefinition)MemberReference; }
}
public bool isVirtual() {
return isVirtual(MethodDefinition);
}
}
class ParamDef {
public ParameterDefinition ParameterDefinition { get; set; }
public string OldName { get; private set; }
public string NewName { get; set; }
public int Index { get; private set; }
public bool Renamed { get; set; }
public ParamDef(ParameterDefinition parameterDefinition, int index) {
this.ParameterDefinition = parameterDefinition;
NewName = OldName = parameterDefinition.Name;
Index = index;
}
public bool gotNewName() {
return NewName != OldName;
}
}
class GenericParamDef : Ref {
public GenericParamDef(GenericParameter genericParameter, int index)
: base(genericParameter, null, index) {
}
public GenericParameter GenericParameter {
get { return (GenericParameter)MemberReference; }
}
public override bool isSame(MemberReference mr) {
throw new NotImplementedException();
}
}
class TypeInfo {
public TypeReference typeReference;
public TypeDef typeDef;
public TypeInfo(TypeReference typeReference, TypeDef typeDef) {
this.typeReference = typeReference;
this.typeDef = typeDef;
}
}
class TypeDef : Ref {
public IDefFinder defFinder;
public TypeInfo baseType = null;
public IList interfaces = new List(); // directly implemented interfaces
public IList derivedTypes = new List();
public Module module;
string newNamespace = null;
DefDict events = new DefDict();
DefDict fields = new DefDict();
DefDict methods = new DefDict();
DefDict properties = new DefDict();
DefDict types = new DefDict();
IList genericParams;
public TypeDefinition TypeDefinition {
get { return (TypeDefinition)MemberReference; }
}
public MemberRenameState MemberRenameState { get; set; }
public MemberRenameState InterfaceScopeState { get; set; }
bool prepareRenameMembersCalled = false;
public IEnumerable NestedTypes {
get { return types.getSorted(); }
}
public TypeDef NestingType { get; set; }
public IList GenericParams {
get { return genericParams; }
}
public TypeDef(TypeDefinition typeDefinition, Module module, int index = 0)
: base(typeDefinition, null, index) {
this.module = module;
genericParams = createGenericParamDefList(TypeDefinition.GenericParameters);
fields.HandleDupe = (newOne, oldOne) => {
if (oldOne.FieldDefinition.IsLiteral && !newOne.FieldDefinition.IsLiteral)
fields.replaceOldWithNew(oldOne, newOne);
};
}
public override bool isSame(MemberReference mr) {
return MemberReferenceHelper.compareTypes(TypeDefinition, mr as TypeReference);
}
public bool isInterface() {
return TypeDefinition.IsInterface;
}
public IEnumerable Methods {
get { return methods.getAll(); }
}
// Called when all members (events, fields, props, methods) have been added
public void membersAdded() {
foreach (var propDef in properties.getAll()) {
foreach (var method in propDef.methodDefinitions()) {
var methodDef = find(method);
if (methodDef == null)
throw new ApplicationException("Could not find property method");
methodDef.Property = propDef;
}
}
foreach (var eventDef in events.getAll()) {
foreach (var method in eventDef.methodDefinitions()) {
var methodDef = find(method);
if (methodDef == null)
throw new ApplicationException("Could not find event method");
methodDef.Event = eventDef;
}
}
}
public IEnumerable getAllInterfaces() {
if (isInterface())
yield return this;
foreach (var ifaceInfo in interfaces) {
foreach (var iface in ifaceInfo.typeDef.getAllInterfaces())
yield return iface;
}
foreach (var typeDef in derivedTypes) {
foreach (var iface in typeDef.getAllInterfaces())
yield return iface;
}
}
public void add(EventDef e) {
events.add(e);
}
public void add(FieldDef f) {
fields.add(f);
}
public void add(MethodDef m) {
methods.add(m);
}
public void add(PropertyDef p) {
properties.add(p);
}
public void add(TypeDef t) {
types.add(t);
}
public MethodDef find(MethodReference mr) {
return methods.find(mr);
}
public FieldDef find(FieldReference fr) {
return fields.find(fr);
}
IEnumerable getInstanceFields() {
foreach (var fieldDef in fields.getSorted()) {
if (!fieldDef.FieldDefinition.IsStatic)
yield return fieldDef;
}
}
bool isNested() {
return NestingType != null;
}
bool isGlobalType() {
if (!isNested())
return TypeDefinition.IsPublic;
var mask = TypeDefinition.Attributes & TypeAttributes.VisibilityMask;
switch (mask) {
case TypeAttributes.NestedPrivate:
case TypeAttributes.NestedAssembly:
case TypeAttributes.NestedFamANDAssem:
return false;
case TypeAttributes.NestedPublic:
case TypeAttributes.NestedFamily:
case TypeAttributes.NestedFamORAssem:
return NestingType.isGlobalType();
default:
throw new ApplicationException(string.Format("Unknown nested type visibility mask: {0}", mask));
}
}
// Renames name, namespace, and generic parameters if needed. Does not rename members.
public void prepareRename(TypeNameState typeNameState) {
var typeDefinition = TypeDefinition;
ITypeNameCreator nameCreator = isGlobalType() ?
typeNameState.globalTypeNameCreator :
typeNameState.internalTypeNameCreator;
if (OldFullName != "" && !typeNameState.IsValidName(OldName)) {
var newBaseType = baseType != null && baseType.typeDef.Renamed ? baseType.typeDef.NewName : null;
rename(nameCreator.newName(typeDefinition, newBaseType));
}
if (typeDefinition.Namespace != "" && !typeNameState.isValidNamespace(typeDefinition.Namespace))
newNamespace = typeNameState.newNamespace(typeDefinition.Namespace);
prepareRenameGenericParams(genericParams, typeNameState.IsValidName);
}
public void rename() {
var typeDefinition = TypeDefinition;
Log.v("Type: {0} ({1:X8})", TypeDefinition.FullName, TypeDefinition.MetadataToken.ToUInt32());
Log.indent();
renameGenericParams(genericParams);
if (gotNewName()) {
var old = typeDefinition.Name;
typeDefinition.Name = NewName;
Log.v("Name: {0} => {1}", old, typeDefinition.Name);
}
if (newNamespace != null) {
var old = typeDefinition.Namespace;
typeDefinition.Namespace = newNamespace;
Log.v("Namespace: {0} => {1}", old, typeDefinition.Namespace);
}
Log.deIndent();
}
static void prepareRenameGenericParams(IList genericParams, Func isValidName, IList otherGenericParams = null) {
Dictionary usedNames = new Dictionary(StringComparer.Ordinal);
INameCreator nameCreator = new GenericParamNameCreator();
if (otherGenericParams != null) {
foreach (var param in otherGenericParams)
usedNames[param.NewName] = true;
}
foreach (var param in genericParams) {
if (!isValidName(param.OldName) || usedNames.ContainsKey(param.OldName)) {
string newName;
do {
newName = nameCreator.newName();
} while (usedNames.ContainsKey(newName));
usedNames[newName] = true;
param.rename(newName);
}
}
}
static void renameGenericParams(IList genericParams) {
foreach (var param in genericParams) {
if (!param.gotNewName())
continue;
param.GenericParameter.Name = param.NewName;
Log.v("GenParam: {0} => {1}", param.OldFullName, param.GenericParameter.FullName);
}
}
public void renameMembers() {
Log.v("Type: {0}", TypeDefinition.FullName);
Log.indent();
renameFields();
renameProperties();
renameEvents();
renameMethods();
Log.deIndent();
}
void renameFields() {
foreach (var fieldDef in fields.getSorted()) {
if (!fieldDef.gotNewName())
continue;
fieldDef.FieldDefinition.Name = fieldDef.NewName;
Log.v("Field: {0} ({1:X8}) => {2}", fieldDef.OldFullName, fieldDef.FieldDefinition.MetadataToken.ToUInt32(), fieldDef.FieldDefinition.FullName);
}
}
void renameProperties() {
foreach (var propDef in properties.getSorted()) {
if (!propDef.gotNewName())
continue;
propDef.PropertyDefinition.Name = propDef.NewName;
Log.v("Property: {0} ({1:X8}) => {2}", propDef.OldFullName, propDef.PropertyDefinition.MetadataToken.ToUInt32(), propDef.PropertyDefinition.FullName);
}
}
void renameEvents() {
foreach (var eventDef in events.getSorted()) {
if (!eventDef.gotNewName())
continue;
eventDef.EventDefinition.Name = eventDef.NewName;
Log.v("Event: {0} ({1:X8}) => {2}", eventDef.OldFullName, eventDef.EventDefinition.MetadataToken.ToUInt32(), eventDef.EventDefinition.FullName);
}
}
void renameMethods() {
foreach (var methodDef in methods.getSorted()) {
Log.v("Method {0} ({1:X8})", methodDef.OldFullName, methodDef.MethodDefinition.MetadataToken.ToUInt32());
Log.indent();
renameGenericParams(methodDef.GenericParams);
if (methodDef.gotNewName()) {
methodDef.MethodReference.Name = methodDef.NewName;
Log.v("Name: {0} => {1}", methodDef.OldFullName, methodDef.MethodReference.FullName);
}
foreach (var param in methodDef.ParamDefs) {
if (!param.gotNewName())
continue;
param.ParameterDefinition.Name = param.NewName;
Log.v("Param ({0}/{1}): {2} => {3}", param.Index + 1, methodDef.ParamDefs.Count, param.OldName, param.NewName);
}
Log.deIndent();
}
}
public void prepareRenameMembers() {
if (prepareRenameMembersCalled)
return;
prepareRenameMembersCalled = true;
foreach (var ifaceInfo in interfaces)
ifaceInfo.typeDef.prepareRenameMembers();
if (baseType != null)
baseType.typeDef.prepareRenameMembers();
if (baseType != null)
MemberRenameState = baseType.typeDef.MemberRenameState.clone();
MemberRenameState.variableNameState.IsValidName = module.IsValidName;
if (InterfaceScopeState != null)
MemberRenameState.mergeRenamed(InterfaceScopeState);
expandGenerics();
prepareRenameFields(); // must be first
prepareRenameProperties();
prepareRenameEvents();
prepareRenameMethods(); // must be last
}
// Replaces the generic params with the generic args, if any
void expandGenerics() {
foreach (var typeInfo in getTypeInfos()) {
var git = typeInfo.typeReference as GenericInstanceType;
if (git == null)
continue;
if (git.GenericArguments.Count != typeInfo.typeDef.TypeDefinition.GenericParameters.Count) {
throw new ApplicationException(string.Format("# args ({0}) != # params ({1})",
git.GenericArguments.Count,
typeInfo.typeDef.TypeDefinition.GenericParameters.Count));
}
expandProperties(git);
expandEvents(git);
expandMethods(git);
}
}
IEnumerable getTypeInfos() {
if (baseType != null)
yield return baseType;
foreach (var typeInfo in interfaces)
yield return typeInfo;
}
void expandProperties(GenericInstanceType git) {
foreach (var propRef in new List(MemberRenameState.properties.Values)) {
var newPropRef = new GenericPropertyRefExpander(propRef, git).expand();
if (ReferenceEquals(newPropRef, propRef))
continue;
MemberRenameState.add(newPropRef);
}
}
void expandEvents(GenericInstanceType git) {
foreach (var eventRef in new List(MemberRenameState.events.Values)) {
var newEventRef = new GenericEventRefExpander(eventRef, git).expand();
if (ReferenceEquals(eventRef, newEventRef))
continue;
MemberRenameState.add(newEventRef);
}
}
void expandMethods(GenericInstanceType git) {
foreach (var methodRef in new List(MemberRenameState.methods.Values)) {
var newMethodRef = new GenericMethodRefExpander(methodRef, git).expand();
if (ReferenceEquals(methodRef, newMethodRef))
continue;
MemberRenameState.add(newMethodRef);
}
}
bool hasFlagsAttribute() {
if (TypeDefinition.CustomAttributes != null) {
foreach (var attr in TypeDefinition.CustomAttributes) {
if (MemberReferenceHelper.verifyType(attr.AttributeType, "mscorlib", "System.FlagsAttribute"))
return true;
}
}
return false;
}
void prepareRenameFields() {
var variableNameState = MemberRenameState.variableNameState;
if (TypeDefinition.IsEnum) {
var instanceFields = new List(getInstanceFields());
if (instanceFields.Count == 1) {
var fieldDef = instanceFields[0];
if (fieldDef.rename("value__")) {
fieldDef.FieldDefinition.IsRuntimeSpecialName = true;
fieldDef.FieldDefinition.IsSpecialName = true;
}
}
int i = 0;
string nameFormat = hasFlagsAttribute() ? "flag_{0}" : "const_{0}";
foreach (var fieldDef in fields.getSorted()) {
if (!fieldDef.FieldDefinition.IsStatic || !fieldDef.FieldDefinition.IsLiteral)
continue;
if (!variableNameState.IsValidName(fieldDef.OldName))
fieldDef.rename(string.Format(nameFormat, i));
i++;
}
}
foreach (var fieldDef in fields.getSorted()) {
if (fieldDef.Renamed)
continue;
if (!variableNameState.IsValidName(fieldDef.OldName))
fieldDef.rename(variableNameState.getNewFieldName(fieldDef.FieldDefinition));
}
}
static MethodReference getOverrideMethod(MethodDefinition meth) {
if (meth == null || !meth.HasOverrides)
return null;
return meth.Overrides[0];
}
static string getRealName(string name) {
int index = name.LastIndexOf('.');
if (index < 0)
return name;
return name.Substring(index + 1);
}
static readonly Regex removeGenericsArityRegex = new Regex(@"`[0-9]+");
static string getOverrideMethodNamePrefix(TypeReference owner) {
var name = owner.FullName.Replace('/', '.');
name = removeGenericsArityRegex.Replace(name, "");
return name + ".";
}
static string getOverrideMethodName(TypeReference owner, string name) {
return getOverrideMethodNamePrefix(owner) + name;
}
void prepareRenameProperties() {
var variableNameState = MemberRenameState.variableNameState;
foreach (var propDef in properties.getSorted()) {
if (propDef.Renamed)
continue;
propDef.Renamed = true;
bool isVirtual = propDef.isVirtual();
string prefix = "";
string baseName = propDef.OldName;
string propName = null;
if (isVirtual)
getVirtualPropName(propDef, ref prefix, ref propName);
if (propName == null && !variableNameState.IsValidName(propDef.OldName))
propName = variableNameState.getNewPropertyName(propDef.PropertyDefinition);
if (propName != null) {
baseName = propName;
propDef.NewName = prefix + baseName;
}
renameSpecialMethod(propDef.PropertyDefinition.GetMethod, prefix + "get_" + baseName);
renameSpecialMethod(propDef.PropertyDefinition.SetMethod, prefix + "set_" + baseName, "value");
if (isVirtual)
MemberRenameState.add(propDef);
}
}
void getVirtualPropName(PropertyDef propDef, ref string prefix, ref string propName) {
PropertyRef sameDef;
var overrideMethod = propDef.getOverrideMethod();
if (overrideMethod != null && (sameDef = defFinder.findProp(overrideMethod)) != null) {
prefix = getOverrideMethodNamePrefix(sameDef.Owner.TypeDefinition);
propName = sameDef.NewName;
return;
}
var method = getOverrideMethod(propDef.PropertyDefinition.GetMethod ?? propDef.PropertyDefinition.SetMethod);
if (method != null) {
var realName = getRealName(method.Name);
// Only use the name if the method is not in one of the loaded files, since the
// name shouldn't be obfuscated.
if (Regex.IsMatch(realName, @"^[sg]et_.") && defFinder.findProp(method) == null) {
prefix = getOverrideMethodNamePrefix(method.DeclaringType);
propName = realName.Substring(4);
return;
}
}
sameDef = MemberRenameState.get(propDef);
if (sameDef != null) {
prefix = "";
propName = sameDef.NewName;
return;
}
}
void prepareRenameEvents() {
var variableNameState = MemberRenameState.variableNameState;
foreach (var eventDef in events.getSorted()) {
if (eventDef.Renamed)
continue;
eventDef.Renamed = true;
bool isVirtual = eventDef.isVirtual();
string prefix = "";
string baseName = eventDef.OldName;
string propName = null;
if (isVirtual)
getVirtualEventName(eventDef, ref prefix, ref propName);
if (propName == null && !variableNameState.IsValidName(eventDef.OldName))
propName = variableNameState.getNewEventName(eventDef.EventDefinition);
if (propName != null) {
baseName = propName;
eventDef.NewName = prefix + baseName;
}
renameSpecialMethod(eventDef.EventDefinition.AddMethod, prefix + "add_" + baseName, "value");
renameSpecialMethod(eventDef.EventDefinition.RemoveMethod, prefix + "remove_" + baseName, "value");
renameSpecialMethod(eventDef.EventDefinition.InvokeMethod, prefix + "raise_" + baseName);
if (isVirtual)
MemberRenameState.add(eventDef);
}
}
void getVirtualEventName(EventDef eventDef, ref string prefix, ref string propName) {
EventRef sameDef;
var overrideMethod = eventDef.getOverrideMethod();
if (overrideMethod != null && (sameDef = defFinder.findEvent(overrideMethod)) != null) {
prefix = getOverrideMethodNamePrefix(sameDef.Owner.TypeDefinition);
propName = sameDef.NewName;
return;
}
var method = getOverrideMethod(eventDef.EventDefinition.AddMethod ?? eventDef.EventDefinition.RemoveMethod);
if (method != null) {
var realName = getRealName(method.Name);
// Only use the name if the method is not in one of the loaded files, since the
// name shouldn't be obfuscated.
if (Regex.IsMatch(realName, @"^(add|remove)_.") && defFinder.findEvent(method) == null) {
prefix = getOverrideMethodNamePrefix(method.DeclaringType);
propName = realName.Substring(realName.IndexOf('_') + 1);
return;
}
}
sameDef = MemberRenameState.get(eventDef);
if (sameDef != null) {
prefix = "";
propName = sameDef.NewName;
return;
}
}
void renameSpecialMethod(MethodDefinition methodDefinition, string newName, string newArgName = null) {
if (methodDefinition == null)
return;
var methodDef = find(methodDefinition);
if (methodDef == null)
throw new ApplicationException("Could not find the event/prop method");
renameMethod(methodDef, newName);
if (newArgName != null && methodDef.ParamDefs.Count > 0) {
var arg = methodDef.ParamDefs[methodDef.ParamDefs.Count - 1];
if (!MemberRenameState.variableNameState.IsValidName(arg.OldName)) {
arg.NewName = newArgName;
arg.Renamed = true;
}
}
}
void prepareRenameMethods() {
foreach (var methodDef in methods.getSorted())
renameMethod(methodDef);
}
void renameMethod(MethodDef methodDef, string suggestedName = null) {
if (methodDef.Renamed)
return;
methodDef.Renamed = true;
var variableNameState = MemberRenameState.variableNameState;
bool isVirtual = methodDef.isVirtual();
var nameCreator = getMethodNameCreator(methodDef, suggestedName);
if (!methodDef.MethodDefinition.IsRuntimeSpecialName && !variableNameState.IsValidName(methodDef.OldName))
methodDef.NewName = nameCreator.newName();
if (methodDef.ParamDefs.Count > 0) {
var newVariableNameState = variableNameState.clone();
foreach (var paramDef in methodDef.ParamDefs) {
if (!newVariableNameState.IsValidName(paramDef.OldName)) {
paramDef.NewName = newVariableNameState.getNewParamName(paramDef.ParameterDefinition);
paramDef.Renamed = true;
}
}
}
prepareRenameGenericParams(methodDef.GenericParams, variableNameState.IsValidName, methodDef.Owner == null ? null : methodDef.Owner.genericParams);
if (isVirtual)
MemberRenameState.add(methodDef);
}
string getPinvokeName(MethodDef methodDef) {
var methodNames = new Dictionary(StringComparer.Ordinal);
foreach (var method in methods.getAll())
methodNames[method.NewName] = true;
var entryPoint = methodDef.MethodDefinition.PInvokeInfo.EntryPoint;
if (Regex.IsMatch(entryPoint, @"^#\d+$"))
entryPoint = DotNetUtils.getDllName(methodDef.MethodDefinition.PInvokeInfo.Module.Name) + "_" + entryPoint.Substring(1);
while (true) {
var newName = MemberRenameState.variableNameState.pinvokeNameCreator.newName(entryPoint);
if (!methodNames.ContainsKey(newName))
return newName;
}
}
INameCreator getMethodNameCreator(MethodDef methodDef, string suggestedName) {
var variableNameState = MemberRenameState.variableNameState;
INameCreator nameCreator = null;
string newName = null;
if (methodDef.MethodDefinition.HasPInvokeInfo)
newName = getPinvokeName(methodDef);
else if (methodDef.MethodDefinition.IsStatic)
nameCreator = variableNameState.staticMethodNameCreator;
else if (methodDef.isVirtual()) {
MethodRef otherMethodRef;
if ((otherMethodRef = MemberRenameState.get(methodDef)) != null)
newName = otherMethodRef.NewName;
else if (methodDef.MethodDefinition.HasOverrides) {
var overrideMethod = methodDef.MethodDefinition.Overrides[0];
var otherMethodDef = defFinder.findMethod(overrideMethod);
if (otherMethodDef != null)
newName = getOverrideMethodName(overrideMethod.DeclaringType, otherMethodDef.NewName);
else
newName = getOverrideMethodName(overrideMethod.DeclaringType, overrideMethod.Name);
}
else
nameCreator = variableNameState.virtualMethodNameCreator;
}
else
nameCreator = variableNameState.instanceMethodNameCreator;
if (newName == null)
newName = suggestedName;
if (newName != null)
nameCreator = new OneNameCreator(newName);
return nameCreator;
}
}
}