string[] getValidArgNames(MethodNameScope scope) { var methods = new List<MethodDef>(scope.Methods); foreach (var method in scope.Methods) { foreach (var overrideRef in method.MethodDefinition.Overrides) { var overrideDef = modules.resolve(overrideRef); if (overrideDef == null) { var typeDef = modules.resolve(overrideRef.DeclaringType) ?? modules.resolveOther(overrideRef.DeclaringType); if (typeDef == null) continue; overrideDef = typeDef.find(overrideRef); if (overrideDef == null) continue; } if (overrideDef.ParamDefs.Count != method.ParamDefs.Count) continue; methods.Add(overrideDef); } } var argNames = new string[scope.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].ParameterDefinition.Name; if (nameChecker == null || nameChecker.isValidMethodArgName(argName)) argNames[i] = argName; } } return argNames; }
public MethodNameScope get(MethodDef method) { if (!method.isVirtual()) throw new ApplicationException("Not a virtual method"); MethodNameScope scope; if (!methodScopes.TryGetValue(method, out scope)) { methodScopes[method] = scope = new MethodNameScope(); scope.add(method); } return scope; }
void restoreExplicitVirtualProperties(MethodNameScope scope) { if (scope.Methods.Count != 1) return; var propMethod = scope.Methods[0]; if (propMethod.Property != null) return; if (propMethod.MethodDefinition.Overrides.Count == 0) return; var theProperty = getOverriddenProperty(propMethod); if (theProperty == null) return; createProperty(theProperty, propMethod, getOverridePrefix(scope, propMethod)); }
void prepareRenameProperty(MethodNameScope scope, bool renameOverrides) { string overridePrefix; var propName = prepareRenameProperty(scope, renameOverrides, out overridePrefix); if (propName == null) return; string methodPrefix; switch (getPropertyMethodType(scope.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 scope.Methods) memberInfos.method(method).rename(methodName); }
void prepareRenameVirtualMethods(MethodNameScope scope, string namePrefix, bool renameOverrides) { if (!hasInvalidMethodName(scope)) return; if (hasDelegateOwner(scope)) { switch (scope.Methods[0].MethodDefinition.Name) { case "Invoke": case "BeginInvoke": case "EndInvoke": return; } } var overrideMethod = getOverrideMethod(scope); var overridePrefix = getOverridePrefix(scope, 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.MethodDefinition.Overrides[0].Name); else newMethodName = getRealName(memberInfos.method(overriddenMethod).newName); } else { newMethodName = getSuggestedMethodName(scope); if (newMethodName == null) { mergeStateHelper.merge(MergeStateFlags.Methods, scope); newMethodName = getAvailableName(namePrefix, false, scope, (scope2, newName) => isMethodAvailable(scope2, newName)); } } var newMethodNameWithPrefix = overridePrefix + newMethodName; foreach (var method in scope.Methods) memberInfos.type(method.Owner).renameMethod(method, newMethodNameWithPrefix); }
bool isItemProperty(MethodNameScope scope) { foreach (var method in scope.Methods) { if (method.Property != null && method.Property.isItemProperty()) return true; } return false; }
void prepareRenameEvent(MethodNameScope scope, bool renameOverrides) { string methodPrefix, overridePrefix; var eventName = prepareRenameEvent(scope, renameOverrides, out overridePrefix, out methodPrefix); if (eventName == null) return; var methodName = overridePrefix + methodPrefix + eventName; foreach (var method in scope.Methods) memberInfos.method(method).rename(methodName); }
static string getOverridePrefix(MethodNameScope scope, MethodDef method) { if (method == null || method.MethodDefinition.Overrides.Count == 0) return ""; if (scope.Methods.Count > 1) { // Don't use an override prefix if the scope has an iface method. foreach (var m in scope.Methods) { if (m.Owner.TypeDefinition.IsInterface) return ""; } } var overrideMethod = method.MethodDefinition.Overrides[0]; var name = overrideMethod.DeclaringType.FullName.Replace('/', '.'); name = removeGenericsArityRegex.Replace(name, ""); return name + "."; }
MethodDef getEventMethod(MethodNameScope scope) { foreach (var method in scope.Methods) { if (method.Event != null) return method; } return null; }
public void add(MethodNameScope scope) { scopes.Add(scope); }
static string getAvailableName(string prefix, bool tryWithoutZero, MethodNameScope scope, Func<MethodNameScope, string, bool> checkAvailable) { for (int i = 0; ; i++) { string newName = i == 0 && tryWithoutZero ? prefix : prefix + i; if (checkAvailable(scope, newName)) return newName; } }
public void merge(MergeStateFlags flags, MethodNameScope scope) { this.flags = flags; visited.Clear(); foreach (var method in scope.Methods) merge(method.Owner); }
void restoreVirtualProperties(MethodNameScope scope) { if (scope.Methods.Count <= 1 || !scope.hasProperty()) return; PropertyDef prop = null; List<MethodDef> missingProps = null; foreach (var method in scope.Methods) { if (method.Property == null) { if (missingProps == null) missingProps = new List<MethodDef>(); 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, ""); }
void restoreVirtualEvents(MethodNameScope scope) { if (scope.Methods.Count <= 1 || !scope.hasEvent()) return; EventMethodType methodType = EventMethodType.None; EventDef evt = null; List<MethodDef> missingEvents = null; foreach (var method in scope.Methods) { if (method.Event == null) { if (missingEvents == null) missingEvents = new List<MethodDef>(); 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, ""); }
bool hasDelegateOwner(MethodNameScope scope) { foreach (var method in scope.Methods) { if (isDelegateClass.check(method.Owner)) return true; } return false; }
string getNewPropertyNamePrefix(MethodNameScope scope) { const string defaultVal = "Prop_"; var propType = getPropertyType(scope); if (propType == null) return defaultVal; var elementType = propType.GetElementType(); if (propType is GenericInstanceType || elementType is GenericParameter) return defaultVal; var prefix = getPrefix(propType); string name = elementType.Name; 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) + "_"; }
bool hasInvalidMethodName(MethodNameScope scope) { foreach (var method in scope.Methods) { var typeInfo = memberInfos.type(method.Owner); var methodInfo = memberInfos.method(method); if (!typeInfo.NameChecker.isValidMethodName(methodInfo.oldName)) return true; } return false; }
MethodDef getOverrideMethod(MethodNameScope scope) { foreach (var method in scope.Methods) { if (method.MethodDefinition.Overrides.Count > 0) return method; } return null; }
bool isPropertyAvailable(MethodNameScope scope, string methodName) { foreach (var method in scope.Methods) { if (memberInfos.type(method.Owner).variableNameState.isPropertyNameUsed(methodName)) return false; } return true; }
MethodDef getPropertyMethod(MethodNameScope scope) { foreach (var method in scope.Methods) { if (method.Property != null) return method; } return null; }
string prepareRenameEvent(MethodNameScope scope, bool renameOverrides, out string overridePrefix, out string methodPrefix) { var eventMethod = getEventMethod(scope); 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(scope, eventMethod); if (renameOverrides && overridePrefix == "") return null; if (!renameOverrides && overridePrefix != "") return null; string newEventName, oldEventName; var eventInfo = memberInfos.evt(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.EventDefinition.Name); } } if (eventInfo.renamed) newEventName = getRealName(eventInfo.newName); else if (mustUseOldEventName || eventDef.Owner.Module.ObfuscatedFile.NameChecker.isValidEventName(oldEventName)) newEventName = oldEventName; else { mergeStateHelper.merge(MergeStateFlags.Events, scope); newEventName = getAvailableName("Event_", false, scope, (scope2, newName) => isEventAvailable(scope2, newName)); } var newEventNameWithPrefix = overridePrefix + newEventName; foreach (var method in scope.Methods) { if (method.Event != null) { memberInfos.evt(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 TypeReference getPropertyType(MethodNameScope scope) { var methodType = getPropertyMethodType(scope.Methods[0]); if (methodType == PropertyMethodType.Other) return null; TypeReference type = null; foreach (var propMethod in scope.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; }
string prepareRenameProperty(MethodNameScope scope, bool renameOverrides, out string overridePrefix) { var propMethod = getPropertyMethod(scope); if (propMethod == null) throw new ApplicationException("No properties found"); overridePrefix = getOverridePrefix(scope, propMethod); if (renameOverrides && overridePrefix == "") return null; if (!renameOverrides && overridePrefix != "") return null; string newPropName, oldPropName; var propDef = propMethod.Property; var propInfo = memberInfos.prop(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.PropertyDefinition.Name); } } if (propInfo.renamed) newPropName = getRealName(propInfo.newName); else if (mustUseOldPropName || propDef.Owner.Module.ObfuscatedFile.NameChecker.isValidPropertyName(oldPropName)) newPropName = oldPropName; else if (isItemProperty(scope)) newPropName = "Item"; else { bool trySameName = true; var propPrefix = getSuggestedPropertyName(scope); if (propPrefix == null) { trySameName = false; propPrefix = getNewPropertyNamePrefix(scope); } mergeStateHelper.merge(MergeStateFlags.Properties, scope); newPropName = getAvailableName(propPrefix, trySameName, scope, (scope2, newName) => isPropertyAvailable(scope2, newName)); } var newPropNameWithPrefix = overridePrefix + newPropName; foreach (var method in scope.Methods) { if (method.Property != null) { memberInfos.prop(method.Property).rename(newPropNameWithPrefix); var ownerInfo = memberInfos.type(method.Owner); ownerInfo.variableNameState.addPropertyName(newPropName); ownerInfo.variableNameState.addPropertyName(newPropNameWithPrefix); } } return newPropName; }
string getSuggestedMethodName(MethodNameScope scope) { foreach (var method in scope.Methods) { var info = memberInfos.method(method); if (info.suggestedName != null) return info.suggestedName; } return null; }
public void merge(MethodNameScope other) { if (this == other) return; methods.AddRange(other.methods); }
string getSuggestedPropertyName(MethodNameScope scope) { foreach (var method in scope.Methods) { if (method.Property == null) continue; var info = memberInfos.prop(method.Property); if (info.suggestedName != null) return info.suggestedName; } return null; }
void merge(MethodNameScope a, MethodNameScope b) { if (a == b) return; if (a.Count < b.Count) { MethodNameScope tmp = a; a = b; b = tmp; } a.merge(b); foreach (var methodDef in b.Methods) methodScopes[methodDef] = a; }
void restoreExplicitVirtualEvents(MethodNameScope scope) { if (scope.Methods.Count != 1) return; var eventMethod = scope.Methods[0]; if (eventMethod.Event != null) return; if (eventMethod.MethodDefinition.Overrides.Count == 0) return; MethodDef overriddenMethod; var theEvent = getOverriddenEvent(eventMethod, out overriddenMethod); if (theEvent == null) return; createEvent(theEvent, eventMethod, getEventMethodType(overriddenMethod), getOverridePrefix(scope, eventMethod)); }