/// <summary> /// Returns syntax for initializing a new instance of the provided type. /// </summary> /// <param name="type">The type.</param> /// <returns>Syntax for initializing a new instance of the provided type.</returns> private static ExpressionSyntax GetObjectCreationExpressionSyntax(Type type) { ExpressionSyntax result; var typeInfo = type.GetTypeInfo(); if (typeInfo.IsValueType) { // Use the default value. result = SF.DefaultExpression(typeInfo.GetTypeSyntax()); } else if (type.GetConstructor(Type.EmptyTypes) != null) { // Use the default constructor. result = SF.ObjectCreationExpression(typeInfo.GetTypeSyntax()).AddArgumentListArguments(); } else { // Create an unformatted object. #if DNXCORE50 var bindingFlags = SyntaxFactoryExtensions.GetBindingFlagsParenthesizedExpressionSyntax( SyntaxKind.BitwiseOrExpression, BindingFlags.Instance, BindingFlags.NonPublic, BindingFlags.Public); var nullLiteralExpressionArgument = SF.Argument(SF.LiteralExpression(SyntaxKind.NullLiteralExpression)); var typeArg = SF.Argument(SF.TypeOfExpression(typeInfo.GetTypeSyntax())); var bindingFlagsArg = SF.Argument(bindingFlags); var binderArg = nullLiteralExpressionArgument; ArgumentSyntax ctorArgumentsArg; var cons = typeInfo.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) .OrderBy(p => p.GetParameters().Count()).FirstOrDefault(); var consParameters = cons != null?cons.GetParameters().Select(p => p.ParameterType).ToArray() : null; if (consParameters != null && consParameters.Length > 0) { var separatedSyntaxList = new SeparatedSyntaxList <ExpressionSyntax>(); separatedSyntaxList = consParameters .Aggregate(separatedSyntaxList, (current, t) => current.Add(SF.DefaultExpression(t.GetTypeInfo().GetTypeSyntax()))); ctorArgumentsArg = SF.Argument(separatedSyntaxList.GetArrayCreationWithInitializerSyntax( SF.PredefinedType(SF.Token(SyntaxKind.ObjectKeyword)))); } else { ctorArgumentsArg = nullLiteralExpressionArgument; } var cultureInfoArg = SF.Argument( SF.IdentifierName("System").Member("Globalization").Member("CultureInfo").Member("InvariantCulture")); var createInstanceArguments = new [] { typeArg, bindingFlagsArg, binderArg, ctorArgumentsArg, cultureInfoArg }; Expression <Func <object> > getUninitializedObject = () => Activator.CreateInstance( default(Type), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, null, System.Globalization.CultureInfo.InvariantCulture); result = SF.CastExpression( type.GetTypeSyntax(), getUninitializedObject.Invoke() .AddArgumentListArguments(createInstanceArguments)); #else Expression <Func <object> > getUninitializedObject = () => FormatterServices.GetUninitializedObject(default(Type)); result = SF.CastExpression( type.GetTypeSyntax(), getUninitializedObject.Invoke() .AddArgumentListArguments( SF.Argument(SF.TypeOfExpression(typeInfo.GetTypeSyntax())))); #endif } return(result); }
/// <summary> /// Returns syntax for the static fields of the serializer class. /// </summary> /// <param name="fields">The fields.</param> /// <returns>Syntax for the static fields of the serializer class.</returns> private static MemberDeclarationSyntax[] GenerateStaticFields(List <FieldInfoMember> fields) { var result = new List <MemberDeclarationSyntax>(); // ReSharper disable once ReturnValueOfPureMethodIsNotUsed Expression <Action <TypeInfo> > getField = _ => _.GetField(string.Empty, BindingFlags.Default); Expression <Action <Type> > getTypeInfo = _ => _.GetTypeInfo(); Expression <Action> getGetter = () => SerializationManager.GetGetter(default(FieldInfo)); Expression <Action> getReferenceSetter = () => SerializationManager.GetReferenceSetter(default(FieldInfo)); Expression <Action> getValueSetter = () => SerializationManager.GetValueSetter(default(FieldInfo)); // Expressions for specifying binding flags. var bindingFlags = SyntaxFactoryExtensions.GetBindingFlagsParenthesizedExpressionSyntax( SyntaxKind.BitwiseOrExpression, BindingFlags.Instance, BindingFlags.NonPublic, BindingFlags.Public); // Add each field and initialize it. foreach (var field in fields) { var fieldInfo = getField.Invoke(getTypeInfo.Invoke(SF.TypeOfExpression(field.FieldInfo.DeclaringType.GetTypeSyntax()))) .AddArgumentListArguments( SF.Argument(field.FieldInfo.Name.GetLiteralExpression()), SF.Argument(bindingFlags)); var fieldInfoVariable = SF.VariableDeclarator(field.InfoFieldName).WithInitializer(SF.EqualsValueClause(fieldInfo)); var fieldInfoField = SF.IdentifierName(field.InfoFieldName); if (!field.IsGettableProperty || !field.IsSettableProperty) { result.Add( SF.FieldDeclaration( SF.VariableDeclaration(typeof(FieldInfo).GetTypeSyntax()).AddVariables(fieldInfoVariable)) .AddModifiers( SF.Token(SyntaxKind.PrivateKeyword), SF.Token(SyntaxKind.StaticKeyword), SF.Token(SyntaxKind.ReadOnlyKeyword))); } // Declare the getter for this field. if (!field.IsGettableProperty) { var getterType = typeof(Func <,>).MakeGenericType(field.FieldInfo.DeclaringType, field.FieldInfo.FieldType) .GetTypeSyntax(); var fieldGetterVariable = SF.VariableDeclarator(field.GetterFieldName) .WithInitializer( SF.EqualsValueClause( SF.CastExpression( getterType, getGetter.Invoke().AddArgumentListArguments(SF.Argument(fieldInfoField))))); result.Add( SF.FieldDeclaration(SF.VariableDeclaration(getterType).AddVariables(fieldGetterVariable)) .AddModifiers( SF.Token(SyntaxKind.PrivateKeyword), SF.Token(SyntaxKind.StaticKeyword), SF.Token(SyntaxKind.ReadOnlyKeyword))); } if (!field.IsSettableProperty) { if (field.FieldInfo.DeclaringType != null && field.FieldInfo.DeclaringType.IsValueType) { var setterType = typeof(SerializationManager.ValueTypeSetter <,>).MakeGenericType( field.FieldInfo.DeclaringType, field.FieldInfo.FieldType).GetTypeSyntax(); var fieldSetterVariable = SF.VariableDeclarator(field.SetterFieldName) .WithInitializer( SF.EqualsValueClause( SF.CastExpression( setterType, getValueSetter.Invoke() .AddArgumentListArguments(SF.Argument(fieldInfoField))))); result.Add( SF.FieldDeclaration(SF.VariableDeclaration(setterType).AddVariables(fieldSetterVariable)) .AddModifiers( SF.Token(SyntaxKind.PrivateKeyword), SF.Token(SyntaxKind.StaticKeyword), SF.Token(SyntaxKind.ReadOnlyKeyword))); } else { var setterType = typeof(Action <,>).MakeGenericType(field.FieldInfo.DeclaringType, field.FieldInfo.FieldType) .GetTypeSyntax(); var fieldSetterVariable = SF.VariableDeclarator(field.SetterFieldName) .WithInitializer( SF.EqualsValueClause( SF.CastExpression( setterType, getReferenceSetter.Invoke() .AddArgumentListArguments(SF.Argument(fieldInfoField))))); result.Add( SF.FieldDeclaration(SF.VariableDeclaration(setterType).AddVariables(fieldSetterVariable)) .AddModifiers( SF.Token(SyntaxKind.PrivateKeyword), SF.Token(SyntaxKind.StaticKeyword), SF.Token(SyntaxKind.ReadOnlyKeyword))); } } } return(result.ToArray()); }
private static MemberDeclarationSyntax GenerateConstructor(string className, List <FieldInfoMember> fields) { var body = new List <StatementSyntax>(); Expression <Action <TypeInfo> > getField = _ => _.GetField(string.Empty, BindingFlags.Default); Expression <Action <Type> > getTypeInfo = _ => _.GetTypeInfo(); Expression <Action <IFieldUtils> > getGetter = _ => _.GetGetter(default(FieldInfo)); Expression <Action <IFieldUtils> > getReferenceSetter = _ => _.GetReferenceSetter(default(FieldInfo)); Expression <Action <IFieldUtils> > getValueSetter = _ => _.GetValueSetter(default(FieldInfo)); // Expressions for specifying binding flags. var bindingFlags = SyntaxFactoryExtensions.GetBindingFlagsParenthesizedExpressionSyntax( SyntaxKind.BitwiseOrExpression, BindingFlags.Instance, BindingFlags.NonPublic, BindingFlags.Public); var fieldUtils = SF.IdentifierName("fieldUtils"); foreach (var field in fields) { // Get the field var fieldInfoField = SF.IdentifierName(field.InfoFieldName); var fieldInfo = getField.Invoke(getTypeInfo.Invoke(SF.TypeOfExpression(field.FieldInfo.DeclaringType.GetTypeSyntax()))) .AddArgumentListArguments( SF.Argument(field.FieldInfo.Name.GetLiteralExpression()), SF.Argument(bindingFlags)); var fieldInfoVariable = SF.VariableDeclarator(field.InfoFieldName).WithInitializer(SF.EqualsValueClause(fieldInfo)); if (!field.IsGettableProperty || !field.IsSettableProperty) { body.Add(SF.LocalDeclarationStatement( SF.VariableDeclaration(typeof(FieldInfo).GetTypeSyntax()).AddVariables(fieldInfoVariable))); } // Set the getter/setter of the field if (!field.IsGettableProperty) { var getterType = typeof(Func <,>).MakeGenericType(field.FieldInfo.DeclaringType, field.FieldInfo.FieldType) .GetTypeSyntax(); var getterInvoke = SF.CastExpression( getterType, getGetter.Invoke(fieldUtils).AddArgumentListArguments(SF.Argument(fieldInfoField))); body.Add(SF.ExpressionStatement( SF.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SF.IdentifierName(field.GetterFieldName), getterInvoke))); } if (!field.IsSettableProperty) { if (field.FieldInfo.DeclaringType != null && field.FieldInfo.DeclaringType.GetTypeInfo().IsValueType) { var setterType = typeof(ValueTypeSetter <,>).MakeGenericType( field.FieldInfo.DeclaringType, field.FieldInfo.FieldType).GetTypeSyntax(); var getValueSetterInvoke = SF.CastExpression( setterType, getValueSetter.Invoke(fieldUtils) .AddArgumentListArguments(SF.Argument(fieldInfoField))); body.Add(SF.ExpressionStatement( SF.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SF.IdentifierName(field.SetterFieldName), getValueSetterInvoke))); } else { var setterType = typeof(Action <,>).MakeGenericType(field.FieldInfo.DeclaringType, field.FieldInfo.FieldType) .GetTypeSyntax(); var getReferenceSetterInvoke = SF.CastExpression( setterType, getReferenceSetter.Invoke(fieldUtils) .AddArgumentListArguments(SF.Argument(fieldInfoField))); body.Add(SF.ExpressionStatement( SF.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SF.IdentifierName(field.SetterFieldName), getReferenceSetterInvoke))); } } } return (SF.ConstructorDeclaration(className) .AddModifiers(SF.Token(SyntaxKind.PublicKeyword)) .AddParameterListParameters( SF.Parameter(fieldUtils.Identifier).WithType(typeof(IFieldUtils).GetTypeSyntax())) .AddBodyStatements(body.ToArray())); }