Beispiel #1
0
        private static MethodDeclarationSyntax GenerateGetMethodNameMethod(WellKnownTypes wellKnownTypes, GrainInterfaceDescription description)
        {
            var method            = wellKnownTypes.GrainReference.Method("GetMethodName");
            var methodDeclaration = method.GetDeclarationSyntax().AddModifiers(Token(SyntaxKind.OverrideKeyword));
            var parameters        = method.Parameters;

            var interfaceIdArgument = parameters[0].Name.ToIdentifierName();
            var methodIdArgument    = parameters[1].Name.ToIdentifierName();

            var callThrowMethodNotImplemented = InvocationExpression(IdentifierName("ThrowMethodNotImplemented"))
                                                .WithArgumentList(ArgumentList(SeparatedList(new[]
            {
                Argument(interfaceIdArgument),
                Argument(methodIdArgument)
            })));

            // This method is used directly after its declaration to create blocks for each interface id, comprising
            // primarily of a nested switch statement for each of the methods in the given interface.
            BlockSyntax ComposeInterfaceBlock(INamedTypeSymbol interfaceType, SwitchStatementSyntax methodSwitch)
            {
                return(Block(methodSwitch.AddSections(SwitchSection()
                                                      .AddLabels(DefaultSwitchLabel())
                                                      .AddStatements(
                                                          ExpressionStatement(callThrowMethodNotImplemented),
                                                          ReturnStatement(LiteralExpression(SyntaxKind.NullLiteralExpression))))));
            }

            var interfaceCases = GrainInterfaceCommon.GenerateGrainInterfaceAndMethodSwitch(
                wellKnownTypes,
                description.Type,
                methodIdArgument,
                methodType => new StatementSyntax[] { ReturnStatement(methodType.Name.ToLiteralExpression()) },
                ComposeInterfaceBlock);

            // Generate the default case, which will throw a NotImplementedException.
            var callThrowInterfaceNotImplemented = InvocationExpression(IdentifierName("ThrowInterfaceNotImplemented"))
                                                   .WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(interfaceIdArgument))));
            var defaultCase = SwitchSection()
                              .AddLabels(DefaultSwitchLabel())
                              .AddStatements(
                ExpressionStatement(callThrowInterfaceNotImplemented),
                ReturnStatement(LiteralExpression(SyntaxKind.NullLiteralExpression)));

            var throwInterfaceNotImplemented = GrainInterfaceCommon.GenerateMethodNotImplementedFunction(wellKnownTypes);
            var throwMethodNotImplemented    = GrainInterfaceCommon.GenerateInterfaceNotImplementedFunction(wellKnownTypes);

            var interfaceIdSwitch =
                SwitchStatement(interfaceIdArgument).AddSections(interfaceCases.ToArray()).AddSections(defaultCase);

            return(methodDeclaration.AddBodyStatements(interfaceIdSwitch, throwInterfaceNotImplemented, throwMethodNotImplemented));
        }
        /// <summary>
        /// Generates syntax for an invoke method.
        /// </summary>
        private MethodDeclarationSyntax GenerateInvokeMethod(
            WellKnownTypes wellKnownTypes,
            INamedTypeSymbol grainType,
            IMethodSymbol invokeMethod,
            Dictionary <IMethodSymbol, GenericInvokerField> genericInvokerFields)
        {
            var parameters = invokeMethod.Parameters;

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

            var interfaceIdProperty = wellKnownTypes.InvokeMethodRequest.Property("InterfaceTypeCode");
            var methodIdProperty    = wellKnownTypes.InvokeMethodRequest.Property("MethodId");
            var argumentsProperty   = wellKnownTypes.InvokeMethodRequest.Property("Arguments");

            // Store the relevant values from the request in local variables.
            var interfaceIdDeclaration =
                LocalDeclarationStatement(
                    VariableDeclaration(wellKnownTypes.Int32.ToTypeSyntax())
                    .AddVariables(
                        VariableDeclarator("interfaceTypeCode")
                        .WithInitializer(EqualsValueClause(requestArgument.Member(interfaceIdProperty.Name)))));
            var interfaceIdVariable = IdentifierName("interfaceTypeCode");

            var methodIdDeclaration =
                LocalDeclarationStatement(
                    VariableDeclaration(wellKnownTypes.Int32.ToTypeSyntax())
                    .AddVariables(
                        VariableDeclarator("methodId")
                        .WithInitializer(EqualsValueClause(requestArgument.Member(methodIdProperty.Name)))));
            var methodIdVariable = IdentifierName("methodId");

            var argumentsDeclaration =
                LocalDeclarationStatement(
                    VariableDeclaration(IdentifierName("var"))
                    .AddVariables(
                        VariableDeclarator("arguments")
                        .WithInitializer(EqualsValueClause(requestArgument.Member(argumentsProperty.Name)))));
            var argumentsVariable = IdentifierName("arguments");

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

            var callThrowMethodNotImplemented = InvocationExpression(IdentifierName("ThrowMethodNotImplemented"))
                                                .WithArgumentList(ArgumentList(SeparatedList(new[]
            {
                Argument(interfaceIdVariable),
                Argument(methodIdVariable)
            })));

            // This method is used directly after its declaration to create blocks for each interface id, comprising
            // primarily of a nested switch statement for each of the methods in the given interface.
            BlockSyntax ComposeInterfaceBlock(INamedTypeSymbol interfaceType, SwitchStatementSyntax methodSwitch)
            {
                ExpressionSyntax targetObject;

                if (grainType.HasInterface(wellKnownTypes.IGrainExtension))
                {
                    targetObject = InvocationExpression(grainArgument.Member("GetGrainExtension", interfaceType), ArgumentList());
                }
                else
                {
                    targetObject = grainArgument.Member("GrainInstance");
                }

                var typedGrainDeclaration = LocalDeclarationStatement(
                    VariableDeclaration(IdentifierName("var"))
                    .AddVariables(
                        VariableDeclarator("casted")
                        .WithInitializer(EqualsValueClause(ParenthesizedExpression(CastExpression(interfaceType.ToTypeSyntax(), targetObject))))));

                return(Block(typedGrainDeclaration,
                             methodSwitch.AddSections(SwitchSection()
                                                      .AddLabels(DefaultSwitchLabel())
                                                      .AddStatements(
                                                          ExpressionStatement(callThrowMethodNotImplemented),
                                                          ReturnStatement(LiteralExpression(SyntaxKind.NullLiteralExpression))))));
            }

            var interfaceCases = GrainInterfaceCommon.GenerateGrainInterfaceAndMethodSwitch(
                wellKnownTypes,
                grainType,
                methodIdVariable,
                methodType => GenerateInvokeForMethod(wellKnownTypes, IdentifierName("casted"), methodType, argumentsVariable, genericInvokerFields),
                ComposeInterfaceBlock);

            var throwInterfaceNotImplemented = GrainInterfaceCommon.GenerateMethodNotImplementedFunction(wellKnownTypes);
            var throwMethodNotImplemented    = GrainInterfaceCommon.GenerateInterfaceNotImplementedFunction(wellKnownTypes);

            // Generate the default case, which will call the above local function to throw .
            var callThrowInterfaceNotImplemented = InvocationExpression(IdentifierName("ThrowInterfaceNotImplemented"))
                                                   .WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(interfaceIdVariable))));
            var defaultCase = SwitchSection()
                              .AddLabels(DefaultSwitchLabel())
                              .AddStatements(
                ExpressionStatement(callThrowInterfaceNotImplemented),
                ReturnStatement(LiteralExpression(SyntaxKind.NullLiteralExpression)));

            var interfaceIdSwitch =
                SwitchStatement(interfaceIdVariable).AddSections(interfaceCases.ToArray()).AddSections(defaultCase);

            return(methodDeclaration.AddBodyStatements(interfaceIdSwitch, throwInterfaceNotImplemented, throwMethodNotImplemented));
        }