Restore events
This commit is contained in:
parent
76420f4736
commit
f7b117fe18
|
@ -352,6 +352,7 @@ namespace de4dot {
|
|||
return;
|
||||
var renamer = new Renamer(theFiles) {
|
||||
RestorePropertiesFromNames = options.RestorePropsEvents,
|
||||
RestoreEventsFromNames = options.RestorePropsEvents,
|
||||
};
|
||||
renamer.rename();
|
||||
}
|
||||
|
|
|
@ -250,6 +250,10 @@ namespace de4dot.renamer {
|
|||
allPropertyInfos[prop] = new PropertyInfo(prop);
|
||||
}
|
||||
|
||||
public void add(EventDef evt) {
|
||||
allEventInfos[evt] = new EventInfo(evt);
|
||||
}
|
||||
|
||||
public void initialize(Modules modules) {
|
||||
foreach (var type in modules.AllTypes) {
|
||||
allTypeInfos[type] = new TypeInfo(type, this);
|
||||
|
@ -261,7 +265,7 @@ namespace de4dot.renamer {
|
|||
allFieldInfos[field] = new FieldInfo(field);
|
||||
|
||||
foreach (var evt in type.AllEvents)
|
||||
allEventInfos[evt] = new EventInfo(evt);
|
||||
add(evt);
|
||||
|
||||
foreach (var prop in type.AllProperties)
|
||||
add(prop);
|
||||
|
|
|
@ -37,6 +37,8 @@ namespace de4dot.renamer {
|
|||
public bool RenameGenericParams { get; set; }
|
||||
public bool RestoreProperties { get; set; }
|
||||
public bool RestorePropertiesFromNames { get; set; }
|
||||
public bool RestoreEvents { get; set; }
|
||||
public bool RestoreEventsFromNames { get; set; }
|
||||
|
||||
Modules modules = new Modules();
|
||||
MemberInfos memberInfos = new MemberInfos();
|
||||
|
@ -59,6 +61,9 @@ namespace de4dot.renamer {
|
|||
RenameGenericParams = true;
|
||||
RestoreProperties = true;
|
||||
RestorePropertiesFromNames = true;
|
||||
RestoreEvents = true;
|
||||
RestoreEventsFromNames = true;
|
||||
|
||||
isDelegateClass = new DerivedFrom(delegateClasses);
|
||||
mergeStateHelper = new MergeStateHelper(memberInfos);
|
||||
|
||||
|
@ -77,7 +82,7 @@ namespace de4dot.renamer {
|
|||
renameTypeDefinitions();
|
||||
renameTypeReferences();
|
||||
modules.onTypesRenamed();
|
||||
restoreProperties(scopes);
|
||||
restorePropertiesAndEvents(scopes);
|
||||
prepareRenameMemberDefinitions(scopes);
|
||||
renameMemberDefinitions();
|
||||
renameMemberReferences();
|
||||
|
@ -445,10 +450,12 @@ namespace de4dot.renamer {
|
|||
}
|
||||
}
|
||||
|
||||
void restoreProperties(MethodNameScopes scopes) {
|
||||
void restorePropertiesAndEvents(MethodNameScopes scopes) {
|
||||
var allScopes = scopes.getAllScopes();
|
||||
restoreVirtualProperties(allScopes);
|
||||
restorePropertiesFromNames(allScopes);
|
||||
restoreVirtualEvents(allScopes);
|
||||
restoreEventsFromNames(allScopes);
|
||||
}
|
||||
|
||||
void restoreVirtualProperties(IEnumerable<MethodNameScope> allScopes) {
|
||||
|
@ -601,6 +608,182 @@ namespace de4dot.renamer {
|
|||
return propDef;
|
||||
}
|
||||
|
||||
void restoreVirtualEvents(IEnumerable<MethodNameScope> allScopes) {
|
||||
if (!RestoreEvents)
|
||||
return;
|
||||
foreach (var scope in allScopes)
|
||||
restoreVirtualEvents(scope);
|
||||
}
|
||||
|
||||
enum EventMethodType {
|
||||
None,
|
||||
Other,
|
||||
Adder,
|
||||
Remover,
|
||||
Raiser,
|
||||
}
|
||||
|
||||
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) {
|
||||
evt = method.Event;
|
||||
if (evt.AddMethod == method)
|
||||
methodType = EventMethodType.Adder;
|
||||
else if (evt.RemoveMethod == method)
|
||||
methodType = EventMethodType.Remover;
|
||||
else if (evt.RaiseMethod == method)
|
||||
methodType = EventMethodType.Raiser;
|
||||
else
|
||||
methodType = EventMethodType.Other;
|
||||
}
|
||||
}
|
||||
if (evt == null)
|
||||
return; // Should never happen
|
||||
if (missingEvents == null)
|
||||
return;
|
||||
|
||||
foreach (var method in missingEvents) {
|
||||
if (!method.Owner.HasModule)
|
||||
continue;
|
||||
|
||||
switch (methodType) {
|
||||
case EventMethodType.Adder:
|
||||
createEventAdder(evt.EventDefinition.Name, method);
|
||||
break;
|
||||
case EventMethodType.Remover:
|
||||
createEventRemover(evt.EventDefinition.Name, method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void restoreEventsFromNames(IEnumerable<MethodNameScope> allScopes) {
|
||||
if (!RestoreEventsFromNames)
|
||||
return;
|
||||
|
||||
foreach (var scope in allScopes) {
|
||||
var scopeMethod = scope.Methods[0];
|
||||
var methodName = scopeMethod.MethodDefinition.Name;
|
||||
bool onlyRenamableMethods = !scope.hasNonRenamableMethod();
|
||||
|
||||
if (Utils.StartsWith(methodName, "add_", StringComparison.Ordinal)) {
|
||||
var eventName = methodName.Substring(4);
|
||||
foreach (var method in scope.Methods) {
|
||||
if (onlyRenamableMethods && !memberInfos.type(method.Owner).NameChecker.isValidEventName(eventName))
|
||||
continue;
|
||||
createEventAdder(eventName, method);
|
||||
}
|
||||
}
|
||||
else if (Utils.StartsWith(methodName, "remove_", StringComparison.Ordinal)) {
|
||||
var eventName = methodName.Substring(7);
|
||||
foreach (var method in scope.Methods) {
|
||||
if (onlyRenamableMethods && !memberInfos.type(method.Owner).NameChecker.isValidEventName(eventName))
|
||||
continue;
|
||||
createEventRemover(eventName, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var type in modules.AllTypes) {
|
||||
foreach (var method in type.AllMethodsSorted) {
|
||||
if (method.isVirtual())
|
||||
continue; // Virtual methods are in allScopes, so already fixed above
|
||||
if (method.Event != null)
|
||||
continue;
|
||||
var methodName = method.MethodDefinition.Name;
|
||||
if (Utils.StartsWith(methodName, "add_", StringComparison.Ordinal))
|
||||
createEventAdder(methodName.Substring(4), method);
|
||||
else if (Utils.StartsWith(methodName, "remove_", StringComparison.Ordinal))
|
||||
createEventRemover(methodName.Substring(7), method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EventDef createEventAdder(string name, MethodDef eventMethod) {
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return null;
|
||||
var ownerType = eventMethod.Owner;
|
||||
if (!ownerType.HasModule)
|
||||
return null;
|
||||
if (eventMethod.Event != null)
|
||||
return null;
|
||||
|
||||
var method = eventMethod.MethodDefinition;
|
||||
var eventDef = createEvent(ownerType, name, getEventType(method));
|
||||
if (eventDef == null)
|
||||
return null;
|
||||
if (eventDef.AddMethod != null)
|
||||
return null;
|
||||
Log.v("Restoring event adder {0} ({1:X8}), Event: {2} ({3:X8})",
|
||||
eventMethod,
|
||||
eventMethod.MethodDefinition.MetadataToken.ToInt32(),
|
||||
eventDef.EventDefinition,
|
||||
eventDef.EventDefinition.MetadataToken.ToInt32());
|
||||
eventDef.EventDefinition.AddMethod = eventMethod.MethodDefinition;
|
||||
eventDef.AddMethod = eventMethod;
|
||||
eventMethod.Event = eventDef;
|
||||
return eventDef;
|
||||
}
|
||||
|
||||
EventDef createEventRemover(string name, MethodDef eventMethod) {
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return null;
|
||||
var ownerType = eventMethod.Owner;
|
||||
if (!ownerType.HasModule)
|
||||
return null;
|
||||
if (eventMethod.Event != null)
|
||||
return null;
|
||||
|
||||
var method = eventMethod.MethodDefinition;
|
||||
var eventDef = createEvent(ownerType, name, getEventType(method));
|
||||
if (eventDef == null)
|
||||
return null;
|
||||
if (eventDef.RemoveMethod != null)
|
||||
return null;
|
||||
Log.v("Restoring event remover {0} ({1:X8}), Event: {2} ({3:X8})",
|
||||
eventMethod,
|
||||
eventMethod.MethodDefinition.MetadataToken.ToInt32(),
|
||||
eventDef.EventDefinition,
|
||||
eventDef.EventDefinition.MetadataToken.ToInt32());
|
||||
eventDef.EventDefinition.RemoveMethod = eventMethod.MethodDefinition;
|
||||
eventDef.RemoveMethod = eventMethod;
|
||||
eventMethod.Event = eventDef;
|
||||
return eventDef;
|
||||
}
|
||||
|
||||
TypeReference getEventType(MethodReference method) {
|
||||
if (method.MethodReturnType.ReturnType.FullName != "System.Void")
|
||||
return null;
|
||||
if (method.Parameters.Count != 1)
|
||||
return null;
|
||||
return method.Parameters[0].ParameterType;
|
||||
}
|
||||
|
||||
EventDef createEvent(TypeDef ownerType, string name, TypeReference eventType) {
|
||||
if (string.IsNullOrEmpty(name) || eventType == null || eventType.FullName == "System.Void")
|
||||
return null;
|
||||
var newEvent = DotNetUtils.createEventDefinition(name, eventType);
|
||||
var eventDef = ownerType.find(newEvent);
|
||||
if (eventDef != null)
|
||||
return eventDef;
|
||||
|
||||
eventDef = ownerType.create(newEvent);
|
||||
memberInfos.add(eventDef);
|
||||
Log.v("Restoring event: {0}", newEvent);
|
||||
return eventDef;
|
||||
}
|
||||
|
||||
void prepareRenameMemberDefinitions(MethodNameScopes scopes) {
|
||||
Log.v("Renaming member definitions #1");
|
||||
|
||||
|
|
|
@ -88,6 +88,14 @@ namespace de4dot.renamer.asmmodules {
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool hasEvent() {
|
||||
foreach (var method in methods) {
|
||||
if (method.Event != null)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format("{0} -- {1}", methods.Count, methods.Count > 0 ? methods[0].ToString() : "");
|
||||
}
|
||||
|
|
|
@ -327,6 +327,10 @@ namespace de4dot.renamer.asmmodules {
|
|||
return properties.find(pr);
|
||||
}
|
||||
|
||||
public EventDef find(EventReference er) {
|
||||
return events.find(er);
|
||||
}
|
||||
|
||||
public PropertyDef create(PropertyDefinition newProp) {
|
||||
if (find(newProp) != null)
|
||||
throw new ApplicationException("Can't add a property when it's already been added");
|
||||
|
@ -337,6 +341,16 @@ namespace de4dot.renamer.asmmodules {
|
|||
return propDef;
|
||||
}
|
||||
|
||||
public EventDef create(EventDefinition newEvent) {
|
||||
if (find(newEvent) != null)
|
||||
throw new ApplicationException("Can't add an event when it's already been added");
|
||||
|
||||
var eventDef = new EventDef(newEvent, this, events.Count);
|
||||
add(eventDef);
|
||||
TypeDefinition.Events.Add(newEvent);
|
||||
return eventDef;
|
||||
}
|
||||
|
||||
public void addMembers() {
|
||||
var type = TypeDefinition;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user