Пример #1
0
        private static MemberDeclarationSyntax GenerateConstructor(WellKnownTypes wellKnownTypes, string className, List <FieldInfoMember> fields)
        {
            var body = new List <StatementSyntax>();

            // Expressions for specifying binding flags.
            var bindingFlags = SymbolSyntaxExtensions.GetBindingFlagsParenthesizedExpressionSyntax(
                SyntaxKind.BitwiseOrExpression,
                BindingFlags.Instance,
                BindingFlags.NonPublic,
                BindingFlags.Public);

            var fieldUtils = IdentifierName("fieldUtils");

            foreach (var field in fields)
            {
                // Get the field
                var fieldInfoField = IdentifierName(field.InfoFieldName);
                var fieldInfo      =
                    InvocationExpression(TypeOfExpression(field.Field.ContainingType.ToTypeSyntax()).Member("GetField"))
                    .AddArgumentListArguments(
                        Argument(field.Field.Name.ToLiteralExpression()),
                        Argument(bindingFlags));
                var fieldInfoVariable =
                    VariableDeclarator(field.InfoFieldName).WithInitializer(EqualsValueClause(fieldInfo));

                if (!field.IsGettableProperty || !field.IsSettableProperty)
                {
                    body.Add(LocalDeclarationStatement(
                                 VariableDeclaration(wellKnownTypes.FieldInfo.ToTypeSyntax()).AddVariables(fieldInfoVariable)));
                }

                // Set the getter/setter of the field
                if (!field.IsGettableProperty)
                {
                    var getterType = wellKnownTypes.Func_2.Construct(field.Field.ContainingType, field.SafeType).ToTypeSyntax();

                    var getterInvoke = CastExpression(
                        getterType,
                        InvocationExpression(fieldUtils.Member("GetGetter")).AddArgumentListArguments(Argument(fieldInfoField)));

                    body.Add(ExpressionStatement(
                                 AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(field.GetterFieldName), getterInvoke)));
                }

                if (!field.IsSettableProperty)
                {
                    if (field.Field.ContainingType != null && field.Field.ContainingType.IsValueType)
                    {
                        var setterType = wellKnownTypes.ValueTypeSetter_2.Construct(field.Field.ContainingType, field.SafeType).ToTypeSyntax();

                        var getValueSetterInvoke = CastExpression(
                            setterType,
                            InvocationExpression(fieldUtils.Member("GetValueSetter"))
                            .AddArgumentListArguments(Argument(fieldInfoField)));

                        body.Add(ExpressionStatement(
                                     AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(field.SetterFieldName), getValueSetterInvoke)));
                    }
                    else
                    {
                        var setterType = wellKnownTypes.Action_2.Construct(field.Field.ContainingType, field.SafeType).ToTypeSyntax();

                        var getReferenceSetterInvoke = CastExpression(
                            setterType,
                            InvocationExpression(fieldUtils.Member("GetReferenceSetter"))
                            .AddArgumentListArguments(Argument(fieldInfoField)));

                        body.Add(ExpressionStatement(
                                     AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(field.SetterFieldName), getReferenceSetterInvoke)));
                    }
                }
            }

            return
                (ConstructorDeclaration(className)
                 .AddModifiers(Token(SyntaxKind.PublicKeyword))
                 .AddParameterListParameters(
                     Parameter(fieldUtils.Identifier).WithType(wellKnownTypes.IFieldUtils.ToTypeSyntax()))
                 .AddBodyStatements(body.ToArray()));
        }
Пример #2
0
        private static ConstructorDeclarationSyntax GenerateConstructor(string simpleClassName, List <FieldDescription> fieldDescriptions)
        {
            var injected   = fieldDescriptions.Where(f => f.IsInjected).ToList();
            var parameters = injected.Select(f => Parameter(f.FieldName.ToIdentifier()).WithType(f.FieldType));

            var fieldAccessorUtility = AliasQualifiedName("global", IdentifierName("Hagar")).Member("Utilities").Member("FieldAccessor");

            IEnumerable <StatementSyntax> GetStatements()
            {
                foreach (var field in fieldDescriptions)
                {
                    switch (field)
                    {
                    case GetterFieldDescription getter:
                        yield return(InitializeGetterField(getter));

                        break;

                    case SetterFieldDescription setter:
                        yield return(InitializeSetterField(setter));

                        break;

                    case FieldDescription _ when field.IsInjected:
                        yield return(ExpressionStatement(
                                         AssignmentExpression(
                                             SyntaxKind.SimpleAssignmentExpression,
                                             ThisExpression().Member(field.FieldName.ToIdentifierName()),
                                             Unwrapped(field.FieldName.ToIdentifierName()))));

                        break;
                    }
                }
            }

            StatementSyntax InitializeGetterField(GetterFieldDescription getter)
            {
                var fieldInfo      = GetFieldInfo(getter.Member.Field.ContainingType, getter.Member.Field.Name);
                var accessorInvoke = CastExpression(
                    getter.FieldType,
                    InvocationExpression(fieldAccessorUtility.Member("GetGetter")).AddArgumentListArguments(Argument(fieldInfo)));

                return(ExpressionStatement(
                           AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(getter.FieldName), accessorInvoke)));
            }

            StatementSyntax InitializeSetterField(SetterFieldDescription setter)
            {
                var field          = setter.Member.Field;
                var fieldInfo      = GetFieldInfo(field.ContainingType, field.Name);
                var accessorMethod = setter.IsContainedByValueType ? "GetValueSetter" : "GetReferenceSetter";
                var accessorInvoke = CastExpression(
                    setter.FieldType,
                    InvocationExpression(fieldAccessorUtility.Member(accessorMethod))
                    .AddArgumentListArguments(Argument(fieldInfo)));

                return(ExpressionStatement(
                           AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(setter.FieldName), accessorInvoke)));
            }

            InvocationExpressionSyntax GetFieldInfo(INamedTypeSymbol containingType, string fieldName)
            {
                var bindingFlags = SymbolSyntaxExtensions.GetBindingFlagsParenthesizedExpressionSyntax(
                    SyntaxKind.BitwiseOrExpression,
                    BindingFlags.Instance,
                    BindingFlags.NonPublic,
                    BindingFlags.Public);

                return(InvocationExpression(TypeOfExpression(containingType.ToTypeSyntax()).Member("GetField"))
                       .AddArgumentListArguments(
                           Argument(fieldName.GetLiteralExpression()),
                           Argument(bindingFlags)));
            }

            return(ConstructorDeclaration(simpleClassName)
                   .AddModifiers(Token(SyntaxKind.PublicKeyword))
                   .AddParameterListParameters(parameters.ToArray())
                   .AddBodyStatements(GetStatements().ToArray()));

            ExpressionSyntax Unwrapped(ExpressionSyntax expr)
            {
                return(InvocationExpression(
                           MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("HagarGeneratedCodeHelper"), IdentifierName("UnwrapService")),
                           ArgumentList(SeparatedList(new[] { Argument(ThisExpression()), Argument(expr) }))));
            }
        }