예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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());
        }
예제 #3
0
        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()));
        }