A game about forced loneliness, made by TACStudios
at master 151 lines 6.2 kB view raw
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}