Esempio n. 1
0
        public CompilationUnitSyntax StubInterface(CompilationUnitSyntax cu, InterfaceDeclarationSyntax interfaceDclr,
                                                   SemanticModel semanticModel)
        {
            INamedTypeSymbol           interfaceType = semanticModel.GetDeclaredSymbol(interfaceDclr);
            NamespaceDeclarationSyntax namespaceNode = GetNamespaceNode(interfaceDclr);
            string interfaceName             = interfaceType.GetGenericName();
            string stubName                  = NamingUtils.GetStubName(interfaceName);
            ClassDeclarationSyntax classDclr = SF.ClassDeclaration(SF.Identifier(stubName))
                                               .AddModifiers(SF.Token(RoslynUtils.GetVisibilityKeyword(interfaceType)))
                                               .WithBaseList(RoslynUtils.BaseList(interfaceName))
                                               .AddAttributeLists(AttributeListList(Attribute("CompilerGenerated")).ToArray());

            classDclr = RoslynUtils.CopyGenericConstraints(interfaceType, classDclr);
            classDclr = AddStubContainerField(classDclr, stubName);
            classDclr = StubProperties(interfaceType, classDclr);
            classDclr = StubMethods(interfaceType, classDclr);

            string fullNameSpace = semanticModel.GetDeclaredSymbol(namespaceNode).ToString();
            NamespaceDeclarationSyntax namespaceDclr = SF.NamespaceDeclaration(SF.IdentifierName(fullNameSpace))
                                                       .WithUsings(namespaceNode.Usings);

            namespaceDclr = namespaceDclr.AddMembers(classDclr);
            cu            = cu.AddMembers(namespaceDclr);
            return(cu);
        }
        private static ClassDeclarationSyntax GenerateWriteGrain(ClassDeclarationSyntax grainClass, ITypeSymbol swmrInterface, int readReplicaCount)
        {
            string grainName                   = grainClass.Identifier.Text;
            string writerGrainName             = SwmrUtils.GetWriteInterfaceName(grainName);
            string writerInterfaceName         = SwmrUtils.GetWriteInterfaceName(swmrInterface.Name);
            ClassDeclarationSyntax writerGrain = GenerateClassSqueleton(writerGrainName).WithBaseList(RoslynUtils.BaseList(new[] { "Grain", writerInterfaceName }));

            writerGrain = RoslynUtils.AddField(writerGrain, "ITopology<string>", "_topology");
            writerGrain = writerGrain.AddMembers(GenerateOnActivateAsyncMethod(readReplicaCount));

            string readReplicaInterfaceName = SwmrUtils.GetReadReplicaInterfaceName(swmrInterface.Name);

            foreach (ISymbol member in swmrInterface.GetMembers())
            {
                IMethodSymbol methodSymbol = member as IMethodSymbol;
                if (methodSymbol == null || IsReadOnlyMethod(methodSymbol) || new MethodInspector(methodSymbol).MethodName == "GetState")
                {
                    continue;
                }

                MethodInspector         methodInspector = new MethodInspector(methodSymbol);
                MethodDeclarationSyntax methodImpl      = GenerateMethodDeclaration(methodInspector);
                methodImpl = SwmrUtils.AddSessionIdParameter(methodImpl).AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.AsyncKeyword)).WithSemicolonToken(SF.Token(SyntaxKind.None));

                BlockSyntax statmentBlock = SF.Block();
                statmentBlock = AddStatement(statmentBlock, "string grainId = this.GetPrimaryKeyString();");
                statmentBlock = AddStatement(statmentBlock, string.Format("{0} grain = GrainFactory.GetGrain<{0}>(grainId);", swmrInterface.Name));
                statmentBlock = AddStatement(statmentBlock, String.Format("{0} await grain.{1}({2});", methodInspector.ReturnType != "Task"? "var result =" : "", methodInspector.MethodName, string.Join(", ", methodInspector.MethodParams.Keys)));
                statmentBlock = AddStatement(statmentBlock, "GrainState state = await grain.GetState();");
                statmentBlock = AddStatement(statmentBlock, "string sessionNode = _topology.GetNode(sessionId);");
                statmentBlock = AddStatement(statmentBlock, "IEnumerable<string> otherNodes = _topology.Nodes.Where(node => node != sessionNode);");

                ForEachStatementSyntax forEachStatement = SF.ForEachStatement(
                    SF.PredefinedType(SF.Token(SyntaxKind.StringKeyword)),
                    SF.Identifier("node"),
                    SF.IdentifierName("otherNodes"),
                    SF.Block(SF.ParseStatement(GenerateSetStateStmt(readReplicaInterfaceName, @"node")))
                    );

                statmentBlock = statmentBlock.AddStatements(forEachStatement);
                statmentBlock =
                    AddStatement(statmentBlock, (string.Format("{0} {1}", "await",
                                                               GenerateSetStateStmt(readReplicaInterfaceName, @"sessionNode"))));
                if (methodInspector.ReturnType != "Task")
                {
                    statmentBlock = AddStatement(statmentBlock, "return result;");
                }
                methodImpl  = methodImpl.WithBody(statmentBlock);
                writerGrain = writerGrain.AddMembers(methodImpl);
            }

            return(writerGrain);
        }
        private static ClassDeclarationSyntax GenerateReadGrain(ClassDeclarationSyntax grainClass, ITypeSymbol swmrInterface, int readReplicaCount)
        {
            string readGrainName             = SwmrUtils.GetReadInterfaceName(grainClass.Identifier.Text);
            string readerInterfaceName       = SwmrUtils.GetReadInterfaceName(swmrInterface.Name);
            ClassDeclarationSyntax readGrain = GenerateClassSqueleton(readGrainName).WithAttributeLists(AttributeUtils.AttributeListList(AttributeUtils.Attribute(StatelessWorkerAttributeName))).WithBaseList(RoslynUtils.BaseList(new[] { "Grain", readerInterfaceName }));

            readGrain = RoslynUtils.AddField(readGrain, "ITopology<string>", "_topology");
            readGrain = readGrain.AddMembers(GenerateOnActivateAsyncMethod(readReplicaCount));

            string readReplicaInterfaceName = SwmrUtils.GetReadReplicaInterfaceName(swmrInterface.Name);

            foreach (ISymbol member in swmrInterface.GetMembers())
            {
                IMethodSymbol methodSymbol = member as IMethodSymbol;
                if (methodSymbol == null || !IsReadOnlyMethod(methodSymbol))
                {
                    continue;
                }

                MethodInspector methodInspector = new MethodInspector(methodSymbol);
                string          parameters      = "string sessionId";
                if (methodInspector.MethodParams.Any())
                {
                    parameters = string.Join(", ", methodInspector.MethodParams.Select(param => string.Format("{0} {1}", param.Value, param.Key))) + " ," + parameters;
                }

                var method = RoslynUtils.ParseMethod(string.Format(
                                                         @"
        public {0} {1}({2})
        {{
            string sessionNode = _topology.GetNode(sessionId);
            var readReplica = GrainFactory.GetGrain<{3}>(sessionNode);
            return readReplica.{1}({4});
        }}", methodInspector.ReturnType, methodInspector.MethodName, parameters, readReplicaInterfaceName, string.Join(", ", methodInspector.MethodParams.Keys)));

                readGrain =
                    readGrain.AddMembers(
                        method.WithLeadingTrivia(SF.EndOfLine("")));
            }
            return(readGrain);
        }
        private ClassDeclarationSyntax GenerateReadReplicaGrain(ClassDeclarationSyntax grainClass, ITypeSymbol swmrInterface)
        {
            string readReplicaGrainName             = SwmrUtils.GetReadReplicaGrainName(grainClass.Identifier.Text);
            string readReplicaInterfaceName         = SwmrUtils.GetReadReplicaInterfaceName(swmrInterface.Name);
            ClassDeclarationSyntax readReplicaGrain = GenerateClassSqueleton(readReplicaGrainName).WithBaseList(RoslynUtils.BaseList(new[] { "Grain", readReplicaInterfaceName }));

            string grainStateTypeName = FindGrainStateTypeName(grainClass);

            readReplicaGrain = readReplicaGrain.AddMembers(SF.FieldDeclaration(SF.VariableDeclaration(SF.ParseTypeName(grainStateTypeName), SF.SeparatedList(new[] { SF.VariableDeclarator(SF.Identifier("State")) }))).AddModifiers(SF.Token(SyntaxKind.PrivateKeyword)));

            readReplicaGrain = readReplicaGrain.AddMembers(GenerateReadReplicaOnActivateAsync(swmrInterface));

            foreach (ISymbol member in swmrInterface.GetMembers())
            {
                IMethodSymbol methodSymbol = member as IMethodSymbol;
                if (methodSymbol == null || !IsReadOnlyMethod(methodSymbol))
                {
                    continue;
                }
                MethodDeclarationSyntax methodImpl = RoslynUtils.FindImplementation(methodSymbol, grainClass);
                readReplicaGrain = readReplicaGrain.AddMembers(methodImpl.WithLeadingTrivia(SF.EndOfLine("")));
            }

            readReplicaGrain = readReplicaGrain.AddMembers(GenerateSetStateMethod(grainStateTypeName));

            return(readReplicaGrain);
        }