// all the resolve functions for the weaver // NOTE: these functions should be made extensions, but right now they still // make heavy use of Weaver.fail and we'd have to check each one's return // value for null otherwise. // (original FieldType.Resolve returns null if not found too, so // exceptions would be a bit inconsistent here) using Mono.CecilX; namespace Mirror.Weaver { public static class Resolvers { public static MethodReference ResolveMethod(TypeReference tr, AssemblyDefinition scriptDef, string name) { if (tr == null) { Weaver.Error($"Cannot resolve method {name} without a class"); return null; } MethodReference method = ResolveMethod(tr, scriptDef, m => m.Name == name); if (method == null) { Weaver.Error($"Method not found with name {name} in type {tr.Name}", tr); } return method; } public static MethodReference ResolveMethod(TypeReference t, AssemblyDefinition scriptDef, System.Func predicate) { foreach (MethodDefinition methodRef in t.Resolve().Methods) { if (predicate(methodRef)) { return scriptDef.MainModule.ImportReference(methodRef); } } Weaver.Error($"Method not found in type {t.Name}", t); return null; } public static MethodReference TryResolveMethodInParents(TypeReference tr, AssemblyDefinition scriptDef, string name) { if (tr == null) { return null; } foreach (MethodDefinition methodRef in tr.Resolve().Methods) { if (methodRef.Name == name) { return scriptDef.MainModule.ImportReference(methodRef); } } // Could not find the method in this class, try the parent return TryResolveMethodInParents(tr.Resolve().BaseType, scriptDef, name); } public static MethodDefinition ResolveDefaultPublicCtor(TypeReference variable) { foreach (MethodDefinition methodRef in variable.Resolve().Methods) { if (methodRef.Name == ".ctor" && methodRef.Resolve().IsPublic && methodRef.Parameters.Count == 0) { return methodRef; } } return null; } public static MethodReference ResolveProperty(TypeReference tr, AssemblyDefinition scriptDef, string name) { foreach (PropertyDefinition pd in tr.Resolve().Properties) { if (pd.Name == name) { return scriptDef.MainModule.ImportReference(pd.GetMethod); } } return null; } } }