@@ -17,28 +17,28 @@ namespace CSharpScriptSerialization
1717{
1818 public abstract class CSScriptSerializer : ICSScriptSerializer
1919 {
20- protected CSScriptSerializer ( Type type )
21- {
22- Type = type ;
23- }
24-
25- public Type Type { get ; }
26-
27- public abstract ExpressionSyntax GetCreation ( object obj ) ;
28-
2920 public static readonly List < ICSScriptSerializerFactory > SerializerFactories =
3021 new List < ICSScriptSerializerFactory > ( ) ;
3122
3223 public static readonly ConcurrentDictionary < Type , ICSScriptSerializer > Serializers =
3324 new ConcurrentDictionary < Type , ICSScriptSerializer > ( ) ;
3425
35- public static T Deserialize < T > ( string script )
36- => DeserializeAsync < T > ( script ) . GetAwaiter ( ) . GetResult ( ) ;
26+ private static readonly ConcurrentDictionary < Type , object > TypeDefaults =
27+ new ConcurrentDictionary < Type , object > ( ) ;
28+
29+ protected CSScriptSerializer ( Type type ) => Type = type ;
30+
31+ public Type Type { get ; }
32+
33+ public abstract ExpressionSyntax GetCreation ( object obj ) ;
34+
35+ public static T Deserialize < T > ( string script ) => DeserializeAsync < T > ( script ) . GetAwaiter ( ) . GetResult ( ) ;
3736
3837 public static Task < T > DeserializeAsync < T > ( string script )
3938 => DeserializeAsync < T > ( script , Enumerable . Empty < Assembly > ( ) , Enumerable . Empty < string > ( ) ) ;
4039
41- public static T Deserialize < T > ( string script , IEnumerable < Assembly > referencedAssemblies , IEnumerable < string > imports )
40+ public static T Deserialize < T > ( string script , IEnumerable < Assembly > referencedAssemblies ,
41+ IEnumerable < string > imports )
4242 => DeserializeAsync < T > ( script , referencedAssemblies , imports ) . GetAwaiter ( ) . GetResult ( ) ;
4343
4444 public static Task < T > DeserializeAsync < T > (
@@ -73,30 +73,23 @@ public static string Serialize(object obj)
7373 }
7474 }
7575
76- public static CompilationUnitSyntax GetCompilationUnitExpression ( object obj )
77- => CompilationUnit ( )
78- . WithMembers (
79- SingletonList < MemberDeclarationSyntax > (
80- GlobalStatement (
81- ExpressionStatement ( GetCreationExpression ( obj ) )
82- . WithSemicolonToken ( MissingToken ( SyntaxKind . SemicolonToken ) ) ) ) ) ;
76+ public static CompilationUnitSyntax GetCompilationUnitExpression ( object obj ) => CompilationUnit ( )
77+ . WithMembers (
78+ SingletonList < MemberDeclarationSyntax > (
79+ GlobalStatement (
80+ ExpressionStatement ( GetCreationExpression ( obj ) )
81+ . WithSemicolonToken ( MissingToken ( SyntaxKind . SemicolonToken ) ) ) ) ) ;
8382
84- public static ExpressionSyntax GetCreationExpression ( object obj )
85- {
86- return GetSerializer ( obj ) . GetCreation ( obj ) ;
87- }
83+ public static ExpressionSyntax GetCreationExpression ( object obj ) => GetSerializer ( obj ) . GetCreation ( obj ) ;
8884
8985 private static ICSScriptSerializer GetSerializer ( object obj )
9086 {
91- if ( obj == null )
87+ switch ( obj )
9288 {
93- return NullCSScriptSerializer . Instance ;
94- }
95-
96- var serializable = obj as ICSScriptSerializable ;
97- if ( serializable != null )
98- {
99- return serializable . GetSerializer ( ) ;
89+ case null :
90+ return NullCSScriptSerializer . Instance ;
91+ case ICSScriptSerializable serializable :
92+ return serializable . GetSerializer ( ) ;
10093 }
10194
10295 var type = UnwrapNullableType ( obj . GetType ( ) ) ;
@@ -166,6 +159,16 @@ private static ICSScriptSerializer CreateSerializer(Type type)
166159 new Func < TimeSpan , object > [ ] { t => t . Ticks } ) ;
167160 }
168161
162+ if ( typeof ( Type ) . GetTypeInfo ( ) . IsAssignableFrom ( type ) )
163+ {
164+ return new TypeCSScriptSerializer ( type ) ;
165+ }
166+
167+ if ( type == typeof ( object ) )
168+ {
169+ return new ConstructorCSScriptSerializer < object > ( ) ;
170+ }
171+
169172 if ( type . IsArray )
170173 {
171174 return new ArrayCSScriptSerializer ( type ) ;
@@ -174,6 +177,7 @@ private static ICSScriptSerializer CreateSerializer(Type type)
174177 if ( type . IsConstructedGenericType )
175178 {
176179 var genericDefinition = type . GetGenericTypeDefinition ( ) ;
180+
177181 if ( genericDefinition == typeof ( Tuple < > ) )
178182 {
179183 return CreateConstructorCSScriptSerializer ( type , CreateTupleGetters ( type , arity : 1 ) ) ;
@@ -206,6 +210,39 @@ private static ICSScriptSerializer CreateSerializer(Type type)
206210 {
207211 return CreateConstructorCSScriptSerializer ( type , CreateTupleGetters ( type , arity : 8 ) ) ;
208212 }
213+
214+ if ( genericDefinition == typeof ( ValueTuple < > ) )
215+ {
216+ return new ValueTupleCSScriptSerializer ( type , CreateValueTupleGetters ( type , arity : 1 ) ) ;
217+ }
218+ if ( genericDefinition == typeof ( ValueTuple < , > ) )
219+ {
220+ return new ValueTupleCSScriptSerializer ( type , CreateValueTupleGetters ( type , arity : 2 ) ) ;
221+ }
222+ if ( genericDefinition == typeof ( ValueTuple < , , > ) )
223+ {
224+ return new ValueTupleCSScriptSerializer ( type , CreateValueTupleGetters ( type , arity : 3 ) ) ;
225+ }
226+ if ( genericDefinition == typeof ( ValueTuple < , , , > ) )
227+ {
228+ return new ValueTupleCSScriptSerializer ( type , CreateValueTupleGetters ( type , arity : 4 ) ) ;
229+ }
230+ if ( genericDefinition == typeof ( ValueTuple < , , , , > ) )
231+ {
232+ return new ValueTupleCSScriptSerializer ( type , CreateValueTupleGetters ( type , arity : 5 ) ) ;
233+ }
234+ if ( genericDefinition == typeof ( ValueTuple < , , , , , > ) )
235+ {
236+ return new ValueTupleCSScriptSerializer ( type , CreateValueTupleGetters ( type , arity : 6 ) ) ;
237+ }
238+ if ( genericDefinition == typeof ( ValueTuple < , , , , , , > ) )
239+ {
240+ return new ValueTupleCSScriptSerializer ( type , CreateValueTupleGetters ( type , arity : 7 ) ) ;
241+ }
242+ if ( genericDefinition == typeof ( ValueTuple < , , , , , , , > ) )
243+ {
244+ return new ValueTupleCSScriptSerializer ( type , CreateValueTupleGetters ( type , arity : 8 ) ) ;
245+ }
209246 }
210247
211248 foreach ( var additionalSerializerFactory in SerializerFactories )
@@ -259,17 +296,15 @@ private static IEnumerable<object> ToEnumerable(IEnumerator enumerator)
259296
260297 private static CSScriptSerializer CreateConstructorCSScriptSerializer (
261298 Type type ,
262- IReadOnlyCollection < Func < object , object > > parameterGetters )
263- => ( CSScriptSerializer ) GetDeclaredConstructor (
299+ IReadOnlyCollection < Func < object , object > > parameterGetters ) => ( CSScriptSerializer ) GetDeclaredConstructor (
264300 typeof ( ConstructorCSScriptSerializer < > ) . MakeGenericType ( type ) ,
265301 new [ ] { typeof ( IReadOnlyCollection < Func < object , object > > ) } )
266302 . Invoke ( new object [ ] { parameterGetters } ) ;
267303
268304 private static CSScriptSerializer CreateCollectionCSScriptSerializer (
269305 Type type ,
270306 IReadOnlyCollection < Func < object , object > > elementDecomposers ,
271- Func < object , IEnumerable < object > > getEnumerable )
272- => ( CSScriptSerializer ) GetDeclaredConstructor (
307+ Func < object , IEnumerable < object > > getEnumerable ) => ( CSScriptSerializer ) GetDeclaredConstructor (
273308 typeof ( CollectionCSScriptSerializer < > ) . MakeGenericType ( type ) ,
274309 new [ ] { typeof ( IReadOnlyCollection < Func < object , object > > ) , typeof ( Func < object , IEnumerable < object > > ) } )
275310 . Invoke ( new object [ ] { elementDecomposers , getEnumerable } ) ;
@@ -285,6 +320,17 @@ private static Func<object, object>[] CreateTupleGetters(Type type, int arity)
285320 return getters . ToArray ( ) ;
286321 }
287322
323+ private static Func < object , object > [ ] CreateValueTupleGetters ( Type type , int arity )
324+ {
325+ var getters = new List < Func < object , object > > ( ) ;
326+ for ( var i = 1 ; i <= arity ; i ++ )
327+ {
328+ var itemField = type . GetTypeInfo ( ) . GetField ( "Item" + i ) ;
329+ getters . Add ( o => itemField . GetValue ( o ) ) ;
330+ }
331+ return getters . ToArray ( ) ;
332+ }
333+
288334 protected static bool IsConstructable ( Type type )
289335 => ! type . GetTypeInfo ( ) . IsInterface
290336 && ! type . GetTypeInfo ( ) . IsAbstract
@@ -312,17 +358,12 @@ protected static Type TryGetElementType(Type type, Type interfaceOrBaseType)
312358 return types . Count == 1 ? types [ index : 0 ] . GetTypeInfo ( ) . GenericTypeArguments . FirstOrDefault ( ) : null ;
313359 }
314360
315- private static readonly ConcurrentDictionary < Type , object > TypeDefaults =
316- new ConcurrentDictionary < Type , object > ( ) ;
317-
318361 protected static object GetDefault ( Type type )
319362 => type . GetTypeInfo ( ) . IsValueType ? TypeDefaults . GetOrAdd ( type , Activator . CreateInstance ) : null ;
320363
321- protected static bool IsDefault ( object obj )
322- => IsDefault ( obj , obj . GetType ( ) ) ;
364+ protected static bool IsDefault ( object obj ) => IsDefault ( obj , obj . GetType ( ) ) ;
323365
324- protected static bool IsDefault ( object obj , Type type )
325- => obj == null || obj . Equals ( GetDefault ( type ) ) ;
366+ protected static bool IsDefault ( object obj , Type type ) => obj == null || obj . Equals ( GetDefault ( type ) ) ;
326367
327368 protected static IEnumerable < Type > GetGenericTypeImplementations ( Type type , Type interfaceOrBaseType )
328369 {
@@ -334,7 +375,7 @@ protected static IEnumerable<Type> GetGenericTypeImplementations(Type type, Type
334375 : GetBaseTypes ( type ) )
335376 . Union ( new [ ] { type } )
336377 . Where ( t => t . GetTypeInfo ( ) . IsGenericType
337- && ( t . GetGenericTypeDefinition ( ) == interfaceOrBaseType ) ) ;
378+ && t . GetGenericTypeDefinition ( ) == interfaceOrBaseType ) ;
338379 }
339380
340381 return Enumerable . Empty < Type > ( ) ;
@@ -441,7 +482,7 @@ protected static TypeSyntax GetTypeSyntax(Type type)
441482 GetArrayRanks ( type ) ) ) ;
442483 }
443484
444- return GetNameSyntax ( type , null ) ;
485+ return GetNameSyntax ( type , genericArguments : null ) ;
445486 }
446487
447488 private static NameSyntax GetNameSyntax ( Type type , List < Type > genericArguments )
@@ -454,8 +495,8 @@ private static NameSyntax GetNameSyntax(Type type, List<Type> genericArguments)
454495 if ( declaringType != null )
455496 {
456497 var genericParameters = declaringType . GetTypeInfo ( ) . GenericTypeParameters ;
457- declaringTypeGenericArguments = genericArguments . GetRange ( 0 , genericParameters . Length ) ;
458- genericArguments . RemoveRange ( 0 , genericParameters . Length ) ;
498+ declaringTypeGenericArguments = genericArguments . GetRange ( index : 0 , count : genericParameters . Length ) ;
499+ genericArguments . RemoveRange ( index : 0 , count : genericParameters . Length ) ;
459500 }
460501
461502 var simpleName = genericArguments . Count > 0
@@ -491,8 +532,7 @@ private static IEnumerable<ArrayRankSpecifierSyntax> GetArrayRanks(Type type)
491532 . Concat ( GetArrayRanks ( type . GetElementType ( ) ) ) ;
492533
493534 protected static TSyntax AddNewLine < TSyntax > ( TSyntax expression )
494- where TSyntax : SyntaxNode
495- => expression . FullSpan . Length > 120
535+ where TSyntax : SyntaxNode => expression . FullSpan . Length > 120
496536 ? expression . WithLeadingTrivia ( CarriageReturnLineFeed )
497537 . WithTrailingTrivia ( CarriageReturnLineFeed )
498538 : expression ;
0 commit comments