Skip to content

Commit

Permalink
Merge pull request #196 from hadashiA/ku/fix-codegen-unity-2021
Browse files Browse the repository at this point in the history
Fix an error in CodeGen that failed to get System.Type (Unity 2021)
  • Loading branch information
hadashiA authored Apr 23, 2021
2 parents c9ad649 + 206cdfa commit 30299a2
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 19 deletions.
71 changes: 53 additions & 18 deletions VContainer/Assets/VContainer/Editor/CodeGen/InjectionILGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using Unity.CompilationPipeline.Common.Diagnostics;
using Unity.CompilationPipeline.Common.ILPostProcessing;
using MethodAttributes = Mono.Cecil.MethodAttributes;
using TypeAttributes = Mono.Cecil.TypeAttributes;
using VContainer.Internal;
Expand All @@ -15,8 +18,11 @@ namespace VContainer.Editor.CodeGen
sealed class InjectionILGenerator
{
readonly ModuleDefinition module;
readonly ICompiledAssembly compiledAssembly;
readonly IList<string> targetNamespaces;

Assembly currentAssembly;

TypeReference ObjectResolverTypeRef =>
objectResolverTypeRef ?? (objectResolverTypeRef = module.ImportReference(typeof(IObjectResolver)));

Expand Down Expand Up @@ -54,9 +60,13 @@ sealed class InjectionILGenerator
MethodReference resolveMethodRef;
MethodReference resolveOrParameterMethodRef;

public InjectionILGenerator(ModuleDefinition module, IList<string> targetNamespaces)
public InjectionILGenerator(
ModuleDefinition module,
ICompiledAssembly compiledAssembly,
IList<string> targetNamespaces = null)
{
this.module = module;
this.compiledAssembly = compiledAssembly;
this.targetNamespaces = targetNamespaces;
}

Expand All @@ -70,9 +80,11 @@ public bool TryGenerate(out List<DiagnosticMessage> diagnosticMessages)

foreach (var typeDef in module.Types)
{
if (typeDef.FullName == "<Module>") continue;

try
{
if (TryGenerate(typeDef, diagnosticMessages))
if (TryGenerateType(typeDef, diagnosticMessages))
{
count += 1;
}
Expand Down Expand Up @@ -108,11 +120,46 @@ public bool TryGenerate(out List<DiagnosticMessage> diagnosticMessages)
return false;
}

bool TryGenerate(TypeDefinition typeDef, List<DiagnosticMessage> diagnosticMessages)
bool NeedsInjectType(Type type)
=> !type.IsEnum &&
!type.IsValueType &&
!type.IsInterface &&
!(type.IsAbstract && type.IsSealed) &&
!typeof(Delegate).IsAssignableFrom(type) &&
!typeof(Attribute).IsAssignableFrom(type) &&
!type.IsGenericType &&
(targetNamespaces == null ||
targetNamespaces.Count <= 0 ||
targetNamespaces.Contains(type.Namespace));

Type GetTypeFromDef(TypeDefinition typeDef)
{
var type = Type.GetType($"{typeDef.FullName}, {module.Assembly.FullName}");
try
{
return Type.GetType($"{typeDef.FullName}, {module.Assembly.FullName}");
}
catch (FileLoadException)
{
if (currentAssembly == null)
currentAssembly = Assembly.Load(compiledAssembly.InMemoryAssembly.PeData);
return currentAssembly.GetType(typeDef.FullName);
}
}

if (type == null || !NeedsInjectType(type))
bool TryGenerateType(TypeDefinition typeDef, List<DiagnosticMessage> diagnosticMessages)
{
var type = GetTypeFromDef(typeDef);
if (type == null)
{
diagnosticMessages.Add(new DiagnosticMessage
{
DiagnosticType = DiagnosticType.Warning,
MessageData = $"Skip IL waving because cant detect type: {typeDef.FullName}"
});
return false;
}

if (!NeedsInjectType(type))
return false;

InjectTypeInfo injectTypeInfo;
Expand All @@ -125,7 +172,7 @@ bool TryGenerate(TypeDefinition typeDef, List<DiagnosticMessage> diagnosticMessa
diagnosticMessages.Add(new DiagnosticMessage
{
DiagnosticType = DiagnosticType.Warning,
MessageData = $"Failed to analyze {type.FullName} : {ex.Message}"
MessageData = $"Failed to analyze {type.FullName} : {ex.GetType()} {ex.Message}"
});
return false;
}
Expand All @@ -134,18 +181,6 @@ bool TryGenerate(TypeDefinition typeDef, List<DiagnosticMessage> diagnosticMessa
return true;
}

bool NeedsInjectType(Type type)
=> !type.IsEnum &&
!type.IsValueType &&
!type.IsInterface &&
!(type.IsAbstract && type.IsSealed) &&
!typeof(Delegate).IsAssignableFrom(type) &&
!typeof(Attribute).IsAssignableFrom(type) &&
!type.IsGenericType &&
(targetNamespaces == null ||
targetNamespaces.Count <= 0 ||
targetNamespaces.Contains(type.Namespace));

void GenerateInnerInjectorType(TypeDefinition typeDef, InjectTypeInfo injectTypeInfo)
{
var injectorTypeDef = new TypeDefinition(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.IO;
using System.Linq;
using System.Reflection;
using Unity.CompilationPipeline.Common.Diagnostics;
using Unity.CompilationPipeline.Common.ILPostProcessing;
using Mono.Cecil;
Expand All @@ -26,7 +27,7 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly)
return null;

var assemblyDefinition = Utils.LoadAssemblyDefinition(compiledAssembly);
var generator = new InjectionILGenerator(assemblyDefinition.MainModule, null);
var generator = new InjectionILGenerator(assemblyDefinition.MainModule, compiledAssembly, null);

if (generator.TryGenerate(out var diagnosticMessages))
{
Expand Down

1 comment on commit 30299a2

@vercel
Copy link

@vercel vercel bot commented on 30299a2 Apr 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.