public void Merge(MethodNameGroup other) { if (this == other) { return; } methods.AddRange(other.methods); }
public MethodNameGroup Get(MMethodDef method) { if (!method.IsVirtual()) { throw new ApplicationException("Not a virtual method"); } if (!methodGroups.TryGetValue(method, out var group)) { methodGroups[method] = group = new MethodNameGroup(); group.Add(method); } return(group); }
void Merge(MethodNameGroup a, MethodNameGroup b) { if (a == b) { return; } if (a.Count < b.Count) { MethodNameGroup tmp = a; a = b; b = tmp; } a.Merge(b); foreach (var methodDef in b.Methods) { methodGroups[methodDef] = a; } }
void RestoreExplicitVirtualEvents(MethodNameGroup group) { if (group.Methods.Count != 1) return; var eventMethod = group.Methods[0]; if (eventMethod.Event != null) return; if (eventMethod.MethodDef.Overrides.Count == 0) return; MMethodDef overriddenMethod; var theEvent = GetOverriddenEvent(eventMethod, out overriddenMethod); if (theEvent == null) return; CreateEvent(theEvent, eventMethod, GetEventMethodType(overriddenMethod), GetOverridePrefix(group, eventMethod)); }
bool IsEventAvailable(MethodNameGroup group, string methodName) { foreach (var method in group.Methods) { if (memberInfos.Type(method.Owner).variableNameState.IsEventNameUsed(methodName)) return false; } return true; }
void RestoreExplicitVirtualProperties(MethodNameGroup group) { if (group.Methods.Count != 1) return; var propMethod = group.Methods[0]; if (propMethod.Property != null) return; if (propMethod.MethodDef.Overrides.Count == 0) return; var theProperty = GetOverriddenProperty(propMethod); if (theProperty == null) return; CreateProperty(theProperty, propMethod, GetOverridePrefix(group, propMethod)); }
public void Merge(MergeStateFlags flags, MethodNameGroup group) { this.flags = flags; visited.Clear(); foreach (var method in group.Methods) Merge(method.Owner); }
bool HasInvalidMethodName(MethodNameGroup group) { foreach (var method in group.Methods) { var typeInfo = memberInfos.Type(method.Owner); var methodInfo = memberInfos.Method(method); if (!typeInfo.NameChecker.IsValidMethodName(methodInfo.oldName)) return true; } return false; }
void PrepareRenameEvent(MethodNameGroup group, bool renameOverrides) { string methodPrefix, overridePrefix; var eventName = PrepareRenameEvent(group, renameOverrides, out overridePrefix, out methodPrefix); if (eventName == null) return; var methodName = overridePrefix + methodPrefix + eventName; foreach (var method in group.Methods) memberInfos.Method(method).Rename(methodName); }
MMethodDef GetOverrideMethod(MethodNameGroup group) { foreach (var method in group.Methods) { if (method.MethodDef.Overrides.Count > 0) return method; } return null; }
public void Add(MethodNameGroup group) { groups.Add(group); }
static string GetOverridePrefix(MethodNameGroup group, MMethodDef method) { if (method == null || method.MethodDef.Overrides.Count == 0) return ""; if (group.Methods.Count > 1) { // Don't use an override prefix if the group has an iface method. foreach (var m in group.Methods) { if (m.Owner.TypeDef.IsInterface) return ""; } } var overrideMethod = method.MethodDef.Overrides[0].MethodDeclaration; if (overrideMethod.DeclaringType == null) return ""; var name = overrideMethod.DeclaringType.FullName.Replace('/', '.'); name = removeGenericsArityRegex.Replace(name, ""); return name + "."; }
string[] GetValidArgNames(MethodNameGroup group) { var methods = new List<MMethodDef>(group.Methods); foreach (var method in group.Methods) { foreach (var ovrd in method.MethodDef.Overrides) { var overrideRef = ovrd.MethodDeclaration; var overrideDef = modules.ResolveMethod(overrideRef); if (overrideDef == null) { var typeDef = modules.ResolveType(overrideRef.DeclaringType) ?? modules.ResolveOther(overrideRef.DeclaringType); if (typeDef == null) continue; overrideDef = typeDef.FindMethod(overrideRef); if (overrideDef == null) continue; } if (overrideDef.VisibleParameterCount != method.VisibleParameterCount) continue; methods.Add(overrideDef); } } var argNames = new string[group.Methods[0].ParamDefs.Count]; foreach (var method in methods) { var nameChecker = !method.Owner.HasModule ? null : method.Owner.Module.ObfuscatedFile.NameChecker; for (int i = 0; i < argNames.Length; i++) { var argName = method.ParamDefs[i].ParameterDef.Name; if (nameChecker == null || nameChecker.IsValidMethodArgName(argName)) argNames[i] = argName; } } return argNames; }
void merge(MethodNameGroup a, MethodNameGroup b) { if (a == b) return; if (a.Count < b.Count) { MethodNameGroup tmp = a; a = b; b = tmp; } a.merge(b); foreach (var methodDef in b.Methods) methodGroups[methodDef] = a; }
public MethodNameGroup get(MethodDef method) { if (!method.isVirtual()) throw new ApplicationException("Not a virtual method"); MethodNameGroup group; if (!methodGroups.TryGetValue(method, out group)) { methodGroups[method] = group = new MethodNameGroup(); group.add(method); } return group; }
public void merge(MethodNameGroup other) { if (this == other) return; methods.AddRange(other.methods); }
string PrepareRenameEvent(MethodNameGroup group, bool renameOverrides, out string overridePrefix, out string methodPrefix) { var eventMethod = GetEventMethod(group); if (eventMethod == null) throw new ApplicationException("No events found"); var eventDef = eventMethod.Event; if (eventMethod == eventDef.AddMethod) methodPrefix = "add_"; else if (eventMethod == eventDef.RemoveMethod) methodPrefix = "remove_"; else if (eventMethod == eventDef.RaiseMethod) methodPrefix = "raise_"; else methodPrefix = ""; overridePrefix = GetOverridePrefix(group, eventMethod); if (renameOverrides && overridePrefix == "") return null; if (!renameOverrides && overridePrefix != "") return null; string newEventName, oldEventName; var eventInfo = memberInfos.Event(eventDef); bool mustUseOldEventName = false; if (overridePrefix == "") oldEventName = eventInfo.oldName; else { var overriddenEventDef = GetOverriddenEvent(eventMethod); if (overriddenEventDef == null) oldEventName = GetRealName(eventInfo.oldName); else { mustUseOldEventName = true; EventInfo info; if (memberInfos.TryGetEvent(overriddenEventDef, out info)) oldEventName = GetRealName(info.newName); else oldEventName = GetRealName(overriddenEventDef.EventDef.Name.String); } } if (eventInfo.renamed) newEventName = GetRealName(eventInfo.newName); else if (mustUseOldEventName || eventDef.Owner.Module.ObfuscatedFile.NameChecker.IsValidEventName(oldEventName)) newEventName = oldEventName; else { mergeStateHelper.Merge(MergeStateFlags.Events, group); newEventName = GetAvailableName("Event_", false, group, (group2, newName) => IsEventAvailable(group2, newName)); } var newEventNameWithPrefix = overridePrefix + newEventName; foreach (var method in group.Methods) { if (method.Event != null) { memberInfos.Event(method.Event).Rename(newEventNameWithPrefix); var ownerInfo = memberInfos.Type(method.Owner); ownerInfo.variableNameState.AddEventName(newEventName); ownerInfo.variableNameState.AddEventName(newEventNameWithPrefix); } } return newEventName; }
// Returns property type, or null if not all methods have the same type TypeSig GetPropertyType(MethodNameGroup group) { var methodType = GetPropertyMethodType(group.Methods[0]); if (methodType == PropertyMethodType.Other) return null; TypeSig type = null; foreach (var propMethod in group.Methods) { TypeSig propType; if (methodType == PropertyMethodType.Setter) propType = propMethod.ParamDefs[propMethod.ParamDefs.Count - 1].ParameterDef.Type; else propType = propMethod.MethodDef.MethodSig.GetRetType(); if (type == null) type = propType; else if (!new SigComparer().Equals(type, propType)) return null; } return type; }
MMethodDef GetEventMethod(MethodNameGroup group) { foreach (var method in group.Methods) { if (method.Event != null) return method; } return null; }
void PrepareRenameVirtualMethods(MethodNameGroup group, string namePrefix, bool renameOverrides) { if (!HasInvalidMethodName(group)) return; if (HasDelegateOwner(group)) { switch (group.Methods[0].MethodDef.Name.String) { case "Invoke": case "BeginInvoke": case "EndInvoke": return; } } var overrideMethod = GetOverrideMethod(group); var overridePrefix = GetOverridePrefix(group, overrideMethod); if (renameOverrides && overridePrefix == "") return; if (!renameOverrides && overridePrefix != "") return; string newMethodName; if (overridePrefix != "") { var overrideInfo = memberInfos.Method(overrideMethod); var overriddenMethod = GetOverriddenMethod(overrideMethod); if (overriddenMethod == null) newMethodName = GetRealName(overrideMethod.MethodDef.Overrides[0].MethodDeclaration.Name.String); else newMethodName = GetRealName(memberInfos.Method(overriddenMethod).newName); } else { newMethodName = GetSuggestedMethodName(group); if (newMethodName == null) { mergeStateHelper.Merge(MergeStateFlags.Methods, group); newMethodName = GetAvailableName(namePrefix, false, group, (group2, newName) => IsMethodAvailable(group2, newName)); } } var newMethodNameWithPrefix = overridePrefix + newMethodName; foreach (var method in group.Methods) memberInfos.Type(method.Owner).RenameMethod(method, newMethodNameWithPrefix); }
void PrepareRenameProperty(MethodNameGroup group, bool renameOverrides) { string overridePrefix; var propName = PrepareRenameProperty(group, renameOverrides, out overridePrefix); if (propName == null) return; string methodPrefix; switch (GetPropertyMethodType(group.Methods[0])) { case PropertyMethodType.Getter: methodPrefix = "get_"; break; case PropertyMethodType.Setter: methodPrefix = "set_"; break; default: throw new ApplicationException("Invalid property type"); } var methodName = overridePrefix + methodPrefix + propName; foreach (var method in group.Methods) memberInfos.Method(method).Rename(methodName); }
string GetSuggestedMethodName(MethodNameGroup group) { foreach (var method in group.Methods) { var info = memberInfos.Method(method); if (info.suggestedName != null) return info.suggestedName; } return null; }
string PrepareRenameProperty(MethodNameGroup group, bool renameOverrides, out string overridePrefix) { var propMethod = GetPropertyMethod(group); if (propMethod == null) throw new ApplicationException("No properties found"); overridePrefix = GetOverridePrefix(group, propMethod); if (renameOverrides && overridePrefix == "") return null; if (!renameOverrides && overridePrefix != "") return null; string newPropName, oldPropName; var propDef = propMethod.Property; var propInfo = memberInfos.Property(propDef); bool mustUseOldPropName = false; if (overridePrefix == "") oldPropName = propInfo.oldName; else { var overriddenPropDef = GetOverriddenProperty(propMethod); if (overriddenPropDef == null) oldPropName = GetRealName(propInfo.oldName); else { mustUseOldPropName = true; PropertyInfo info; if (memberInfos.TryGetProperty(overriddenPropDef, out info)) oldPropName = GetRealName(info.newName); else oldPropName = GetRealName(overriddenPropDef.PropertyDef.Name.String); } } if (propInfo.renamed) newPropName = GetRealName(propInfo.newName); else if (mustUseOldPropName || propDef.Owner.Module.ObfuscatedFile.NameChecker.IsValidPropertyName(oldPropName)) newPropName = oldPropName; else if (IsItemProperty(group)) newPropName = "Item"; else { bool trySameName = true; var propPrefix = GetSuggestedPropertyName(group); if (propPrefix == null) { trySameName = false; propPrefix = GetNewPropertyNamePrefix(group); } mergeStateHelper.Merge(MergeStateFlags.Properties, group); newPropName = GetAvailableName(propPrefix, trySameName, group, (group2, newName) => IsPropertyAvailable(group2, newName)); } var newPropNameWithPrefix = overridePrefix + newPropName; foreach (var method in group.Methods) { if (method.Property != null) { memberInfos.Property(method.Property).Rename(newPropNameWithPrefix); var ownerInfo = memberInfos.Type(method.Owner); ownerInfo.variableNameState.AddPropertyName(newPropName); ownerInfo.variableNameState.AddPropertyName(newPropNameWithPrefix); } } return newPropName; }
static string GetAvailableName(string prefix, bool tryWithoutZero, MethodNameGroup group, Func<MethodNameGroup, string, bool> checkAvailable) { for (int i = 0; ; i++) { string newName = i == 0 && tryWithoutZero ? prefix : prefix + i; if (checkAvailable(group, newName)) return newName; } }
bool IsItemProperty(MethodNameGroup group) { foreach (var method in group.Methods) { if (method.Property != null && method.Property.IsItemProperty()) return true; } return false; }
bool HasDelegateOwner(MethodNameGroup group) { foreach (var method in group.Methods) { if (isDelegateClass.Check(method.Owner)) return true; } return false; }
MMethodDef GetPropertyMethod(MethodNameGroup group) { foreach (var method in group.Methods) { if (method.Property != null) return method; } return null; }
void RestoreVirtualProperties(MethodNameGroup group) { if (group.Methods.Count <= 1 || !group.HasProperty()) return; MPropertyDef prop = null; List<MMethodDef> missingProps = null; foreach (var method in group.Methods) { if (method.Property == null) { if (missingProps == null) missingProps = new List<MMethodDef>(); missingProps.Add(method); } else if (prop == null || !method.Owner.HasModule) prop = method.Property; } if (prop == null) return; // Should never happen if (missingProps == null) return; foreach (var method in missingProps) CreateProperty(prop, method, ""); }
// Returns property type, or null if not all methods have the same type TypeReference getPropertyType(MethodNameGroup group) { var methodType = getPropertyMethodType(group.Methods[0]); if (methodType == PropertyMethodType.Other) return null; TypeReference type = null; foreach (var propMethod in group.Methods) { TypeReference propType; if (methodType == PropertyMethodType.Setter) propType = propMethod.ParamDefs[propMethod.ParamDefs.Count - 1].ParameterDefinition.ParameterType; else propType = propMethod.MethodDefinition.MethodReturnType.ReturnType; if (type == null) type = propType; else if (!MemberReferenceHelper.compareTypes(type, propType)) return null; } return type; }
void RestoreVirtualEvents(MethodNameGroup group) { if (group.Methods.Count <= 1 || !group.HasEvent()) return; EventMethodType methodType = EventMethodType.None; MEventDef evt = null; List<MMethodDef> missingEvents = null; foreach (var method in group.Methods) { if (method.Event == null) { if (missingEvents == null) missingEvents = new List<MMethodDef>(); missingEvents.Add(method); } else if (evt == null || !method.Owner.HasModule) { evt = method.Event; methodType = GetEventMethodType(method); } } if (evt == null) return; // Should never happen if (missingEvents == null) return; foreach (var method in missingEvents) CreateEvent(evt, method, methodType, ""); }
string GetNewPropertyNamePrefix(MethodNameGroup group) { const string defaultVal = "Prop_"; var propType = GetPropertyType(group); if (propType == null) return defaultVal; var elementType = propType.ScopeType.ToTypeSig(false).RemovePinnedAndModifiers(); if (propType is GenericInstSig || elementType is GenericSig) return defaultVal; var prefix = GetPrefix(propType); string name = elementType.TypeName; int i; if ((i = name.IndexOf('`')) >= 0) name = name.Substring(0, i); if ((i = name.LastIndexOf('.')) >= 0) name = name.Substring(i + 1); if (name == "") return defaultVal; return prefix.ToUpperInvariant() + UpperFirst(name) + "_"; }
string GetSuggestedPropertyName(MethodNameGroup group) { foreach (var method in group.Methods) { if (method.Property == null) continue; var info = memberInfos.Property(method.Property); if (info.suggestedName != null) return info.suggestedName; } return null; }
bool isPropertyAvailable(MethodNameGroup group, string methodName) { foreach (var method in group.Methods) { if (memberInfos.type(method.Owner).variableNameState.isPropertyNameUsed(methodName)) return false; } return true; }