Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 4507e0b

Browse files
committed
Add AOT Helper code which also seems to help UWP .NET Native where the official rd.xml has no effect
1 parent 82c58d8 commit 4507e0b

File tree

2 files changed

+210
-7
lines changed

2 files changed

+210
-7
lines changed

build/copy-pcl.bat

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ COPY ..\src\ServiceStack.Text\PclExport.Net40.cs ..\..\ServiceStack\src\Service
99
COPY ..\src\ServiceStack.Text\PclExport.Net40.cs ..\..\ServiceStack\src\ServiceStack.Pcl.Ios\
1010
COPY ..\src\ServiceStack.Text\PclExport.Net40.cs ..\..\ServiceStack\src\ServiceStack.Pcl.Net45\
1111
COPY ..\src\ServiceStack.Text\PclExport.WinStore.cs ..\..\ServiceStack\src\ServiceStack.Pcl.WinStore\
12+
COPY ..\src\ServiceStack.Text\PclExport.WinStore.cs ..\..\ServiceStack\src\ServiceStack.Pcl.WinStore81\
1213

1314
COPY ..\src\ServiceStack.Text\Pcl.* ..\..\ServiceStack\src\ServiceStack.Pcl.Android\
1415
COPY ..\src\ServiceStack.Text\Pcl.* ..\..\ServiceStack\src\ServiceStack.Pcl.Ios\
1516
COPY ..\src\ServiceStack.Text\Pcl.* ..\..\ServiceStack\src\ServiceStack.Pcl.Net45\
1617
COPY ..\src\ServiceStack.Text\Pcl.* ..\..\ServiceStack\src\ServiceStack.Pcl.WinStore\
18+
COPY ..\src\ServiceStack.Text\Pcl.* ..\..\ServiceStack\src\ServiceStack.Pcl.WinStore81\
1719

src/ServiceStack.Text/PclExport.WinStore.cs

Lines changed: 208 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
using System.IO;
88
using System.Linq;
99
using System.Reflection;
10+
using ServiceStack.Text;
11+
using ServiceStack.Text.Common;
12+
using ServiceStack.Text.Json;
1013

1114
namespace ServiceStack
1215
{
@@ -31,7 +34,7 @@ public override string ReadAllText(string filePath)
3134
task.AsTask().Wait();
3235

3336
var file = task.GetResults();
34-
37+
3538
var streamTask = file.OpenStreamForReadAsync();
3639
streamTask.Wait();
3740

@@ -74,21 +77,21 @@ private sealed class AppDomain
7477
{
7578
public static AppDomain CurrentDomain { get; private set; }
7679
public static Assembly[] cacheObj = null;
77-
80+
7881
static AppDomain()
7982
{
8083
CurrentDomain = new AppDomain();
8184
}
82-
85+
8386
public Assembly[] GetAssemblies()
8487
{
8588
return cacheObj ?? GetAssemblyListAsync().Result.ToArray();
8689
}
87-
90+
8891
private async System.Threading.Tasks.Task<IEnumerable<Assembly>> GetAssemblyListAsync()
8992
{
9093
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
91-
94+
9295
var assemblies = new List<Assembly>();
9396
foreach (Windows.Storage.StorageFile file in await folder.GetFilesAsync())
9497
{
@@ -97,7 +100,7 @@ private async System.Threading.Tasks.Task<IEnumerable<Assembly>> GetAssemblyList
97100
try
98101
{
99102
var filename = file.Name.Substring(0, file.Name.Length - file.FileType.Length);
100-
AssemblyName name = new AssemblyName() { Name = filename };
103+
AssemblyName name = new AssemblyName() {Name = filename};
101104
Assembly asm = Assembly.Load(name);
102105
assemblies.Add(asm);
103106
}
@@ -109,7 +112,7 @@ private async System.Threading.Tasks.Task<IEnumerable<Assembly>> GetAssemblyList
109112
}
110113

111114
cacheObj = assemblies.ToArray();
112-
115+
113116
return cacheObj;
114117
}
115118
}
@@ -125,6 +128,204 @@ public override string GetAssemblyCodeBase(Assembly assembly)
125128
// // .Net 4.0+ does this under the hood anyway.
126129
// return TimeZoneInfo.ConvertTimeToUtc(dateTime);
127130
//}
131+
132+
public override void VerifyInAssembly(Type accessType, ICollection<string> assemblyNames)
133+
{
134+
}
135+
136+
public static void InitForAot()
137+
{
138+
}
139+
140+
internal class Poco
141+
{
142+
public string Dummy { get; set; }
143+
}
144+
145+
public override void RegisterForAot()
146+
{
147+
RegisterTypeForAot<Poco>();
148+
149+
RegisterElement<Poco, string>();
150+
151+
RegisterElement<Poco, bool>();
152+
RegisterElement<Poco, char>();
153+
RegisterElement<Poco, byte>();
154+
RegisterElement<Poco, sbyte>();
155+
RegisterElement<Poco, short>();
156+
RegisterElement<Poco, ushort>();
157+
RegisterElement<Poco, int>();
158+
RegisterElement<Poco, uint>();
159+
160+
RegisterElement<Poco, long>();
161+
RegisterElement<Poco, ulong>();
162+
RegisterElement<Poco, float>();
163+
RegisterElement<Poco, double>();
164+
RegisterElement<Poco, decimal>();
165+
166+
RegisterElement<Poco, bool?>();
167+
RegisterElement<Poco, char?>();
168+
RegisterElement<Poco, byte?>();
169+
RegisterElement<Poco, sbyte?>();
170+
RegisterElement<Poco, short?>();
171+
RegisterElement<Poco, ushort?>();
172+
RegisterElement<Poco, int?>();
173+
RegisterElement<Poco, uint?>();
174+
RegisterElement<Poco, long?>();
175+
RegisterElement<Poco, ulong?>();
176+
RegisterElement<Poco, float?>();
177+
RegisterElement<Poco, double?>();
178+
RegisterElement<Poco, decimal?>();
179+
180+
//RegisterElement<Poco, JsonValue>();
181+
182+
RegisterTypeForAot<DayOfWeek>(); // used by DateTime
183+
184+
// register built in structs
185+
RegisterTypeForAot<Guid>();
186+
RegisterTypeForAot<TimeSpan>();
187+
RegisterTypeForAot<DateTime>();
188+
RegisterTypeForAot<DateTimeOffset>();
189+
190+
RegisterTypeForAot<Guid?>();
191+
RegisterTypeForAot<TimeSpan?>();
192+
RegisterTypeForAot<DateTime?>();
193+
RegisterTypeForAot<DateTimeOffset?>();
194+
}
195+
196+
public static void RegisterTypeForAot<T>()
197+
{
198+
AotConfig.RegisterSerializers<T>();
199+
}
200+
201+
public static void RegisterQueryStringWriter()
202+
{
203+
var i = 0;
204+
if (QueryStringWriter<Poco>.WriteFn() != null) i++;
205+
}
206+
207+
public static int RegisterElement<T, TElement>()
208+
{
209+
var i = 0;
210+
i += AotConfig.RegisterSerializers<TElement>();
211+
AotConfig.RegisterElement<T, TElement, JsonTypeSerializer>();
212+
AotConfig.RegisterElement<T, TElement, Text.Jsv.JsvTypeSerializer>();
213+
return i;
214+
}
215+
216+
internal class AotConfig
217+
{
218+
internal static JsReader<JsonTypeSerializer> jsonReader;
219+
internal static JsWriter<JsonTypeSerializer> jsonWriter;
220+
internal static JsReader<Text.Jsv.JsvTypeSerializer> jsvReader;
221+
internal static JsWriter<Text.Jsv.JsvTypeSerializer> jsvWriter;
222+
internal static JsonTypeSerializer jsonSerializer;
223+
internal static Text.Jsv.JsvTypeSerializer jsvSerializer;
224+
225+
static AotConfig()
226+
{
227+
jsonSerializer = new JsonTypeSerializer();
228+
jsvSerializer = new Text.Jsv.JsvTypeSerializer();
229+
jsonReader = new JsReader<JsonTypeSerializer>();
230+
jsonWriter = new JsWriter<JsonTypeSerializer>();
231+
jsvReader = new JsReader<Text.Jsv.JsvTypeSerializer>();
232+
jsvWriter = new JsWriter<Text.Jsv.JsvTypeSerializer>();
233+
}
234+
235+
internal static int RegisterSerializers<T>()
236+
{
237+
var i = 0;
238+
i += Register<T, JsonTypeSerializer>();
239+
if (jsonSerializer.GetParseFn<T>() != null) i++;
240+
if (jsonSerializer.GetWriteFn<T>() != null) i++;
241+
if (jsonReader.GetParseFn<T>() != null) i++;
242+
if (jsonWriter.GetWriteFn<T>() != null) i++;
243+
244+
i += Register<T, Text.Jsv.JsvTypeSerializer>();
245+
if (jsvSerializer.GetParseFn<T>() != null) i++;
246+
if (jsvSerializer.GetWriteFn<T>() != null) i++;
247+
if (jsvReader.GetParseFn<T>() != null) i++;
248+
if (jsvWriter.GetWriteFn<T>() != null) i++;
249+
250+
//RegisterCsvSerializer<T>();
251+
RegisterQueryStringWriter();
252+
return i;
253+
}
254+
255+
internal static void RegisterCsvSerializer<T>()
256+
{
257+
CsvSerializer<T>.WriteFn();
258+
CsvSerializer<T>.WriteObject(null, null);
259+
CsvWriter<T>.Write(null, default(IEnumerable<T>));
260+
CsvWriter<T>.WriteRow(null, default(T));
261+
}
262+
263+
public static ParseStringDelegate GetParseFn(Type type)
264+
{
265+
var parseFn = JsonTypeSerializer.Instance.GetParseFn(type);
266+
return parseFn;
267+
}
268+
269+
internal static int Register<T, TSerializer>() where TSerializer : ITypeSerializer
270+
{
271+
var i = 0;
272+
273+
if (JsonWriter<T>.WriteFn() != null) i++;
274+
if (JsonWriter.Instance.GetWriteFn<T>() != null) i++;
275+
if (JsonReader.Instance.GetParseFn<T>() != null) i++;
276+
if (JsonReader<T>.Parse(null) != null) i++;
277+
if (JsonReader<T>.GetParseFn() != null) i++;
278+
//if (JsWriter.GetTypeSerializer<JsonTypeSerializer>().GetWriteFn<T>() != null) i++;
279+
if (new List<T>() != null) i++;
280+
if (new T[0] != null) i++;
281+
282+
JsConfig<T>.ExcludeTypeInfo = false;
283+
284+
if (JsConfig<T>.OnDeserializedFn != null) i++;
285+
if (JsConfig<T>.HasDeserializeFn) i++;
286+
if (JsConfig<T>.SerializeFn != null) i++;
287+
if (JsConfig<T>.DeSerializeFn != null) i++;
288+
//JsConfig<T>.SerializeFn = arg => "";
289+
//JsConfig<T>.DeSerializeFn = arg => default(T);
290+
if (TypeConfig<T>.Properties != null) i++;
291+
292+
WriteListsOfElements<T, TSerializer>.WriteList(null, null);
293+
WriteListsOfElements<T, TSerializer>.WriteIList(null, null);
294+
WriteListsOfElements<T, TSerializer>.WriteEnumerable(null, null);
295+
WriteListsOfElements<T, TSerializer>.WriteListValueType(null, null);
296+
WriteListsOfElements<T, TSerializer>.WriteIListValueType(null, null);
297+
WriteListsOfElements<T, TSerializer>.WriteGenericArrayValueType(null, null);
298+
WriteListsOfElements<T, TSerializer>.WriteArray(null, null);
299+
300+
TranslateListWithElements<T>.LateBoundTranslateToGenericICollection(null, null);
301+
TranslateListWithConvertibleElements<T, T>.LateBoundTranslateToGenericICollection(null, null);
302+
303+
QueryStringWriter<T>.WriteObject(null, null);
304+
return i;
305+
}
306+
307+
internal static void RegisterElement<T, TElement, TSerializer>() where TSerializer : ITypeSerializer
308+
{
309+
DeserializeDictionary<TSerializer>.ParseDictionary<T, TElement>(null, null, null, null);
310+
DeserializeDictionary<TSerializer>.ParseDictionary<TElement, T>(null, null, null, null);
311+
312+
ToStringDictionaryMethods<T, TElement, TSerializer>.WriteIDictionary(null, null, null, null);
313+
ToStringDictionaryMethods<TElement, T, TSerializer>.WriteIDictionary(null, null, null, null);
314+
315+
// Include List deserialisations from the Register<> method above. This solves issue where List<Guid> properties on responses deserialise to null.
316+
// No idea why this is happening because there is no visible exception raised. Suspect IOS is swallowing an AOT exception somewhere.
317+
DeserializeArrayWithElements<TElement, TSerializer>.ParseGenericArray(null, null);
318+
DeserializeListWithElements<TElement, TSerializer>.ParseGenericList(null, null, null);
319+
320+
// Cannot use the line below for some unknown reason - when trying to compile to run on device, mtouch bombs during native code compile.
321+
// Something about this line or its inner workings is offensive to mtouch. Luckily this was not needed for my List<Guide> issue.
322+
// DeserializeCollection<JsonTypeSerializer>.ParseCollection<TElement>(null, null, null);
323+
324+
TranslateListWithElements<TElement>.LateBoundTranslateToGenericICollection(null, typeof(List<TElement>));
325+
TranslateListWithConvertibleElements<TElement, TElement>.LateBoundTranslateToGenericICollection(null, typeof(List<TElement>));
326+
}
327+
}
328+
128329
}
129330
}
130331

0 commit comments

Comments
 (0)