Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
TypeNameParser.cs
Go to the documentation of this file.
2using System.IO;
7using System.Text;
9
10namespace System;
11
12internal sealed class TypeNameParser : IDisposable
13{
15
16 private static readonly char[] SPECIAL_CHARS = new char[7] { ',', '[', ']', '&', '*', '+', '\\' };
17
18 [DllImport("QCall", CharSet = CharSet.Unicode)]
19 private static extern void _CreateTypeNameParser(string typeName, ObjectHandleOnStack retHandle, bool throwOnError);
20
21 [DllImport("QCall", CharSet = CharSet.Unicode)]
22 private static extern void _GetNames(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
23
24 [DllImport("QCall", CharSet = CharSet.Unicode)]
25 private static extern void _GetTypeArguments(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
26
27 [DllImport("QCall", CharSet = CharSet.Unicode)]
28 private static extern void _GetModifiers(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
29
30 [DllImport("QCall", CharSet = CharSet.Unicode)]
31 private static extern void _GetAssemblyName(SafeTypeNameParserHandle pTypeNameParser, StringHandleOnStack retString);
32
33 [RequiresUnreferencedCode("The type might be removed")]
34 internal static Type GetType(string typeName, Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark)
35 {
36 if (typeName == null)
37 {
38 throw new ArgumentNullException("typeName");
39 }
40 if (typeName.Length > 0 && typeName[0] == '\0')
41 {
43 }
44 Type result = null;
45 SafeTypeNameParserHandle safeTypeNameParserHandle = CreateTypeNameParser(typeName, throwOnError);
46 if (safeTypeNameParserHandle != null)
47 {
48 using TypeNameParser typeNameParser = new TypeNameParser(safeTypeNameParserHandle);
49 result = typeNameParser.ConstructType(assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
50 }
51 return result;
52 }
53
58
59 public void Dispose()
60 {
62 }
63
64 [RequiresUnreferencedCode("The type might be removed")]
65 private unsafe Type ConstructType(Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark)
66 {
67 Assembly assembly = null;
68 string assemblyName = GetAssemblyName();
69 if (assemblyName.Length > 0)
70 {
71 assembly = ResolveAssembly(assemblyName, assemblyResolver, throwOnError, ref stackMark);
72 if (assembly == null)
73 {
74 return null;
75 }
76 }
77 string[] names = GetNames();
78 if (names == null)
79 {
80 if (throwOnError)
81 {
83 }
84 return null;
85 }
86 Type type = ResolveType(assembly, names, typeResolver, throwOnError, ignoreCase, ref stackMark);
87 if (type == null)
88 {
89 return null;
90 }
92 Type[] array = null;
93 if (typeArguments != null)
94 {
95 array = new Type[typeArguments.Length];
96 for (int i = 0; i < typeArguments.Length; i++)
97 {
98 using (TypeNameParser typeNameParser = new TypeNameParser(typeArguments[i]))
99 {
100 array[i] = typeNameParser.ConstructType(assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
101 }
102 if (array[i] == null)
103 {
104 return null;
105 }
106 }
107 }
108 int[] modifiers = GetModifiers();
109 fixed (int* value = modifiers)
110 {
111 IntPtr pModifiers = new IntPtr(value);
112 return RuntimeTypeHandle.GetTypeHelper(type, array, pModifiers, (modifiers != null) ? modifiers.Length : 0);
113 }
114 }
115
116 private static Assembly ResolveAssembly(string asmName, Func<AssemblyName, Assembly> assemblyResolver, bool throwOnError, ref StackCrawlMark stackMark)
117 {
118 Assembly assembly;
119 if (assemblyResolver == null)
120 {
121 if (throwOnError)
122 {
124 }
125 else
126 {
127 try
128 {
130 }
132 {
133 return null;
134 }
135 }
136 }
137 else
138 {
139 assembly = assemblyResolver(new AssemblyName(asmName));
140 if (assembly == null && throwOnError)
141 {
143 }
144 }
145 return assembly;
146 }
147
148 [RequiresUnreferencedCode("The type might be removed")]
149 private static Type ResolveType(Assembly assembly, string[] names, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark)
150 {
151 string text = EscapeTypeName(names[0]);
152 Type type;
153 if (typeResolver == null)
154 {
155 type = ((!(assembly == null)) ? assembly.GetType(text, throwOnError, ignoreCase) : RuntimeType.GetType(text, throwOnError, ignoreCase, ref stackMark));
156 }
157 else
158 {
159 type = typeResolver(assembly, text, ignoreCase);
160 if (type == null && throwOnError)
161 {
162 string message = ((assembly == null) ? SR.Format(SR.TypeLoad_ResolveType, text) : SR.Format(SR.TypeLoad_ResolveTypeFromAssembly, text, assembly.FullName));
163 throw new TypeLoadException(message);
164 }
165 }
166 if (type != null)
167 {
168 BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic;
169 if (ignoreCase)
170 {
171 bindingFlags |= BindingFlags.IgnoreCase;
172 }
173 for (int i = 1; i < names.Length; i++)
174 {
175 type = type.GetNestedType(names[i], bindingFlags);
176 if (type == null)
177 {
178 if (!throwOnError)
179 {
180 break;
181 }
182 throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveNestedType, names[i], names[i - 1]));
183 }
184 }
185 }
186 return type;
187 }
188
189 private static string EscapeTypeName(string name)
190 {
191 if (name.IndexOfAny(SPECIAL_CHARS) < 0)
192 {
193 return name;
194 }
195 Span<char> initialBuffer = stackalloc char[64];
196 ValueStringBuilder valueStringBuilder = new ValueStringBuilder(initialBuffer);
197 foreach (char c in name)
198 {
199 if (Array.IndexOf(SPECIAL_CHARS, c) >= 0)
200 {
201 valueStringBuilder.Append('\\');
202 }
203 valueStringBuilder.Append(c);
204 }
205 return valueStringBuilder.ToString();
206 }
207
208 private static SafeTypeNameParserHandle CreateTypeNameParser(string typeName, bool throwOnError)
209 {
211 _CreateTypeNameParser(typeName, ObjectHandleOnStack.Create(ref o), throwOnError);
212 return o;
213 }
214
215 private string[] GetNames()
216 {
217 string[] o = null;
219 return o;
220 }
221
223 {
224 SafeTypeNameParserHandle[] o = null;
226 return o;
227 }
228
229 private int[] GetModifiers()
230 {
231 int[] o = null;
233 return o;
234 }
235
236 private string GetAssemblyName()
237 {
238 string s = null;
240 return s;
241 }
242}
int IList. IndexOf(object value)
Definition Array.cs:1228
virtual ? string FullName
Definition Assembly.cs:74
virtual ? Type GetType(string name)
Definition Assembly.cs:305
static RuntimeAssembly InternalLoad(string assemblyName, ref StackCrawlMark stackMark, AssemblyLoadContext assemblyLoadContext=null)
static RuntimeType GetType(string typeName, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark)
static ? AssemblyLoadContext CurrentContextualReflectionContext
static string Format_StringZeroLength
Definition SR.cs:1360
static string TypeLoad_ResolveTypeFromAssembly
Definition SR.cs:2018
static string TypeLoad_ResolveNestedType
Definition SR.cs:2014
static string Arg_TypeLoadNullStr
Definition SR.cs:434
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string FileNotFound_ResolveAssembly
Definition SR.cs:1314
static string TypeLoad_ResolveType
Definition SR.cs:2016
Definition SR.cs:7
static void _GetTypeArguments(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray)
static readonly char[] SPECIAL_CHARS
static void _CreateTypeNameParser(string typeName, ObjectHandleOnStack retHandle, bool throwOnError)
unsafe Type ConstructType(Func< AssemblyName, Assembly > assemblyResolver, Func< Assembly, string, bool, Type > typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark)
static void _GetNames(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray)
TypeNameParser(SafeTypeNameParserHandle handle)
static string EscapeTypeName(string name)
static SafeTypeNameParserHandle CreateTypeNameParser(string typeName, bool throwOnError)
static Assembly ResolveAssembly(string asmName, Func< AssemblyName, Assembly > assemblyResolver, bool throwOnError, ref StackCrawlMark stackMark)
static Type ResolveType(Assembly assembly, string[] names, Func< Assembly, string, bool, Type > typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark)
SafeTypeNameParserHandle[] GetTypeArguments()
readonly SafeTypeNameParserHandle m_NativeParser
static Type GetType(string typeName, Func< AssemblyName, Assembly > assemblyResolver, Func< Assembly, string, bool, Type > typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark)
static void _GetAssemblyName(SafeTypeNameParserHandle pTypeNameParser, StringHandleOnStack retString)
static void _GetModifiers(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray)
static unsafe Type GetTypeHelper(Type typeStart, Type[] genericArgs, IntPtr pModifiers, int cModifiers)