コード例 #1
0
        private static MemberDeclarationSyntax GenerateConstructor(string className, List <FieldInfoMember> fields)
        {
            var body = new List <StatementSyntax>();

            Expression <Action <Type> >        getField           = _ => _.GetField(string.Empty, BindingFlags.Default);
            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(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.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()));
        }
コード例 #2
0
        /// <summary>
        /// Generates syntax to invoke a method on a grain.
        /// </summary>
        /// <param name="grainType">
        /// The grain type.
        /// </param>
        /// <param name="grain">
        /// The grain instance expression.
        /// </param>
        /// <param name="method">
        /// The method.
        /// </param>
        /// <param name="arguments">
        /// The arguments expression.
        /// </param>
        /// <returns>
        /// Syntax to invoke a method on a grain.
        /// </returns>
        private static StatementSyntax[] GenerateInvokeForMethod(
            Type grainType,
            IdentifierNameSyntax grain,
            MethodInfo method,
            ExpressionSyntax arguments)
        {
            var castGrain = SF.ParenthesizedExpression(SF.CastExpression(grainType.GetTypeSyntax(), grain));

            // Construct expressions to retrieve each of the method's parameters.
            var parameters       = new List <ExpressionSyntax>();
            var methodParameters = method.GetParameters().ToList();

            for (var i = 0; i < methodParameters.Count; i++)
            {
                var parameter     = methodParameters[i];
                var parameterType = parameter.ParameterType.GetTypeSyntax();
                var indexArg      = SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(i)));
                var arg           = SF.CastExpression(
                    parameterType,
                    SF.ElementAccessExpression(arguments).AddArgumentListArguments(indexArg));
                parameters.Add(arg);
            }

            // If the method is a generic method definition, use the generic method invoker field to invoke the method.
            if (method.IsGenericMethodDefinition)
            {
                var invokerFieldName = GetGenericMethodInvokerFieldName(method);
                var invokerCall      = SF.InvocationExpression(
                    SF.IdentifierName(invokerFieldName)
                    .Member((GenericMethodInvoker invoker) => invoker.Invoke(null, null)))
                                       .AddArgumentListArguments(SF.Argument(grain), SF.Argument(arguments));
                return(new StatementSyntax[] { SF.ReturnStatement(SF.AwaitExpression(invokerCall)) });
            }

            // Invoke the method.
            var grainMethodCall =
                SF.InvocationExpression(castGrain.Member(method.Name))
                .AddArgumentListArguments(parameters.Select(SF.Argument).ToArray());

            // For void methods, invoke the method and return null.
            if (method.ReturnType == typeof(void))
            {
                return(new StatementSyntax[]
                {
                    SF.ExpressionStatement(grainMethodCall),
                    SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression))
                });
            }

            // For methods which return non-generic Task, await the method and return null.
            if (method.ReturnType == typeof(Task))
            {
                return(new StatementSyntax[]
                {
                    SF.ExpressionStatement(SF.AwaitExpression(grainMethodCall)),
                    SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression))
                });
            }

            return(new StatementSyntax[]
            {
                SF.ReturnStatement(SF.AwaitExpression(grainMethodCall))
            });
        }
コード例 #3
0
        /// <summary>
        /// Generates invoker methods.
        /// </summary>
        /// <param name="grainType">The grain type.</param>
        /// <param name="onEncounteredType">
        /// The callback which is invoked when a type is encountered.
        /// </param>
        /// <returns>Invoker methods for the provided grain type.</returns>
        private static MemberDeclarationSyntax[] GenerateInvokeMethods(Type grainType, Action <Type> onEncounteredType)
        {
            var baseReference = SF.BaseExpression();
            var methods       = GrainInterfaceUtils.GetMethods(grainType);
            var members       = new List <MemberDeclarationSyntax>();

            foreach (var method in methods)
            {
                onEncounteredType(method.ReturnType);
                var methodId         = GrainInterfaceUtils.ComputeMethodId(method);
                var methodIdArgument =
                    SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId)));

                // Construct a new object array from all method arguments.
                var parameters = method.GetParameters();
                var body       = new List <StatementSyntax>();
                foreach (var parameter in parameters)
                {
                    onEncounteredType(parameter.ParameterType);
                    if (typeof(IGrainObserver).IsAssignableFrom(parameter.ParameterType))
                    {
                        body.Add(
                            SF.ExpressionStatement(
                                CheckGrainObserverParamInternalExpression.Invoke()
                                .AddArgumentListArguments(SF.Argument(parameter.Name.ToIdentifierName()))));
                    }
                }

                // Get the parameters argument value.
                ExpressionSyntax args;
                if (parameters.Length == 0)
                {
                    args = SF.LiteralExpression(SyntaxKind.NullLiteralExpression);
                }
                else
                {
                    args =
                        SF.ArrayCreationExpression(typeof(object).GetArrayTypeSyntax())
                        .WithInitializer(
                            SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression)
                            .AddExpressions(parameters.Select(GetParameterForInvocation).ToArray()));
                }

                var options = GetInvokeOptions(method);

                // Construct the invocation call.
                if (method.ReturnType == typeof(void))
                {
                    var invocation = SF.InvocationExpression(baseReference.Member("InvokeOneWayMethod"))
                                     .AddArgumentListArguments(methodIdArgument)
                                     .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ExpressionStatement(invocation));
                }
                else
                {
                    var returnType = method.ReturnType == typeof(Task)
                                         ? typeof(object)
                                         : method.ReturnType.GenericTypeArguments[0];
                    var invocation =
                        SF.InvocationExpression(baseReference.Member("InvokeMethodAsync", returnType))
                        .AddArgumentListArguments(methodIdArgument)
                        .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ReturnStatement(invocation));
                }

                members.Add(method.GetDeclarationSyntax().AddBodyStatements(body.ToArray()));
            }

            return(members.ToArray());
        }
コード例 #4
0
        public ExpressionSyntax GetFullExpressionForVbObjectComparison(VBSyntax.BinaryExpressionSyntax node, ExpressionSyntax lhs, ExpressionSyntax rhs)
        {
            _extraUsingDirectives.Add("Microsoft.VisualBasic.CompilerServices");
            var optionCompareTextCaseInsensitive = SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(OptionCompareTextCaseInsensitive ? SyntaxKind.TrueKeyword : SyntaxKind.FalseLiteralExpression));
            var compareObject = SyntaxFactory.InvocationExpression(ValidSyntaxFactory.MemberAccess(nameof(Operators), nameof(Operators.ConditionalCompareObjectEqual)),
                                                                   SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[]
                                                                                                                          { SyntaxFactory.Argument(lhs), SyntaxFactory.Argument(rhs), optionCompareTextCaseInsensitive })));

            return(NegateIfNeeded(node, compareObject));
        }
コード例 #5
0
        /// <summary>
        /// Generates syntax for an invoke method.
        /// </summary>
        /// <param name="grainType">
        /// The grain type.
        /// </param>
        /// <param name="invokeMethod">
        /// The invoke method to generate.
        /// </param>
        /// <returns>
        /// Syntax for an invoke method.
        /// </returns>
        private static MethodDeclarationSyntax GenerateInvokeMethod(Type grainType, MethodInfo invokeMethod)
        {
            var parameters = invokeMethod.GetParameters();

            var grainArgument   = parameters[0].Name.ToIdentifierName();
            var requestArgument = parameters[1].Name.ToIdentifierName();

            // Store the relevant values from the request in local variables.
            var interfaceIdDeclaration =
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(typeof(int).GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("interfaceId")
                        .WithInitializer(SF.EqualsValueClause(requestArgument.Member((InvokeMethodRequest _) => _.InterfaceId)))));
            var interfaceIdVariable = SF.IdentifierName("interfaceId");

            var methodIdDeclaration =
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(typeof(int).GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("methodId")
                        .WithInitializer(SF.EqualsValueClause(requestArgument.Member((InvokeMethodRequest _) => _.MethodId)))));
            var methodIdVariable = SF.IdentifierName("methodId");

            var argumentsDeclaration =
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(typeof(object[]).GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("arguments")
                        .WithInitializer(SF.EqualsValueClause(requestArgument.Member((InvokeMethodRequest _) => _.Arguments)))));
            var argumentsVariable = SF.IdentifierName("arguments");

            var methodDeclaration = invokeMethod.GetDeclarationSyntax()
                                    .AddModifiers(SF.Token(SyntaxKind.AsyncKeyword))
                                    .AddBodyStatements(interfaceIdDeclaration, methodIdDeclaration, argumentsDeclaration);

            var interfaceCases = CodeGeneratorCommon.GenerateGrainInterfaceAndMethodSwitch(
                grainType,
                methodIdVariable,
                methodType => GenerateInvokeForMethod(grainType, grainArgument, methodType, argumentsVariable));

            // Generate the default case, which will throw a NotImplementedException.
            var errorMessage = SF.BinaryExpression(
                SyntaxKind.AddExpression,
                "interfaceId=".GetLiteralExpression(),
                interfaceIdVariable);
            var throwStatement =
                SF.ThrowStatement(
                    SF.ObjectCreationExpression(typeof(NotImplementedException).GetTypeSyntax())
                    .AddArgumentListArguments(SF.Argument(errorMessage)));
            var defaultCase       = SF.SwitchSection().AddLabels(SF.DefaultSwitchLabel()).AddStatements(throwStatement);
            var interfaceIdSwitch =
                SF.SwitchStatement(interfaceIdVariable).AddSections(interfaceCases.ToArray()).AddSections(defaultCase);

            // If the provided grain is null, throw an argument exception.
            var argumentNullException =
                SF.ObjectCreationExpression(typeof(ArgumentNullException).GetTypeSyntax())
                .AddArgumentListArguments(SF.Argument(parameters[0].Name.GetLiteralExpression()));
            var grainArgumentCheck =
                SF.IfStatement(
                    SF.BinaryExpression(
                        SyntaxKind.EqualsExpression,
                        grainArgument,
                        SF.LiteralExpression(SyntaxKind.NullLiteralExpression)),
                    SF.ThrowStatement(argumentNullException));

            return(methodDeclaration.AddBodyStatements(grainArgumentCheck, interfaceIdSwitch));
        }
コード例 #6
0
        /// <summary>
        /// Generates switch cases for the provided grain type.
        /// </summary>
        /// <param name="grainType">
        /// The grain type.
        /// </param>
        /// <param name="methodIdArgument">
        /// The method id argument, which is used to select the correct switch label.
        /// </param>
        /// <param name="generateMethodHandler">
        /// The function used to generate switch block statements for each method.
        /// </param>
        /// <returns>
        /// The switch cases for the provided grain type.
        /// </returns>
        public static SwitchSectionSyntax[] GenerateGrainInterfaceAndMethodSwitch(
            Type grainType,
            ExpressionSyntax methodIdArgument,
            Func <MethodInfo, StatementSyntax[]> generateMethodHandler)
        {
            var interfaces = GrainInterfaceUtils.GetRemoteInterfaces(grainType);

            interfaces[GrainInterfaceUtils.GetGrainInterfaceId(grainType)] = grainType;

            // Switch on interface id.
            var interfaceCases = new List <SwitchSectionSyntax>();

            foreach (var @interface in interfaces)
            {
                var interfaceType = @interface.Value;
                var interfaceId   = @interface.Key;
                var methods       = GrainInterfaceUtils.GetMethods(interfaceType);

                var methodCases = new List <SwitchSectionSyntax>();

                // Switch on method id.
                foreach (var method in methods)
                {
                    // Generate switch case.
                    var methodId   = GrainInterfaceUtils.ComputeMethodId(method);
                    var methodType = method;

                    // Generate the switch label for this interface id.
                    var methodIdSwitchLabel =
                        SF.CaseSwitchLabel(
                            SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId)));

                    // Generate the switch body.
                    var methodInvokeStatement = generateMethodHandler(methodType);

                    methodCases.Add(
                        SF.SwitchSection().AddLabels(methodIdSwitchLabel).AddStatements(methodInvokeStatement));
                }

                // Generate the switch label for this interface id.
                var interfaceIdSwitchLabel =
                    SF.CaseSwitchLabel(
                        SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(interfaceId)));

                // Generate the default case, which will throw a NotImplementedException.
                var errorMessage = SF.BinaryExpression(
                    SyntaxKind.AddExpression,
                    "interfaceId=".GetLiteralExpression(),
                    SF.BinaryExpression(
                        SyntaxKind.AddExpression,
                        SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(interfaceId)),
                        SF.BinaryExpression(
                            SyntaxKind.AddExpression,
                            ",methodId=".GetLiteralExpression(),
                            methodIdArgument)));
                var throwStatement =
                    SF.ThrowStatement(
                        SF.ObjectCreationExpression(typeof(NotImplementedException).GetTypeSyntax())
                        .AddArgumentListArguments(SF.Argument(errorMessage)));
                var defaultCase = SF.SwitchSection().AddLabels(SF.DefaultSwitchLabel()).AddStatements(throwStatement);

                // Generate switch statements for the methods in this interface.
                var methodSwitchStatements =
                    SF.SwitchStatement(methodIdArgument).AddSections(methodCases.ToArray()).AddSections(defaultCase);

                // Generate the switch section for this interface.
                interfaceCases.Add(
                    SF.SwitchSection().AddLabels(interfaceIdSwitchLabel).AddStatements(methodSwitchStatements));
            }

            return(interfaceCases.ToArray());
        }
コード例 #7
0
        private static MemberDeclarationSyntax GenerateDeepCopierMethod(Type type, List <FieldInfoMember> fields)
        {
            var originalVariable    = SF.IdentifierName("original");
            var inputVariable       = SF.IdentifierName("input");
            var resultVariable      = SF.IdentifierName("result");
            var boxedResultVariable = resultVariable;

            var body = new List <StatementSyntax>();

            if (type.GetCustomAttribute <ImmutableAttribute>() != null)
            {
                // Immutable types do not require copying.
                body.Add(SF.ReturnStatement(originalVariable));
            }
            else
            {
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("input")
                            .WithInitializer(
                                SF.EqualsValueClause(
                                    SF.ParenthesizedExpression(
                                        SF.CastExpression(type.GetTypeSyntax(), originalVariable)))))));
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("result")
                            .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type))))));

                if (type.IsValueType)
                {
                    // For value types, we need to box the result for reflection-based setters to work.
                    body.Add(SF.LocalDeclarationStatement(
                                 SF.VariableDeclaration(typeof(object).GetTypeSyntax())
                                 .AddVariables(
                                     SF.VariableDeclarator("boxedResult").WithInitializer(SF.EqualsValueClause(resultVariable)))));
                    boxedResultVariable = SF.IdentifierName("boxedResult");
                }

                // Record this serialization.
                Expression <Action> recordObject =
                    () => SerializationContext.Current.RecordObject(default(object), default(object));
                var currentSerializationContext =
                    SyntaxFactory.AliasQualifiedName(
                        SF.IdentifierName(SF.Token(SyntaxKind.GlobalKeyword)),
                        SF.IdentifierName("Orleans"))
                    .Qualify("Serialization")
                    .Qualify("SerializationContext")
                    .Qualify("Current");
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(currentSerializationContext)
                        .AddArgumentListArguments(SF.Argument(originalVariable), SF.Argument(boxedResultVariable))));

                // Copy all members from the input to the result.
                foreach (var field in fields)
                {
                    body.Add(SF.ExpressionStatement(field.GetSetter(boxedResultVariable, field.GetGetter(inputVariable))));
                }

                body.Add(SF.ReturnStatement(boxedResultVariable));
            }

            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "DeepCopier")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("original")).WithType(typeof(object).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList().AddAttributes(SF.Attribute(typeof(CopierMethodAttribute).GetNameSyntax()))));
        }
コード例 #8
0
ファイル: SyntaxUtil.cs プロジェクト: Svengali/SharpLibs
 public static InvocationExpressionSyntax OptionalGetValueOrDefault(ExpressionSyntax optionalOfTExpression, ExpressionSyntax defaultValue)
 {
     return(SF.InvocationExpression(
                SF.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, optionalOfTExpression, SF.IdentifierName(nameof(Option <int> .ValueOr))),
                SF.ArgumentList(SF.SingletonSeparatedList(SF.Argument(defaultValue)))));
 }
コード例 #9
0
        /// <summary>
        /// Generates syntax to invoke a method on a grain.
        /// </summary>
        /// <param name="grainType">
        /// The grain type.
        /// </param>
        /// <param name="grain">
        /// The grain instance expression.
        /// </param>
        /// <param name="method">
        /// The method.
        /// </param>
        /// <param name="arguments">
        /// The arguments expression.
        /// </param>
        /// <returns>
        /// Syntax to invoke a method on a grain.
        /// </returns>
        private static StatementSyntax[] GenerateInvokeForMethod(
            Type grainType,
            IdentifierNameSyntax grain,
            MethodInfo method,
            ExpressionSyntax arguments)
        {
            var castGrain = SF.ParenthesizedExpression(SF.CastExpression(grainType.GetTypeSyntax(), grain));

            // Construct expressions to retrieve each of the method's parameters.
            var parameters       = new List <ExpressionSyntax>();
            var methodParameters = method.GetParameters().ToList();

            for (var i = 0; i < methodParameters.Count; i++)
            {
                var parameter     = methodParameters[i];
                var parameterType = parameter.ParameterType.GetTypeSyntax();
                var indexArg      = SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(i)));
                var arg           = SF.CastExpression(
                    parameterType,
                    SF.ElementAccessExpression(arguments).AddArgumentListArguments(indexArg));
                parameters.Add(arg);
            }

            // If the method is a generic method definition, use the generic method invoker field to invoke the method.
            if (method.IsGenericMethodDefinition)
            {
                var invokerFieldName = GetGenericMethodInvokerFieldName(method);
                var invokerCall      = SF.InvocationExpression(
                    SF.IdentifierName(invokerFieldName)
                    .Member((GenericMethodInvoker invoker) => invoker.Invoke(null, null)))
                                       .AddArgumentListArguments(SF.Argument(grain), SF.Argument(arguments));
                return(new StatementSyntax[] { SF.ReturnStatement(SF.AwaitExpression(invokerCall)) });
            }

            // Invoke the method.
            var grainMethodCall =
                SF.InvocationExpression(castGrain.Member(method.Name))
                .AddArgumentListArguments(parameters.Select(SF.Argument).ToArray());

            // For void methods, invoke the method and return null.
            if (method.ReturnType == typeof(void))
            {
                return(new StatementSyntax[]
                {
                    SF.ExpressionStatement(grainMethodCall),
                    SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression))
                });
            }

            // For methods which return non-generic Task, await the method and return null.
            if (method.ReturnType == typeof(Task))
            {
                return(new StatementSyntax[]
                {
                    SF.ExpressionStatement(SF.AwaitExpression(grainMethodCall)),
                    SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression))
                });
            }

            if (method.ReturnType.IsGenericType &&
                method.ReturnType.GetGenericTypeDefinition().FullName == "System.Threading.Tasks.ValueTask`1")
            {
                var convertToTaskResult = SF.IdentifierName("AsTask");

                // Converting ValueTask method result to Task since "Invoke" method should return Task.
                // Temporary solution. Need to change when Orleans will be using ValueTask instead of Task.
                grainMethodCall =
                    SF.InvocationExpression(
                        SF.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                  SF.ExpressionStatement(grainMethodCall).Expression, convertToTaskResult));
            }


            return(new StatementSyntax[]
            {
                SF.ReturnStatement(SF.AwaitExpression(grainMethodCall))
            });
        }
コード例 #10
0
        public ExpressionSyntax AddExplicitConvertTo(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, ITypeSymbol type)
        {
            var displayType = type.ToMinimalDisplayString(_semanticModel, vbNode.SpanStart);

            if (csNode is InvocationExpressionSyntax invoke &&
                invoke.Expression is MemberAccessExpressionSyntax expr &&
                expr.Expression is IdentifierNameSyntax name && name.Identifier.ValueText == "Conversions" &&
                expr.Name.Identifier.ValueText == $"To{displayType}")
            {
                return(csNode);
            }

            var method = typeof(Conversions).GetMethod($"To{displayType}");

            if (method == null)
            {
                throw new NotImplementedException($"Unimplemented conversion for {displayType}");
            }

            // Need to use Conversions rather than Convert to match what VB does, eg. True -> -1
            _extraUsingDirectives.Add("Microsoft.VisualBasic.CompilerServices");
            var memberAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                    SyntaxFactory.IdentifierName("Conversions"), SyntaxFactory.IdentifierName($"To{displayType}"));
            var arguments = SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(csNode)));

            return(SyntaxFactory.InvocationExpression(memberAccess, arguments));
        }
コード例 #11
0
        /// <summary>
        /// Generates invoker methods.
        /// </summary>
        /// <param name="grainType">The grain type.</param>
        /// <param name="onEncounteredType">
        /// The callback which is invoked when a type is encountered.
        /// </param>
        /// <returns>Invoker methods for the provided grain type.</returns>
        private static MemberDeclarationSyntax[] GenerateInvokeMethods(Type grainType, Action <Type> onEncounteredType)
        {
            var baseReference = SF.BaseExpression();
            var methods       = GrainInterfaceUtils.GetMethods(grainType);
            var members       = new List <MemberDeclarationSyntax>();

            foreach (var method in methods)
            {
                onEncounteredType(method.ReturnType);
                var methodId         = GrainInterfaceUtils.ComputeMethodId(method);
                var methodIdArgument =
                    SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId)));

                // Construct a new object array from all method arguments.
                var parameters = method.GetParameters();
                var body       = new List <StatementSyntax>();
                foreach (var parameter in parameters)
                {
                    onEncounteredType(parameter.ParameterType);
                    if (typeof(IGrainObserver).GetTypeInfo().IsAssignableFrom(parameter.ParameterType))
                    {
                        body.Add(
                            SF.ExpressionStatement(
                                CheckGrainObserverParamInternalExpression.Invoke()
                                .AddArgumentListArguments(SF.Argument(parameter.Name.ToIdentifierName()))));
                    }
                }

                // Get the parameters argument value.
                ExpressionSyntax args;
                if (method.IsGenericMethodDefinition)
                {
                    // Create an arguments array which includes the method's type parameters followed by the method's parameter list.
                    var allParameters = new List <ExpressionSyntax>();
                    foreach (var typeParameter in method.GetGenericArguments())
                    {
                        allParameters.Add(SF.TypeOfExpression(typeParameter.GetTypeSyntax()));
                    }

                    allParameters.AddRange(parameters.Select(GetParameterForInvocation));

                    args =
                        SF.ArrayCreationExpression(typeof(object).GetArrayTypeSyntax())
                        .WithInitializer(
                            SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression)
                            .AddExpressions(allParameters.ToArray()));
                }
                else if (parameters.Length == 0)
                {
                    args = SF.LiteralExpression(SyntaxKind.NullLiteralExpression);
                }
                else
                {
                    args =
                        SF.ArrayCreationExpression(typeof(object).GetArrayTypeSyntax())
                        .WithInitializer(
                            SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression)
                            .AddExpressions(parameters.Select(GetParameterForInvocation).ToArray()));
                }

                var options = GetInvokeOptions(method);

                // Construct the invocation call.
                var isOneWayTask = method.GetCustomAttribute <OneWayAttribute>() != null;
                if (method.ReturnType == typeof(void) || isOneWayTask)
                {
                    var invocation = SF.InvocationExpression(baseReference.Member("InvokeOneWayMethod"))
                                     .AddArgumentListArguments(methodIdArgument)
                                     .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ExpressionStatement(invocation));

                    if (isOneWayTask)
                    {
                        if (method.ReturnType != typeof(Task))
                        {
                            throw new CodeGenerationException(
                                      $"Method {grainType.GetParseableName()}.{method.Name} is marked with [{nameof(OneWayAttribute)}], " +
                                      $"but has a return type which is not assignable from {typeof(Task)}");
                        }

                        var done = typeof(Task).GetNameSyntax(true).Member((object _) => Task.CompletedTask);
                        body.Add(SF.ReturnStatement(done));
                    }
                }
                else
                {
                    var returnType = method.ReturnType == typeof(Task)
                                         ? typeof(object)
                                         : method.ReturnType.GenericTypeArguments[0];
                    var invocation =
                        SF.InvocationExpression(baseReference.Member("InvokeMethodAsync", returnType))
                        .AddArgumentListArguments(methodIdArgument)
                        .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ReturnStatement(invocation));
                }

                members.Add(method.GetDeclarationSyntax().AddBodyStatements(body.ToArray()));
            }

            return(members.ToArray());
        }
コード例 #12
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          = () => FieldUtils.GetGetter(default(FieldInfo));
            Expression <Action>             getReferenceSetter = () => FieldUtils.GetReferenceSetter(default(FieldInfo));
            Expression <Action>             getValueSetter     = () => FieldUtils.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.GetTypeInfo().IsValueType)
                    {
                        var setterType =
                            typeof(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());
        }
コード例 #13
0
            public ExpressionSyntax GetSetter(ExpressionSyntax instance, ExpressionSyntax value, ExpressionSyntax boxedInstance = null)
            {
                Expression <Action> fieldSetter = () => this.FieldInfo.SetValue(default(object), default(object));

                // If the field is the backing field for an auto-property, try to use the property directly.
                var propertyName = Regex.Match(this.FieldInfo.Name, "^<([^>]+)>.*$");

                if (propertyName.Success && this.FieldInfo.DeclaringType != null)
                {
                    var name     = propertyName.Groups[1].Value;
                    var property = this.FieldInfo.DeclaringType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
                    if (property != null && property.GetSetMethod() != null)
                    {
                        return(SF.AssignmentExpression(
                                   SyntaxKind.SimpleAssignmentExpression,
                                   instance.Member(property.Name),
                                   value));
                    }
                }

                return(fieldSetter.Invoke(this.FieldInfoExpression)
                       .AddArgumentListArguments(SF.Argument(boxedInstance ?? instance), SF.Argument(value)));
            }
コード例 #14
0
            public ExpressionSyntax GetGetter(ExpressionSyntax instance, bool forceAvoidCopy = false)
            {
                Expression <Action> fieldGetter = () => this.FieldInfo.GetValue(default(object));
                var getFieldExpression          =
                    fieldGetter.Invoke(this.FieldInfoExpression).AddArgumentListArguments(SF.Argument(instance));

                // If the field is the backing field for an auto-property, try to use the property directly.
                var propertyName = Regex.Match(this.FieldInfo.Name, "^<([^>]+)>.*$");

                if (propertyName.Success && this.FieldInfo.DeclaringType != null)
                {
                    var name     = propertyName.Groups[1].Value;
                    var property = this.FieldInfo.DeclaringType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public);
                    if (property != null && property.GetGetMethod() != null)
                    {
                        return(instance.Member(property.Name));
                    }
                }

                if (forceAvoidCopy || this.FieldInfo.FieldType.IsOrleansShallowCopyable())
                {
                    // Shallow-copy the field.
                    return(getFieldExpression);
                }

                // Deep-copy the field.
                Expression <Action> deepCopyInner = () => SerializationManager.DeepCopyInner(default(object));

                return(SF.CastExpression(
                           this.FieldInfo.FieldType.GetTypeSyntax(),
                           deepCopyInner.Invoke().AddArgumentListArguments(SF.Argument(getFieldExpression))));
            }
コード例 #15
0
        /// <summary>
        /// Returns syntax for the deserializer method.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="fields">The fields.</param>
        /// <returns>Syntax for the deserializer method.</returns>
        private static MemberDeclarationSyntax GenerateDeserializerMethod(Type type, List <FieldInfoMember> fields)
        {
            Expression <Action <IDeserializationContext> > deserializeInner =
                ctx => ctx.DeserializeInner(default(Type));
            var contextParameter = SF.IdentifierName("context");

            var resultDeclaration =
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(type.GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("result")
                        .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type)))));
            var resultVariable = SF.IdentifierName("result");

            var body = new List <StatementSyntax> {
                resultDeclaration
            };

            // Value types cannot be referenced, only copied, so there is no need to box & record instances of value types.
            if (!type.IsValueType)
            {
                // Record the result for cyclic deserialization.
                Expression <Action <IDeserializationContext> > recordObject = ctx => ctx.RecordObject(default(object));
                var currentSerializationContext = contextParameter;
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(currentSerializationContext)
                        .AddArgumentListArguments(SF.Argument(resultVariable))));
            }

            // Deserialize all fields.
            foreach (var field in fields)
            {
                var deserialized =
                    deserializeInner.Invoke(contextParameter)
                    .AddArgumentListArguments(
                        SF.Argument(SF.TypeOfExpression(field.Type)));
                body.Add(
                    SF.ExpressionStatement(
                        field.GetSetter(
                            resultVariable,
                            SF.CastExpression(field.Type, deserialized))));
            }

            // If the type implements the internal IOnDeserialized lifecycle method, invoke it's method now.
            if (typeof(IOnDeserialized).IsAssignableFrom(type))
            {
                Expression <Action <IOnDeserialized> > onDeserializedMethod = _ => _.OnDeserialized(default(ISerializerContext));

                // C#: ((IOnDeserialized)result).OnDeserialized(context);
                var typedResult          = SF.ParenthesizedExpression(SF.CastExpression(typeof(IOnDeserialized).GetTypeSyntax(), resultVariable));
                var invokeOnDeserialized = onDeserializedMethod.Invoke(typedResult).AddArgumentListArguments(SF.Argument(contextParameter));
                body.Add(SF.ExpressionStatement(invokeOnDeserialized));
            }

            body.Add(SF.ReturnStatement(SF.CastExpression(type.GetTypeSyntax(), resultVariable)));
            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "Deserializer")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("expected")).WithType(typeof(Type).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("context")).WithType(typeof(IDeserializationContext).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList()
                     .AddAttributes(SF.Attribute(typeof(DeserializerMethodAttribute).GetNameSyntax()))));
        }
コード例 #16
0
        /// <summary>
        /// Generates syntax to invoke a method on a grain.
        /// </summary>
        /// <param name="grainType">
        /// The grain type.
        /// </param>
        /// <param name="grain">
        /// The grain instance expression.
        /// </param>
        /// <param name="method">
        /// The method.
        /// </param>
        /// <param name="arguments">
        /// The arguments expression.
        /// </param>
        /// <returns>
        /// Syntax to invoke a method on a grain.
        /// </returns>
        private static StatementSyntax[] GenerateInvokeForMethod(
            Type grainType,
            IdentifierNameSyntax grain,
            MethodInfo method,
            ExpressionSyntax arguments)
        {
            var castGrain = SF.ParenthesizedExpression(SF.CastExpression(grainType.GetTypeSyntax(), grain));

            // Construct expressions to retrieve each of the method's parameters.
            var parameters       = new List <ExpressionSyntax>();
            var methodParameters = method.GetParameters().ToList();

            for (var i = 0; i < methodParameters.Count; i++)
            {
                var parameter     = methodParameters[i];
                var parameterType = parameter.ParameterType.GetTypeSyntax();
                var indexArg      = SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(i)));
                var arg           = SF.CastExpression(
                    parameterType,
                    SF.ElementAccessExpression(arguments).AddArgumentListArguments(indexArg));
                parameters.Add(arg);
            }

            // If the method is a generic method definition, use the generic method invoker field to invoke the method.
            if (method.IsGenericMethodDefinition)
            {
                var invokerFieldName = GetGenericMethodInvokerFieldName(method);
                var invokerCall      = SF.InvocationExpression(
                    SF.IdentifierName(invokerFieldName)
                    .Member((GenericMethodInvoker invoker) => invoker.Invoke(null, null)))
                                       .AddArgumentListArguments(SF.Argument(grain), SF.Argument(arguments));
                return(new StatementSyntax[] { SF.ReturnStatement(invokerCall) });
            }

            // Invoke the method.
            var grainMethodCall =
                SF.InvocationExpression(castGrain.Member(method.Name))
                .AddArgumentListArguments(parameters.Select(SF.Argument).ToArray());

            // For void methods, invoke the method and return a completed task.
            if (method.ReturnType == typeof(void))
            {
                var completed = (Expression <Func <Task <object> > >)(() => TaskUtility.Completed());
                return(new StatementSyntax[]
                {
                    SF.ExpressionStatement(grainMethodCall),
                    SF.ReturnStatement(completed.Invoke())
                });
            }

            // For methods which return the expected type, Task<object>, simply return that.
            if (method.ReturnType == typeof(Task <object>))
            {
                return(new StatementSyntax[] { SF.ReturnStatement(grainMethodCall) });
            }

            // The invoke method expects a Task<object>, so we need to upcast the returned value.
            // For methods which do not return a value, the Box extension method returns a meaningless value.
            return(new StatementSyntax[]
            {
                SF.ReturnStatement(SF.InvocationExpression(grainMethodCall.Member((Task _) => _.Box())))
            });
        }
コード例 #17
0
        /// <summary>
        /// Returns syntax for the deep copier method.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="fields">The fields.</param>
        /// <returns>Syntax for the deep copier method.</returns>
        private static MemberDeclarationSyntax GenerateDeepCopierMethod(Type type, List <FieldInfoMember> fields)
        {
            var originalVariable = SF.IdentifierName("original");
            var inputVariable    = SF.IdentifierName("input");
            var resultVariable   = SF.IdentifierName("result");

            var body = new List <StatementSyntax>();

            if (type.GetCustomAttribute <ImmutableAttribute>() != null)
            {
                // Immutable types do not require copying.
                var typeName = type.GetParseableName(new TypeFormattingOptions(includeGlobal: false));
                var comment  = SF.Comment($"// No deep copy required since {typeName} is marked with the [Immutable] attribute.");
                body.Add(SF.ReturnStatement(originalVariable).WithLeadingTrivia(comment));
            }
            else
            {
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("input")
                            .WithInitializer(
                                SF.EqualsValueClause(
                                    SF.ParenthesizedExpression(
                                        SF.CastExpression(type.GetTypeSyntax(), originalVariable)))))));
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("result")
                            .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type))))));

                // Record this serialization.
                Expression <Action <ICopyContext> > recordObject =
                    ctx => ctx.RecordCopy(default(object), default(object));
                var context = SF.IdentifierName("context");
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(context)
                        .AddArgumentListArguments(SF.Argument(originalVariable), SF.Argument(resultVariable))));

                // Copy all members from the input to the result.
                foreach (var field in fields)
                {
                    body.Add(SF.ExpressionStatement(field.GetSetter(resultVariable, field.GetGetter(inputVariable, context))));
                }

                body.Add(SF.ReturnStatement(resultVariable));
            }

            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "DeepCopier")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("original")).WithType(typeof(object).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("context")).WithType(typeof(ICopyContext).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList().AddAttributes(SF.Attribute(typeof(CopierMethodAttribute).GetNameSyntax()))));
        }
コード例 #18
0
        public (ExpressionSyntax csLeft, ExpressionSyntax csRight) AdjustForVbStringComparison(VBSyntax.ExpressionSyntax vbLeft, ExpressionSyntax csLeft, TypeInfo lhsTypeInfo, VBSyntax.ExpressionSyntax vbRight, ExpressionSyntax csRight, TypeInfo rhsTypeInfo)
        {
            if (OptionCompareTextCaseInsensitive)
            {
                _extraUsingDirectives.Add("System.Globalization");
                var compareOptions = SyntaxFactory.Argument(GetCompareTextCaseInsensitiveCompareOptions());
                var compareString  = SyntaxFactory.InvocationExpression(ValidSyntaxFactory.MemberAccess(nameof(CultureInfo), nameof(CultureInfo.CurrentCulture),
                                                                                                        nameof(CultureInfo.CompareInfo), nameof(CompareInfo.Compare)),
                                                                        SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[]
                                                                                                                               { SyntaxFactory.Argument(csLeft), SyntaxFactory.Argument(csRight), compareOptions })));
                csLeft  = compareString;
                csRight = SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression,
                                                          SyntaxFactory.Literal(0));
            }
            else
            {
                (csLeft, csRight) = VbCoerceToString(vbLeft, csLeft, lhsTypeInfo, vbRight, csRight, rhsTypeInfo);
            }

            return(csLeft, csRight);
        }
コード例 #19
0
 public static ArgumentListSyntax ArgumentListWithOneArgument(ExpressionSyntax arg)
 {
     return(SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList <ArgumentSyntax>(SyntaxFactory.Argument(arg))));
 }
コード例 #20
0
        private static MemberDeclarationSyntax GenerateDeserializerMethod(Type type, List <FieldInfoMember> fields)
        {
            Expression <Action> deserializeInner =
                () => SerializationManager.DeserializeInner(default(Type), default(BinaryTokenStreamReader));
            var streamParameter = SF.IdentifierName("stream");

            var resultDeclaration =
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(type.GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("result")
                        .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type)))));
            var resultVariable      = SF.IdentifierName("result");
            var boxedResultVariable = resultVariable;

            var body = new List <StatementSyntax> {
                resultDeclaration
            };

            if (type.IsValueType)
            {
                // For value types, we need to box the result for reflection-based setters to work.
                body.Add(SF.LocalDeclarationStatement(
                             SF.VariableDeclaration(typeof(object).GetTypeSyntax())
                             .AddVariables(
                                 SF.VariableDeclarator("boxedResult").WithInitializer(SF.EqualsValueClause(resultVariable)))));
                boxedResultVariable = SF.IdentifierName("boxedResult");
            }

            // Record the result for cyclic deserialization.
            Expression <Action> recordObject =
                () => DeserializationContext.Current.RecordObject(default(object));
            var currentSerializationContext =
                SyntaxFactory.AliasQualifiedName(
                    SF.IdentifierName(SF.Token(SyntaxKind.GlobalKeyword)),
                    SF.IdentifierName("Orleans"))
                .Qualify("Serialization")
                .Qualify("DeserializationContext")
                .Qualify("Current");

            body.Add(
                SF.ExpressionStatement(
                    recordObject.Invoke(currentSerializationContext)
                    .AddArgumentListArguments(
                        SF.Argument(boxedResultVariable))));

            // Deserialize all fields.
            foreach (var field in fields)
            {
                var deserialized =
                    deserializeInner.Invoke()
                    .AddArgumentListArguments(
                        SF.Argument(SF.TypeOfExpression(field.Type)),
                        SF.Argument(streamParameter));
                body.Add(
                    SF.ExpressionStatement(
                        field.GetSetter(
                            resultVariable,
                            SF.CastExpression(field.Type, deserialized),
                            boxedResultVariable)));
            }

            body.Add(SF.ReturnStatement(SF.CastExpression(type.GetTypeSyntax(), boxedResultVariable)));
            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "Deserializer")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("expected")).WithType(typeof(Type).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("stream")).WithType(typeof(BinaryTokenStreamReader).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList()
                     .AddAttributes(SF.Attribute(typeof(DeserializerMethodAttribute).GetNameSyntax()))));
        }