A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.Text;
4using Mono.Cecil;
5
6namespace zzzUnity.Burst.CodeGen
7{
8 /// <summary>
9 /// Provides some Cecil Extensions.
10 /// </summary>
11#if BURST_COMPILER_SHARED
12 public
13#else
14 internal
15#endif
16 static class CecilExtensions
17 {
18 public static void BuildAssemblyQualifiedName(this TypeReference type, StringBuilder builder)
19 {
20 if (type == null) throw new ArgumentNullException(nameof(type));
21
22 TypeReference elementType;
23 type.BuildReflectionFullName(builder, out elementType, assemblyQualified: true);
24
25 if (!(elementType is GenericParameter))
26 {
27 // Recover assembly reference from scope first (e.g for types imported), otherwise from Module.Assembly
28 var assemblyReference = elementType.Scope as AssemblyNameReference ?? elementType.Module?.Assembly?.Name;
29 if (assemblyReference != null)
30 {
31 builder.Append(", ").Append(assemblyReference);
32 }
33 }
34 }
35
36 public static void BuildReflectionFullName(this TypeReference type, StringBuilder builder, bool assemblyQualified)
37 {
38 BuildReflectionFullName(type, builder, out _, assemblyQualified);
39 }
40
41 public static void BuildReflectionFullName(this TypeReference type, StringBuilder builder, out TypeReference elementType, bool assemblyQualified)
42 {
43 if (type == null) throw new ArgumentNullException(nameof(type));
44
45 if (type is PointerType pointerType)
46 {
47 pointerType.ElementType.BuildReflectionFullName(builder, out elementType, assemblyQualified);
48 builder.Append("*");
49 }
50 else if (type is PinnedType pinnedType)
51 {
52 pinnedType.ElementType.BuildReflectionFullName(builder, out elementType, assemblyQualified);
53 builder.Append(" pinned");
54 }
55 else if (type is ByReferenceType byReferenceType)
56 {
57 byReferenceType.ElementType.BuildReflectionFullName(builder, out elementType, assemblyQualified);
58 builder.Append("&");
59 }
60 else if (type is ArrayType arrayType)
61 {
62 arrayType.ElementType.BuildReflectionFullName(builder, out elementType, assemblyQualified);
63 builder.Append("[]");
64 }
65 else if (type is GenericParameter genericParameter)
66 {
67 elementType = type;
68 builder.Append(genericParameter.Type == GenericParameterType.Method ? "!!" : "!");
69 builder.Append(genericParameter.Position);
70 }
71 else if (type is FunctionPointerType functionPointerType)
72 {
73 elementType = type;
74 builder.Append("delegate* ");
75 builder.Append(functionPointerType.CallingConvention switch
76 {
77 MethodCallingConvention.Default => "managed",
78 MethodCallingConvention.Unmanaged => "unmanaged",
79 MethodCallingConvention.C => "unmanaged[Cdecl]",
80 MethodCallingConvention.FastCall => "unmanaged[Fastcall]",
81 MethodCallingConvention.ThisCall => "unmanaged[Thiscall]",
82 MethodCallingConvention.StdCall => "unmanaged[Stdcall]",
83 MethodCallingConvention.Generic => "generic",
84 MethodCallingConvention.VarArg => "vararg",
85 var conv => $"<unknown calling conv: {(int)conv}>",
86 });
87 builder.Append("<");
88 for (var i = 0; i < functionPointerType.Parameters.Count; i++)
89 {
90 var param = functionPointerType.Parameters[i];
91 param.ParameterType.BuildAssemblyQualifiedName(builder);
92 builder.Append(", ");
93 }
94
95 functionPointerType.MethodReturnType.ReturnType.BuildAssemblyQualifiedName(builder);
96 builder.Append(">");
97 }
98 else
99 {
100 elementType = type;
101 var types = new List<TypeReference>();
102 var declaringType = type;
103 while (declaringType != null)
104 {
105 types.Add(declaringType);
106 declaringType = declaringType.DeclaringType;
107 }
108
109 var baseType = types[types.Count - 1];
110
111 if (!string.IsNullOrEmpty(baseType.Namespace))
112 {
113 builder.Append(baseType.Namespace);
114 builder.Append(".");
115 }
116
117 builder.Append(baseType.Name);
118 for (int i = types.Count - 2; i >= 0; i--)
119 {
120 var nestedType = types[i];
121 builder.Append("+").Append(nestedType.Name);
122 }
123
124 if (elementType is GenericInstanceType genericInstanceType && genericInstanceType.HasGenericArguments)
125 {
126 builder.Append("[");
127 for (var i = 0; i < genericInstanceType.GenericArguments.Count; i++)
128 {
129 var genericArgument = genericInstanceType.GenericArguments[i];
130 if (i > 0)
131 {
132 builder.Append(",");
133 }
134
135 if (assemblyQualified)
136 {
137 builder.Append("[");
138 genericArgument.BuildAssemblyQualifiedName(builder);
139 builder.Append("]");
140 }
141 else
142 {
143 genericArgument.BuildReflectionFullName(builder, out var _, assemblyQualified: true);
144 }
145 }
146 builder.Append("]");
147 }
148 }
149 }
150 }
151}