Skip to content

Commit

Permalink
feat: use ILPostProcessor for weaver (#525)
Browse files Browse the repository at this point in the history
The weaver now uses ILPostProcessor API from unity.  This is the same thing MLAPI will use soon.

This is an internal feature from Unity that is still subject to change,  see:
https://forum.unity.com/threads/how-does-unity-do-codegen-and-why-cant-i-do-it-myself.853867/#post-5646937

but it solves a lot of issues:
* The weaver can now weave the runtime too!,  so mirror core can use [Syncvar] and all that jazz.
* The weaver is multithreaded,  each assembly is weaved in a different thread.  In theory, this should be faster when you have multiple CPU cores,  but I have not benchmarked it.
* No more cases where weaver doesn't run
* Some weaver errors now take you to the code when double clicking
* No need to rebuild all assemblies to bootstrap weaver

Note editor scripts are no longer weaved.  Apparently, ILPostProcessor is not applied consistently to editor scripts. For this reason, some of the tests must now be done in runtime tests.

BREAKING CHANGE: MirrorNG assembly no longer contains the components.  Reference Mirror.Components instead.
BREAKING CHANGE: Editor scripts are no longer weaved
  • Loading branch information
paulpach committed Jan 11, 2021
1 parent 10b8928 commit def64cd
Show file tree
Hide file tree
Showing 382 changed files with 827 additions and 565 deletions.
1 change: 1 addition & 0 deletions Assets/Mirror/AssemblyInfo.cs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@


Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "Mirror.Experimental",
"name": "Mirror.Components",
"references": [
"GUID:f51ebe6a0ceec4240a699833d6309b23",
"GUID:30817c1a0e6d646d99c048fc403f5979"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 0 additions & 52 deletions Assets/Mirror/Editor/EnterPlayModeSettingsCheck.cs

This file was deleted.

117 changes: 0 additions & 117 deletions Assets/Mirror/Editor/Weaver/CompilationFinishedHook.cs

This file was deleted.

5 changes: 3 additions & 2 deletions Assets/Mirror/Editor/Weaver/IWeaverLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ namespace Mirror.Weaver
{
public interface IWeaverLogger
{
void Error(string msg);
void Error(string message);
void Error(string message, MemberReference mr);
void Warning(string msg);
void Error(string message, MethodDefinition md);
void Warning(string message);
void Warning(string message, MemberReference mr);
}
}
34 changes: 29 additions & 5 deletions Assets/Mirror/Editor/Weaver/Logger.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,52 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Mono.Cecil;
using UnityEngine;
using Mono.Cecil.Cil;
using Unity.CompilationPipeline.Common.Diagnostics;

namespace Mirror.Weaver
{
public class Logger : IWeaverLogger
{
public void Error(string msg)
public List<DiagnosticMessage> Diagnostics = new List<DiagnosticMessage>();

public void Error(string message)
{
Debug.LogError(msg);
AddMessage(message, null, DiagnosticType.Error);
}

public void Error(string message, MemberReference mr)
{
Error($"{message} (at {mr})");
}

public void Error(string message, MethodDefinition md)
{
AddMessage($"{message} (at {md})", md.DebugInformation.SequencePoints.FirstOrDefault(), DiagnosticType.Error);
}

public void Warning(string message, MemberReference mr)
{
Warning($"{message} (at {mr})");
}

public void Warning(string msg)
public void Warning(string message)
{
AddMessage($"{message}", null, DiagnosticType.Warning);
}

private void AddMessage(string message, SequencePoint sequencePoint, DiagnosticType diagnosticType)
{
Debug.LogWarning(msg);
Diagnostics.Add(new DiagnosticMessage
{
DiagnosticType = diagnosticType,
File = sequencePoint?.Document.Url.Replace($"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}", ""),
Line = sequencePoint?.StartLine ?? 0,
Column = sequencePoint?.StartColumn ?? 0,
MessageData = message
}) ;
}
}
}
45 changes: 45 additions & 0 deletions Assets/Mirror/Editor/Weaver/MirrorIlPostProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Unity.CompilationPipeline.Common.ILPostProcessing;
using System.Linq;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace Mirror.Weaver
{
public class MirrorIlPostProcessor : ILPostProcessor
{
public const string RuntimeAssemblyName = "Mirror";

public override ILPostProcessor GetInstance() => this;

public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
{
if (!WillProcess(compiledAssembly))
return null;

var logger = new Logger();
var weaver = new Weaver(logger);

AssemblyDefinition assemblyDefinition = weaver.Weave(compiledAssembly);

// write
var pe = new MemoryStream();
var pdb = new MemoryStream();

var writerParameters = new WriterParameters
{
SymbolWriterProvider = new PortablePdbWriterProvider(),
SymbolStream = pdb,
WriteSymbols = true
};

assemblyDefinition?.Write(pe, writerParameters);

return new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()), logger.Diagnostics);
}

public override bool WillProcess(ICompiledAssembly compiledAssembly) =>
compiledAssembly.Name == RuntimeAssemblyName ||
compiledAssembly.References.Any(filePath => Path.GetFileNameWithoutExtension(filePath) == RuntimeAssemblyName);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit def64cd

Please sign in to comment.