Model: Detect and fix orphan property methods
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||
Copyright 2017-2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
@@ -68,7 +68,8 @@ namespace Il2CppInspector.Reflection
|
||||
public static IList<CustomAttributeData> GetCustomAttributes(FieldInfo field) => getCustomAttributes(field.Assembly, field.Definition.token, field.Definition.customAttributeIndex);
|
||||
public static IList<CustomAttributeData> GetCustomAttributes(MethodBase method) => getCustomAttributes(method.Assembly, method.Definition.token, method.Definition.customAttributeIndex);
|
||||
public static IList<CustomAttributeData> GetCustomAttributes(ParameterInfo param) => getCustomAttributes(param.DeclaringMethod.Assembly, param.Definition.token, param.Definition.customAttributeIndex);
|
||||
public static IList<CustomAttributeData> GetCustomAttributes(PropertyInfo prop) => getCustomAttributes(prop.Assembly, prop.Definition.token, prop.Definition.customAttributeIndex);
|
||||
public static IList<CustomAttributeData> GetCustomAttributes(PropertyInfo prop)
|
||||
=> prop.Definition != null ? getCustomAttributes(prop.Assembly, prop.Definition.token, prop.Definition.customAttributeIndex) : new List<CustomAttributeData>();
|
||||
public static IList<CustomAttributeData> GetCustomAttributes(TypeInfo type) => getCustomAttributes(type.Assembly, type.Definition.token, type.Definition.customAttributeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||
Copyright 2017-2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
@@ -57,5 +57,16 @@ namespace Il2CppInspector.Reflection {
|
||||
if (Definition.set >= 0)
|
||||
SetMethod = declaringType.DeclaredMethods.First(x => x.Index == declaringType.Definition.methodStart + Definition.set);
|
||||
}
|
||||
|
||||
// Create a property based on a get and set method
|
||||
public PropertyInfo(MethodInfo getter, MethodInfo setter, TypeInfo declaringType) :
|
||||
base(declaringType) {
|
||||
Index = -1;
|
||||
Definition = null;
|
||||
|
||||
Name = (getter ?? setter).Name.Replace(".get_", ".").Replace(".set_", ".");
|
||||
GetMethod = getter;
|
||||
SetMethod = setter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
/*
|
||||
Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||
Copyright 2017-2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@@ -523,9 +522,39 @@ namespace Il2CppInspector.Reflection {
|
||||
for (var p = Definition.propertyStart; p < Definition.propertyStart + Definition.property_count; p++)
|
||||
DeclaredProperties.Add(new PropertyInfo(pkg, p, this));
|
||||
|
||||
// There are rare cases when properties are only given as methods in the metadata
|
||||
// Find these and add them as properties
|
||||
// There are rare cases when explicitly implemented interface properties
|
||||
// are only given as methods in the metadata. Find these and add them as properties
|
||||
var eip = DeclaredMethods.Where(m => m.Name.Contains(".get_") || m.Name.Contains(".set_"))
|
||||
.Except(DeclaredProperties.Select(p => p.GetMethod))
|
||||
.Except(DeclaredProperties.Select(p => p.SetMethod));
|
||||
|
||||
// Build a paired list of getters and setters
|
||||
var pairedEip = new List<(MethodInfo get, MethodInfo set)>();
|
||||
foreach (var p in eip) {
|
||||
// Discern property name
|
||||
var n = p.Name.Replace(".get_", ".").Replace(".set_", ".");
|
||||
|
||||
// Find setter with no matching getter
|
||||
if (p.Name.Contains(".get_"))
|
||||
if (pairedEip.FirstOrDefault(pe => pe.get == null && pe.set.Name == p.Name.Replace(".get_", ".set_")) is (MethodInfo get, MethodInfo set) method) {
|
||||
pairedEip.Remove(method);
|
||||
pairedEip.Add((p, method.set));
|
||||
}
|
||||
else
|
||||
pairedEip.Add((p, null));
|
||||
|
||||
// Find getter with no matching setter
|
||||
if (p.Name.Contains(".set_"))
|
||||
if (pairedEip.FirstOrDefault(pe => pe.set == null && pe.get.Name == p.Name.Replace(".set_", ".get_")) is (MethodInfo get, MethodInfo set) method) {
|
||||
pairedEip.Remove(method);
|
||||
pairedEip.Add((method.get, p));
|
||||
}
|
||||
else
|
||||
pairedEip.Add((null, p));
|
||||
}
|
||||
|
||||
foreach (var prop in pairedEip)
|
||||
DeclaredProperties.Add(new PropertyInfo(prop.get, prop.set, this));
|
||||
|
||||
// Add all events
|
||||
for (var e = Definition.eventStart; e < Definition.eventStart + Definition.event_count; e++)
|
||||
|
||||
Reference in New Issue
Block a user