Exemple #1
0
        public static SyntaxToken LowercaseIdentifierFirstLetter(SyntaxToken identifier)
        {
            ThrowHelpers.ThrowIfNotIdentifier(nameof(identifier), identifier);

            if (identifier.Value is string s && s.Length >= 1)
            {
                var newString = char.ToLowerInvariant(s[0]) + (s.Length >= 2 ? s.Substring(1) : string.Empty);
                return(SF.Identifier(newString));
            }

            return(identifier);
        }
        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);
        }
Exemple #3
0
 public static TypeSyntax CreateSyntax(this INamedTypeSymbol symbol)
 {
     Contract.Requires(symbol.CanBeReferencedByName);
     if (symbol.IsGenericType)
     {
         return(symbol.CreateGenericSyntax(symbol.TypeArguments.Select(s => (TypeSyntax)(((INamedTypeSymbol)s).CreateSyntax())).ToArray()));
     }
     else
     {
         return(SF.IdentifierName(SF.Identifier(symbol.Name)));
     }
 }
        private static ParameterSyntax[] GetEventParameters(IEventSymbol eventSymbol)
        {
            List <ParameterSyntax> parameters = new List <ParameterSyntax>
            {
                SF.Parameter(SF.Identifier("sender")).WithType(SF.ParseTypeName("object"))
            };
            INamedTypeSymbol type = (INamedTypeSymbol)(eventSymbol.Type);

            if (type.TypeArguments.Any())
            {
                parameters.Add(SF.Parameter(SF.Identifier("args"))
                               .WithType(SF.ParseTypeName(type.TypeArguments[0].Name)));
            }

            return(parameters.ToArray());
        }
Exemple #5
0
        private static MethodDeclarationSyntax GenerateSetupMethod(IMethodSymbol methodSymbol, string setupMethodName, string delegateTypeName,
                                                                   INamedTypeSymbol stubbedInterface,
                                                                   ClassDeclarationSyntax stub)
        {
            SyntaxKind visibility = RoslynUtils.GetVisibilityKeyword(stubbedInterface);
            MethodDeclarationSyntax methodDclr = SF.MethodDeclaration(SF.ParseTypeName(stub.Identifier.Text), setupMethodName)
                                                 .AddModifiers(SF.Token(visibility)).WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken))
                                                 .AddParameterListParameters(
                SF.Parameter(SF.Identifier("del")).WithType(SF.ParseTypeName(delegateTypeName)),
                SF.Parameter(SF.Identifier("count")).WithType(SF.ParseTypeName("int")).WithDefault(SF.EqualsValueClause(SF.ParseExpression("Times.Forever"))),
                SF.Parameter(SF.Identifier("overwrite")).WithType(SF.ParseTypeName("bool")).WithDefault(SF.EqualsValueClause(SF.ParseExpression("false")))
                )
                                                 .WithBody(SF.Block(
                                                               SF.ParseStatement("_stubs.SetMethodStub(del, count, overwrite);\n"),
                                                               SF.ParseStatement("return this;\n")
                                                               ))
                                                 .WithSemicolonToken(SF.Token(SyntaxKind.None));

            return(RoslynUtils.CopyGenericConstraints(methodSymbol, methodDclr));
        }
Exemple #6
0
        private static ParameterSyntax[] GetEventParameters(IEventSymbol eventSymbol, bool isCustomDelegateEvent)
        {
            var parameters        = new List <ParameterSyntax>();
            INamedTypeSymbol type = (INamedTypeSymbol)(eventSymbol.Type);

            if (isCustomDelegateEvent)
            {
                IMethodSymbol delegateInvokeMethodSymbol = ((INamedTypeSymbol)(eventSymbol.OriginalDefinition).Type).DelegateInvokeMethod;
                parameters.AddRange(RoslynUtils.GetMethodParameterSyntaxList(delegateInvokeMethodSymbol).ToArray());
            }
            else
            {
                parameters.Add(SF.Parameter(SF.Identifier("sender")).WithType(SF.ParseTypeName("object")));
                if (type.TypeArguments.Any())
                {
                    parameters.Add(SF.Parameter(SF.Identifier("args"))
                                   .WithType(SF.ParseTypeName(type.TypeArguments[0].Name)));
                }
            }

            return(parameters.ToArray());
        }
Exemple #7
0
 public static SyntaxToken IdentifierToken(string name) => SF.Identifier(name);
 private static ClassDeclarationSyntax GenerateClassSqueleton(string className)
 {
     return(SF.ClassDeclaration(SF.Identifier(className)).AddModifiers(SF.Token(SyntaxKind.PublicKeyword)));
 }
        private static MethodDeclarationSyntax GenerateMethodDeclaration(MethodInspector methodInspector)
        {
            MethodDeclarationSyntax methodDclr = SF.MethodDeclaration(SF.ParseTypeName(methodInspector.ReturnType), SF.Identifier(methodInspector.MethodName));

            foreach (KeyValuePair <string, string> keyValuePair in methodInspector.MethodParams)
            {
                string paramType = keyValuePair.Value;
                string paramName = keyValuePair.Key;
                methodDclr = RoslynUtils.AppendParameterToMethod(methodDclr, RoslynUtils.CreateParameter(paramType, paramName));
            }
            return(methodDclr);
        }
        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);
        }
Exemple #11
0
 public static ParameterSyntax CreateParameter(string type, string name)
 {
     return(SF.Parameter(new SyntaxList <AttributeListSyntax>(), new SyntaxTokenList(), SF.IdentifierName(type), SF.Identifier(new SyntaxTriviaList().Add(SF.Space), name, new SyntaxTriviaList()), null));
 }
Exemple #12
0
 public static ClassDeclarationSyntax AddField(ClassDeclarationSyntax classDeclaration, string type, string name)
 {
     return(classDeclaration.AddMembers(
                SF.FieldDeclaration(SF.VariableDeclaration(SF.ParseTypeName(type),
                                                           SF.SeparatedList(new[] { SF.VariableDeclarator(SF.Identifier(name)) })))
                .AddModifiers(SF.Token(SyntaxKind.PrivateKeyword))));
 }
        private BasePropertyDeclarationSyntax CreatePropertyDclr(IMethodSymbol methodSymbol, string propType)
        {
            if (methodSymbol.IsIndexerAccessor())
            {
                IndexerDeclarationSyntax indexerDclr = SF.IndexerDeclaration(
                    SF.ParseTypeName(propType))
                                                       .WithExplicitInterfaceSpecifier(SF.ExplicitInterfaceSpecifier(
                                                                                           SF.IdentifierName(methodSymbol.GetContainingInterfaceGenericQualifiedName())));
                indexerDclr = indexerDclr.AddParameterListParameters(
                    RoslynUtils.GetMethodParameterSyntaxList(methodSymbol).ToArray());
                return(indexerDclr);
            }

            string propName = methodSymbol.AssociatedSymbol.Name;
            PropertyDeclarationSyntax propDclr = SF.PropertyDeclaration(SF.ParseTypeName(propType), SF.Identifier(propName))
                                                 .WithExplicitInterfaceSpecifier(SF.ExplicitInterfaceSpecifier(
                                                                                     SF.IdentifierName(methodSymbol.GetContainingInterfaceGenericQualifiedName())));

            return(propDclr);
        }
Exemple #14
0
 public static GenericNameSyntax CreateGenericSyntax(this INamedTypeSymbol symbol, params TypeSyntax[] parameters)
 {
     Contract.Requires(symbol.CanBeReferencedByName);
     return(CreateGenericSyntax(SF.Identifier(symbol.Name), parameters));
 }
        private static ClassDeclarationSyntax GenerateApiControllerForInterface(InterfaceDeclarationSyntax interfaceNode, SemanticModel semanticModel)
        {
            if (!RoslynUtils.IsPublic(interfaceNode))
            {
                return(null);
            }

            AttributeSyntax apiControllerAttribute = AttributeUtils.SelectAttributeOfType(interfaceNode.AttributeLists, typeof(ApiControllerAttribute), semanticModel);

            // if the interface is not annotated with the ApiController attribute, do nothing
            if (apiControllerAttribute == null)
            {
                return(null);
            }

            var namespaceNode = interfaceNode.Parent as NamespaceDeclarationSyntax;

            if (namespaceNode == null)
            {
                throw new Exception("A grain interface must be declared inside a namespace");
            }

            // copy all attributes except the ApiController attribute
            SyntaxList <AttributeListSyntax> attributesLists = AttributeUtils.RemoveAttributeOfType(interfaceNode.AttributeLists, typeof(ApiControllerAttribute), semanticModel);

            // add the RoutePrefix attribute (if any)
            var attributeInspector = new AttributeInspector(apiControllerAttribute, semanticModel);

            if (attributeInspector.NamedArguments.ContainsKey(RoutePrefix))
            {
                AttributeSyntax routePrefixAttribute = AttributeUtils.AttributeWithArgument(RoutePrefix,
                                                                                            attributeInspector.NamedArguments[RoutePrefix]);
                attributesLists = attributesLists.Add(AttributeUtils.AttributeList(routePrefixAttribute));
            }

            string grainName         = interfaceNode.Identifier.Text;
            string apiControllerName = GetApiControllerName(grainName);

            // create the Api controller class, add the attributes to it and make it a subclass of ApiController
            ClassDeclarationSyntax classDclr =
                SF.ClassDeclaration(SF.Identifier(apiControllerName)).AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.PartialKeyword)).WithAttributeLists(SF.List(attributesLists)).WithBaseList(SF.BaseList(SF.SeparatedList <BaseTypeSyntax>().Add(SF.SimpleBaseType(SF.IdentifierName(ApicontrollerClassName)))));

            // Add the IGrainFactory field and to the constructor
            classDclr = RoslynUtils.AddField(classDclr, "IGrainFactory", "_grainFactory");
            MethodDeclarationSyntax constructor = RoslynUtils.ParseMethod(string.Format(@"
        public {0}(IGrainFactory grainFactory)
        {{
            _grainFactory = grainFactory;
        }}", apiControllerName)).WithTrailingTrivia(SF.EndOfLine(""));

            classDclr = classDclr.AddMembers(constructor);

            // generate the api controller methods and add them to the class
            IEnumerable <MethodDeclarationSyntax> apiControllerMethods = GenerateApiControllerMethods(RoslynUtils.GetMethodDeclarations(interfaceNode), grainName);

            // ReSharper disable once LoopCanBeConvertedToQuery
            foreach (var method in apiControllerMethods)
            {
                classDclr = classDclr.AddMembers(method);
            }
            return(classDclr);
        }