123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Mono.Cecil;
-
- namespace zzzUnity.Burst.CodeGen
- {
- /// <summary>
- /// Provides some Cecil Extensions.
- /// </summary>
- #if BURST_COMPILER_SHARED
- public
- #else
- internal
- #endif
- static class CecilExtensions
- {
- public static void BuildAssemblyQualifiedName(this TypeReference type, StringBuilder builder)
- {
- if (type == null) throw new ArgumentNullException(nameof(type));
-
- TypeReference elementType;
- type.BuildReflectionFullName(builder, out elementType, assemblyQualified: true);
-
- if (!(elementType is GenericParameter))
- {
- // Recover assembly reference from scope first (e.g for types imported), otherwise from Module.Assembly
- var assemblyReference = elementType.Scope as AssemblyNameReference ?? elementType.Module?.Assembly?.Name;
- if (assemblyReference != null)
- {
- builder.Append(", ").Append(assemblyReference);
- }
- }
- }
-
- public static void BuildReflectionFullName(this TypeReference type, StringBuilder builder, bool assemblyQualified)
- {
- BuildReflectionFullName(type, builder, out _, assemblyQualified);
- }
-
- public static void BuildReflectionFullName(this TypeReference type, StringBuilder builder, out TypeReference elementType, bool assemblyQualified)
- {
- if (type == null) throw new ArgumentNullException(nameof(type));
-
- if (type is PointerType pointerType)
- {
- pointerType.ElementType.BuildReflectionFullName(builder, out elementType, assemblyQualified);
- builder.Append("*");
- }
- else if (type is PinnedType pinnedType)
- {
- pinnedType.ElementType.BuildReflectionFullName(builder, out elementType, assemblyQualified);
- builder.Append(" pinned");
- }
- else if (type is ByReferenceType byReferenceType)
- {
- byReferenceType.ElementType.BuildReflectionFullName(builder, out elementType, assemblyQualified);
- builder.Append("&");
- }
- else if (type is ArrayType arrayType)
- {
- arrayType.ElementType.BuildReflectionFullName(builder, out elementType, assemblyQualified);
- builder.Append("[]");
- }
- else if (type is GenericParameter genericParameter)
- {
- elementType = type;
- builder.Append(genericParameter.Type == GenericParameterType.Method ? "!!" : "!");
- builder.Append(genericParameter.Position);
- }
- else if (type is FunctionPointerType functionPointerType)
- {
- elementType = type;
- builder.Append("delegate* ");
- builder.Append(functionPointerType.CallingConvention switch
- {
- MethodCallingConvention.Default => "managed",
- MethodCallingConvention.Unmanaged => "unmanaged",
- MethodCallingConvention.C => "unmanaged[Cdecl]",
- MethodCallingConvention.FastCall => "unmanaged[Fastcall]",
- MethodCallingConvention.ThisCall => "unmanaged[Thiscall]",
- MethodCallingConvention.StdCall => "unmanaged[Stdcall]",
- MethodCallingConvention.Generic => "generic",
- MethodCallingConvention.VarArg => "vararg",
- var conv => $"<unknown calling conv: {(int)conv}>",
- });
- builder.Append("<");
- for (var i = 0; i < functionPointerType.Parameters.Count; i++)
- {
- var param = functionPointerType.Parameters[i];
- param.ParameterType.BuildAssemblyQualifiedName(builder);
- builder.Append(", ");
- }
-
- functionPointerType.MethodReturnType.ReturnType.BuildAssemblyQualifiedName(builder);
- builder.Append(">");
- }
- else
- {
- elementType = type;
- var types = new List<TypeReference>();
- var declaringType = type;
- while (declaringType != null)
- {
- types.Add(declaringType);
- declaringType = declaringType.DeclaringType;
- }
-
- var baseType = types[types.Count - 1];
-
- if (!string.IsNullOrEmpty(baseType.Namespace))
- {
- builder.Append(baseType.Namespace);
- builder.Append(".");
- }
-
- builder.Append(baseType.Name);
- for (int i = types.Count - 2; i >= 0; i--)
- {
- var nestedType = types[i];
- builder.Append("+").Append(nestedType.Name);
- }
-
- if (elementType is GenericInstanceType genericInstanceType && genericInstanceType.HasGenericArguments)
- {
- builder.Append("[");
- for (var i = 0; i < genericInstanceType.GenericArguments.Count; i++)
- {
- var genericArgument = genericInstanceType.GenericArguments[i];
- if (i > 0)
- {
- builder.Append(",");
- }
-
- if (assemblyQualified)
- {
- builder.Append("[");
- genericArgument.BuildAssemblyQualifiedName(builder);
- builder.Append("]");
- }
- else
- {
- genericArgument.BuildReflectionFullName(builder, out var _, assemblyQualified: true);
- }
- }
- builder.Append("]");
- }
- }
- }
- }
- }
|