mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
Weaver: pass AssemblyResolver to Weave() so ReaderWriterProcessor can resolve Mirror.dll from CurrentAssembly's References instead of passing the AssemblyDefinition / using reflection / opening the file from Weaver / etc.
-> prepares for ILPostProcessor which needs to use the resolver to find it
This commit is contained in:
parent
5d629b0fb7
commit
7088938bb7
@ -12,6 +12,7 @@ namespace Mirror.Weaver
|
||||
{
|
||||
public static class CompilationFinishedHook
|
||||
{
|
||||
// needs to be the same as Weaver.MirrorAssemblyName!
|
||||
const string MirrorRuntimeAssemblyName = "Mirror";
|
||||
const string MirrorWeaverAssemblyName = "Mirror.Weaver";
|
||||
|
||||
@ -150,9 +151,6 @@ static HashSet<string> GetDependecyPaths(string assemblyPath)
|
||||
// file path, with dependencies added.
|
||||
static bool WeaveFromFile(string assemblyPath, string[] dependencies, string mirrorAssemblyPath)
|
||||
{
|
||||
// resolve mirror assembly
|
||||
using (DefaultAssemblyResolver mirrorAsmResolver = new DefaultAssemblyResolver())
|
||||
using (AssemblyDefinition mirrorAssembly = AssemblyDefinition.ReadAssembly(mirrorAssemblyPath, new ReaderParameters { ReadWrite = false, ReadSymbols = false, AssemblyResolver = mirrorAsmResolver }))
|
||||
// open the assembly file as stream
|
||||
using (FileStream stream = new FileStream(assemblyPath, FileMode.Open, FileAccess.ReadWrite))
|
||||
// resolve assembly from stream
|
||||
@ -174,7 +172,7 @@ static bool WeaveFromFile(string assemblyPath, string[] dependencies, string mir
|
||||
|
||||
// create weaver with logger
|
||||
weaver = new Weaver(new CompilationFinishedLogger());
|
||||
return weaver.Weave(assembly, mirrorAssembly);
|
||||
return weaver.Weave(assembly, asmResolver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,5 +244,16 @@ public static IEnumerable<FieldDefinition> FindAllPublicFields(this TypeDefiniti
|
||||
public static bool ContainsClass(this ModuleDefinition module, string nameSpace, string className) =>
|
||||
module.GetTypes().Any(td => td.Namespace == nameSpace &&
|
||||
td.Name == className);
|
||||
|
||||
|
||||
public static AssemblyNameReference FindReference(this ModuleDefinition module, string referenceName)
|
||||
{
|
||||
foreach (AssemblyNameReference reference in module.AssemblyReferences)
|
||||
{
|
||||
if (reference.Name == referenceName)
|
||||
return reference;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,18 +10,40 @@ namespace Mirror.Weaver
|
||||
{
|
||||
public static class ReaderWriterProcessor
|
||||
{
|
||||
public static bool Process(AssemblyDefinition CurrentAssembly, AssemblyDefinition mirrorAssembly, Writers writers, Readers readers, ref bool WeavingFailed)
|
||||
public static bool Process(AssemblyDefinition CurrentAssembly, IAssemblyResolver resolver, Logger Log, Writers writers, Readers readers, ref bool WeavingFailed)
|
||||
{
|
||||
// find NetworkReader/Writer extensions from Mirror.dll first.
|
||||
// and NetworkMessage custom writer/reader extensions.
|
||||
// NOTE: do not include this result in our 'modified' return value,
|
||||
// otherwise Unity crashes when running tests
|
||||
ProcessAssemblyClasses(CurrentAssembly, mirrorAssembly, writers, readers, ref WeavingFailed);
|
||||
ProcessMirrorAssemblyClasses(CurrentAssembly, resolver, Log, writers, readers, ref WeavingFailed);
|
||||
|
||||
// find readers/writers in the assembly we are in right now.
|
||||
return ProcessAssemblyClasses(CurrentAssembly, CurrentAssembly, writers, readers, ref WeavingFailed);
|
||||
}
|
||||
|
||||
static void ProcessMirrorAssemblyClasses(AssemblyDefinition CurrentAssembly, IAssemblyResolver resolver, Logger Log, Writers writers, Readers readers, ref bool WeavingFailed)
|
||||
{
|
||||
// find Mirror.dll in assembly's references.
|
||||
// those are guaranteed to be resolvable and correct.
|
||||
// after all, it references them :)
|
||||
AssemblyNameReference mirrorAssemblyReference = CurrentAssembly.MainModule.FindReference(Weaver.MirrorAssemblyName);
|
||||
if (mirrorAssemblyReference != null)
|
||||
{
|
||||
// resolve the assembly to load the AssemblyDefinition.
|
||||
// we need to search all types in it.
|
||||
// if we only were to resolve one known type like in WeaverTypes,
|
||||
// then we wouldn't need it.
|
||||
AssemblyDefinition mirrorAssembly = resolver.Resolve(mirrorAssemblyReference);
|
||||
if (mirrorAssembly != null)
|
||||
{
|
||||
ProcessAssemblyClasses(CurrentAssembly, mirrorAssembly, writers, readers, ref WeavingFailed);
|
||||
}
|
||||
else Log.Error($"Failed to resolve {mirrorAssemblyReference}");
|
||||
}
|
||||
else Log.Error("Failed to find Mirror AssemblyNameReference. Can't register Mirror.dll readers/writers.");
|
||||
}
|
||||
|
||||
static bool ProcessAssemblyClasses(AssemblyDefinition CurrentAssembly, AssemblyDefinition assembly, Writers writers, Readers readers, ref bool WeavingFailed)
|
||||
{
|
||||
bool modified = false;
|
||||
|
@ -15,10 +15,14 @@ internal class Weaver
|
||||
public const string GeneratedCodeClassName = "GeneratedNetworkCode";
|
||||
TypeDefinition GeneratedCodeClass;
|
||||
|
||||
// for resolving Mirror.dll in ReaderWriterProcessor, we need to know
|
||||
// Mirror.dll name
|
||||
public const string MirrorAssemblyName = "Mirror";
|
||||
|
||||
WeaverTypes weaverTypes;
|
||||
WeaverLists weaverLists;
|
||||
IAssemblyResolver Resolver;
|
||||
AssemblyDefinition CurrentAssembly;
|
||||
AssemblyDefinition MirrorAssembly;
|
||||
Writers writers;
|
||||
Readers readers;
|
||||
bool WeavingFailed;
|
||||
@ -117,18 +121,24 @@ void CreateGeneratedCodeClass()
|
||||
// new uses ...?
|
||||
//
|
||||
// => assembly: the one we are currently weaving (MyGame.dll)
|
||||
// => mirrorAssembly: the Mirror.dll assembly. sometimes needed to find
|
||||
// all extensions in Mirror.dll etc. while we can resolve known types
|
||||
// in other assemblys, we can't search unknown types in another
|
||||
// assembly without opening it.
|
||||
// (weaver shouldn't worry about opening. it should simply weave)
|
||||
public bool Weave(AssemblyDefinition assembly, AssemblyDefinition mirrorAssembly)
|
||||
// => resolver: useful in case we need to resolve any of the assembly's
|
||||
// assembly.MainModule.AssemblyReferences.
|
||||
// -> we can resolve ANY of them given that the resolver
|
||||
// works properly (need custom one for ILPostProcessor)
|
||||
// -> IMPORTANT: .Resolve() takes an AssemblyNameReference.
|
||||
// those from assembly.MainModule.AssemblyReferences are
|
||||
// guaranteed to be resolve-able.
|
||||
// Parsing from a string for Library/.../Mirror.dll
|
||||
// would not be guaranteed to be resolve-able because
|
||||
// for ILPostProcessor we can't assume where Mirror.dll
|
||||
// is etc.
|
||||
public bool Weave(AssemblyDefinition assembly, IAssemblyResolver resolver)
|
||||
{
|
||||
WeavingFailed = false;
|
||||
try
|
||||
{
|
||||
Resolver = resolver;
|
||||
CurrentAssembly = assembly;
|
||||
MirrorAssembly = mirrorAssembly;
|
||||
|
||||
// fix "No writer found for ..." error
|
||||
// https://github.com/vis2k/Mirror/issues/2579
|
||||
@ -160,7 +170,7 @@ public bool Weave(AssemblyDefinition assembly, AssemblyDefinition mirrorAssembly
|
||||
|
||||
Stopwatch rwstopwatch = Stopwatch.StartNew();
|
||||
// Need to track modified from ReaderWriterProcessor too because it could find custom read/write functions or create functions for NetworkMessages
|
||||
bool modified = ReaderWriterProcessor.Process(CurrentAssembly, mirrorAssembly, writers, readers, ref WeavingFailed);
|
||||
bool modified = ReaderWriterProcessor.Process(CurrentAssembly, resolver, Log, writers, readers, ref WeavingFailed);
|
||||
rwstopwatch.Stop();
|
||||
Console.WriteLine($"Find all reader and writers took {rwstopwatch.ElapsedMilliseconds} milliseconds");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user