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); }
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()); }
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)); }
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()); }
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); }
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)); }
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); }
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); }