public static ConstructorDeclarationSyntax MakeConstructor(string className, IEnumerable <Field> fields) { var constructorParameters = SF.ParameterList( SF.SeparatedList( fields.Select(field => SF.Parameter(SF.Identifier(field.Name)) .WithType(field.Type)))); var constructorBodyStatements = fields.Select( field => SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SF.ThisExpression(), SF.IdentifierName(field.Name) ), SF.IdentifierName(field.Name)))); return (SF.ConstructorDeclaration(className) .WithModifiers(SF.TokenList(new[] { SF.Token(SyntaxKind.PublicKeyword) })) .WithParameterList(constructorParameters) .WithBody(SF.Block(constructorBodyStatements))); }
/// <summary> /// Returns syntax for the constructor. /// </summary> /// <param name="className">The name of the class.</param> /// <returns>Syntax for the constructor.</returns> private static ConstructorDeclarationSyntax GenerateConstructor(string className) { return (SF.ConstructorDeclaration(className) .AddModifiers(SF.Token(SyntaxKind.StaticKeyword)) .AddParameterListParameters() .AddBodyStatements( SF.ExpressionStatement( SF.InvocationExpression(SF.IdentifierName("Register")).AddArgumentListArguments()))); }
public ClassContext(string className, Type baseType, Type modelType, ContentContextExitHandler <ClassDeclarationSyntax> exitHandler) { _className = className; _baseType = baseType; _modelType = modelType; _exitHandler = exitHandler; var modelTypeName = GetTypeName(modelType); var constructor = SF.ConstructorDeclaration(_className) .WithModifiers(SF.TokenList(SF.Token(SyntaxKind.PublicKeyword))) .WithBody(SF.Block()); _memberDeclarations.Add(constructor); }
public ConstructorDeclarationSyntax Build() { var ctor = SF.ConstructorDeclaration(_name) .AddModifiers(_modifiers.Build().ToArray()) .AddParameterListParameters(_parameters.Select(p => p.Build()).ToArray()); if (_expr != null) { return(ctor.WithExpressionBody(SF.ArrowExpressionClause(_expr.Value.Build())).WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken))); } else if (_block != null) { return(ctor.WithBody(_block.Value.Build())); } else { return(ctor.WithSemicolonToken(SF.Token(SyntaxKind.SemicolonToken))); } }
private static ConstructorDeclarationSyntax MakeConstructor( TypeDeclarationSyntax type, IEnumerable <Field> fields, ConstructorDeclarationSyntax maybePreviousConstructor) { var fieldsList = fields.ToList(); var constructorParameters = SF.ParameterList( SF.SeparatedList( fieldsList.Select( field => SF.Parameter(SF.Identifier(field.Name)) .WithType(field.Type) .WithAttributeLists(field.Attributes) ) ) ); var constructorBodyStatements = fieldsList.Select( field => SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SF.ThisExpression(), SF.IdentifierName(field.Name) ), SF.IdentifierName(field.Name) ) ) ); var previousAttributes = maybePreviousConstructor?.AttributeLists ?? new SyntaxList <AttributeListSyntax>(); var res = SF.ConstructorDeclaration(type.Identifier.Text) .WithAttributeLists(previousAttributes) .WithModifiers(SF.TokenList(new[] { SF.Token(SyntaxKind.PublicKeyword) })) .WithParameterList(constructorParameters) .WithBody(SF.Block(constructorBodyStatements)); res = fieldsList.Any(x => x.StructuredTrivia != null) ? res.WithLeadingTrivia( MakeXmlDocComments(maybePreviousConstructor, fieldsList, Constants.DefaultCtorSummary) ) : maybePreviousConstructor?.HasLeadingTrivia ?? false? res.WithLeadingTrivia(maybePreviousConstructor.GetLeadingTrivia()) : res; return(res); }
protected virtual IEnumerable <MemberDeclarationSyntax> CreateConstructors() { yield return(SF.ConstructorDeclaration ( SF.List <AttributeListSyntax>(), // Only Amazon.JSII.Runtime should create interface proxies, // so we make the constructor private. SF.TokenList(SF.Token(SyntaxKind.PrivateKeyword)), GetProxyTypeNameSyntax(), SF.ParseParameterList("(ByRefValue reference)"), SF.ConstructorInitializer ( SyntaxKind.BaseConstructorInitializer, SF.ParseArgumentList("(reference)") ), SF.Block(), null )); }
GetTypeDeclarationWithEmptyConstructor(Document document, SyntaxNode root, ClassDeclarationSyntax @class, MemberDeclarationSyntax[] injectables) { var classsName = @class.Identifier.Text; var newConstructor = SF.ConstructorDeclaration( SF.Identifier(classsName)) .WithModifiers(SF.TokenList( SF.Token( SF.TriviaList(), SyntaxKind.PublicKeyword, SF.TriviaList(SF.Space)))) .WithBody(SF.Block()); var members = @class.Members; var lastInjectableIndex = @class.Members.IndexOf(injectables.Last()); var lastInjectableIsLastMember = lastInjectableIndex == @class.Members.Count(); ClassDeclarationSyntax newClass; if (lastInjectableIsLastMember) { newClass = @class.AddMembers(newConstructor); } else { var newMmebers = members.Insert(lastInjectableIndex + 1, newConstructor); newClass = @class.WithMembers(newMmebers); } var newDocumentRoot = root.ReplaceNode(@class, newClass); var newDocument = document.WithSyntaxRoot(newDocumentRoot); newDocumentRoot = newDocument.GetSyntaxRootAsync().Result; newClass = newDocumentRoot.GetMatchingClassDeclaration(newClass); newConstructor = GetPublicEligableConstructors(newClass).Single(); return(newDocument, newDocumentRoot, newClass, newConstructor); }
private ClassDeclarationSyntax AddConstructor(INamedTypeSymbol interfaceType, ClassDeclarationSyntax classDclr, SimpleStubsConfig config) { string ctorName = NamingUtils.GetStubName(interfaceType.Name); string defaultMockBehavior = GetValidMockBehaviorEnumValue(config.DefaultMockBehavior); var ctorParameter = SF.Parameter(SF.Identifier("mockBehavior")) .WithType(SF.ParseTypeName("MockBehavior")) .WithDefault(SF.EqualsValueClause(SF.ParseExpression($"MockBehavior.{defaultMockBehavior}"))); classDclr = classDclr.AddMembers(SF.ConstructorDeclaration(ctorName) .WithModifiers(SF.TokenList(SF.Token(SyntaxKind.PublicKeyword))) .WithParameterList(SF.ParameterList().AddParameters(ctorParameter)) .WithBody(SF.Block().AddStatements(SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.IdentifierName("MockBehavior"), SF.IdentifierName("mockBehavior"))) ))); return(classDclr); }
private void AddCtor(WebInfoGenerationData genData, List <WebInfoGenerationData> childrenGens) { var statements = new List <StatementSyntax>(); var infoInit = SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.IdentifierName(InfoClassName), SF.ObjectCreationExpression(SF.ParseTypeName($"{InfoStaticClassName}.{InfoClassName}")) .WithArgumentList(SF.ArgumentList()) ) ); statements.Add(infoInit); var locatorInit = SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.IdentifierName(LocatorClassName), SF.ObjectCreationExpression(SF.IdentifierName(nameof(WebLocatorInfo))) .WithArgumentList(SF.ArgumentList()) ) ); statements.Add(locatorInit); var locatorProps = new List <string> { nameof(WebLocatorInfo.LocatorType), nameof(WebLocatorInfo.LocatorValue), nameof(WebLocatorInfo.IsRelative) }; foreach (var locatorProp in locatorProps) { var st = SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SF.IdentifierName(LocatorClassName), SF.IdentifierName(locatorProp) ), SF.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SF.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SF.IdentifierName(InfoStaticClassName), SF.IdentifierName(LocatorStaticClassName) ), SF.IdentifierName(locatorProp) ) ) ); statements.Add(st); } if (childrenGens?.Count > 0) { var elsInit = SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.IdentifierName(nameof(CombinedWebElementInfo.Elements)), SF.ObjectCreationExpression( SF.GenericName(SF.Identifier("List")) .WithTypeArgumentList(SF.TypeArgumentList(SF.SingletonSeparatedList <TypeSyntax>(SF.IdentifierName(nameof(WebElementInfo))))) ) .WithArgumentList(SF.ArgumentList()) ) ); statements.Add(elsInit); foreach (var childGen in childrenGens) { var propInit = SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.IdentifierName(childGen.PropertyName), SF.ObjectCreationExpression(SF.IdentifierName(childGen.ClassName)) .WithArgumentList(SF.ArgumentList()) ) ); statements.Add(propInit); var parentSt = SF.ExpressionStatement( SF.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, SF.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SF.IdentifierName(childGen.PropertyName), SF.IdentifierName(nameof(WebElementInfo.Parent)) ), SF.ThisExpression() ) ); statements.Add(parentSt); var elsAddSt = SF.ExpressionStatement( SF.InvocationExpression( SF.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SF.IdentifierName(nameof(CombinedWebElementInfo.Elements)), SF.IdentifierName("Add") ) ).WithArgumentList( SF.ArgumentList( SF.SingletonSeparatedList(SF.Argument(SF.IdentifierName(childGen.PropertyName))) ) ) ); statements.Add(elsAddSt); } } var summary = GetDocCommentWithText(genData.Element.Description); var ctor = SF.ConstructorDeclaration(SF.Identifier(genData.ClassName)) .WithBody(SF.Block(statements)) .WithModifiers(SF.TokenList(SF.Token(SyntaxKind.PublicKeyword).WithLeadingTrivia(SF.Trivia(summary)))); var cd = genData.ClassSyntax.AddMembers(ctor); genData.ClassSyntax = cd; }
private SyntaxList <MemberDeclarationSyntax> CreateProtectedConstructors() { var list = new SyntaxList <MemberDeclarationSyntax>(); //We implicitly have version //if( m_fields.Count > 0 ) { BaseMethodDeclarationSyntax cons = SF.ConstructorDeclaration(m_class.Identifier); cons = SU.AddKeyword(cons, SyntaxKind.ProtectedKeyword); var paramList = new SeparatedSyntaxList <ParameterSyntax>(); { var param = SF.Parameter(SF.Identifier("version")) .WithType(SF.IdentifierName("ulong")); paramList = paramList.Add(param); } foreach (var f in m_fields) { var param = SF.Parameter(f.Key.Identifier) .WithType(f.Value); paramList = paramList.Add(param); } cons = cons.WithParameterList(SF.ParameterList(paramList)); var block = SF.Block(); var assignments = new SyntaxList <StatementSyntax>(); foreach (var f in m_fields) { var statement = SF.ParseStatement($"this.{f.Key.Identifier} = {f.Key.Identifier};"); assignments = assignments.Add(statement); } block = block.WithStatements(assignments); cons = cons.WithBody(block); list = list.Add(cons); } { BaseMethodDeclarationSyntax cons = SF.ConstructorDeclaration(m_class.Identifier); cons = SU.AddKeyword(cons, SyntaxKind.ProtectedKeyword); var block = SF.Block(); cons = cons.WithBody(block); list = list.Add(cons); } return(list); }
void Save(string packageOutputRoot, ISymbolMap symbols, Assembly assembly, string tarballFileName, string jsiiFileName) { if (assembly.Docs != null) { // TODO: Use Microsoft.Extensions.Logging instead of Console.Error. Console.Error.WriteLine($"Warning: Ignoring documentation comment on assembly {assembly.Name}. Assembly-level documentation comments are not supported for .NET"); } SaveProjectFile(); SaveAssemblyInfo(assembly.Name, assembly.Version, tarballFileName); SaveDependencyAnchorFile(); foreach (Type type in assembly.Types?.Values ?? Enumerable.Empty <Type>()) { SaveType(type); } void SaveProjectFile() { XElement project = new XElement("Project", new XAttribute("Sdk", "Microsoft.NET.Sdk"), new XElement("PropertyGroup", assembly.GetMsBuildProperties()), new XElement("ItemGroup", new XElement("EmbeddedResource", new XAttribute("Include", tarballFileName) ) ), new XElement("ItemGroup", new XElement("PackageReference", new XAttribute("Include", "Amazon.JSII.Runtime"), new XAttribute("Version", JsiiVersion.Version) ), GetDependencies() .Distinct() .Select(d => new { Package = symbols.GetAssemblyName(d.Key), Version = d.Value.GetDecoratedVersion() }) .Select(d => new XElement("PackageReference", new XAttribute("Include", d.Package), new XAttribute("Version", d.Version) ) ) ) ); if (!_fileSystem.Directory.Exists(packageOutputRoot)) { _fileSystem.Directory.CreateDirectory(packageOutputRoot); } // Save to StringBuilder instead of directly to path, so that we can // redirect the output through the filesystem shim. Project files are // small, so this shouldn't be a memory hog. StringBuilder builder = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings { // Visual Studio omits the XML declaration when creating project files, so we do too. OmitXmlDeclaration = true, // Visual Studio indents project files (they are often edited by hand), so we do too. Indent = true, }; using (XmlWriter writer = XmlWriter.Create(builder, settings)) { project.Save(writer); } string csProjPath = Path.Combine(packageOutputRoot, $"{assembly.GetNativePackageId()}.csproj"); _fileSystem.File.WriteAllText(csProjPath, builder.ToString()); IEnumerable <KeyValuePair <string, PackageVersion> > GetDependencies() { foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(assembly)) { yield return(dependency); } IEnumerable <KeyValuePair <string, PackageVersion> > GetDependenciesCore(DependencyRoot root) { if (root.Dependencies == null) { yield break; } foreach (var kvp in root.Dependencies) { yield return(kvp); foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(kvp.Value)) { yield return(dependency); } } } } } void SaveDependencyAnchorFile() { string anchorNamespace = $"{assembly.GetNativeNamespace()}.Internal.DependencyResolution"; var syntaxTree = SF.SyntaxTree( SF.CompilationUnit( SF.List <ExternAliasDirectiveSyntax>(), SF.List <UsingDirectiveSyntax>(), SF.List <AttributeListSyntax>(), SF.List <MemberDeclarationSyntax>(new[] { SF.NamespaceDeclaration( SF.IdentifierName(anchorNamespace), SF.List <ExternAliasDirectiveSyntax>(), SF.List <UsingDirectiveSyntax>(), SF.List(new MemberDeclarationSyntax[] { GenerateDependencyAnchor() }) ) }) ).NormalizeWhitespace(elasticTrivia: true) ); string directory = GetNamespaceDirectory(packageOutputRoot, @anchorNamespace); SaveSyntaxTree(directory, "Anchor.cs", syntaxTree); ClassDeclarationSyntax GenerateDependencyAnchor() { return(SF.ClassDeclaration( SF.List <AttributeListSyntax>(), SF.TokenList(SF.Token(SyntaxKind.PublicKeyword)), SF.Identifier("Anchor"), null, null, SF.List <TypeParameterConstraintClauseSyntax>(), SF.List(new MemberDeclarationSyntax[] { SF.ConstructorDeclaration( SF.List <AttributeListSyntax>(), SF.TokenList(SF.Token(SyntaxKind.PublicKeyword)), SF.Identifier("Anchor"), SF.ParameterList(SF.SeparatedList <ParameterSyntax>()), null, SF.Block(SF.List(GenerateAnchorReferences())), null ) }) )); IEnumerable <StatementSyntax> GenerateAnchorReferences() { return(assembly.Dependencies?.Keys .Select(k => assembly.GetNativeNamespace(k)) .Select(n => $"{n}.Internal.DependencyResolution.Anchor") .Select(t => SF.ExpressionStatement(SF.ObjectCreationExpression( SF.Token(SyntaxKind.NewKeyword), SF.ParseTypeName(t), SF.ArgumentList(SF.SeparatedList <ArgumentSyntax>()), null ))) ?? Enumerable.Empty <StatementSyntax>()); } } } void SaveAssemblyInfo(string name, string version, string tarball) { SyntaxTree assemblyInfo = SF.SyntaxTree( SF.CompilationUnit( SF.List <ExternAliasDirectiveSyntax>(), SF.List(new[] { SF.UsingDirective(SF.ParseName("Amazon.JSII.Runtime.Deputy")) }), SF.List(new[] { SF.AttributeList( SF.AttributeTargetSpecifier( SF.Identifier("assembly"), SF.Token(SyntaxKind.ColonToken) ), SF.SeparatedList(new[] { SF.Attribute( SF.ParseName("JsiiAssembly"), SF.ParseAttributeArgumentList($"({SF.Literal(name)}, {SF.Literal(version)}, {SF.Literal(tarball)})") ) }) ) }), SF.List <MemberDeclarationSyntax>() ).NormalizeWhitespace(elasticTrivia: true) ); string assemblyInfoPath = Path.Combine(packageOutputRoot, "AssemblyInfo.cs"); _fileSystem.File.WriteAllText(assemblyInfoPath, assemblyInfo.ToString()); } void SaveType(Type type) { string @namespace = symbols.GetNamespace(type); string directory = GetNamespaceDirectory(packageOutputRoot, @namespace); switch (type.Kind) { case TypeKind.Class: { var classType = (ClassType)type; if (classType.IsAbstract) { SaveTypeFile($"{symbols.GetAbstractClassProxyName(classType)}.cs", new AbstractClassProxyGenerator(assembly.Name, classType, symbols).CreateSyntaxTree()); } SaveTypeFile($"{symbols.GetName(type)}.cs", new ClassGenerator(assembly.Name, classType, symbols).CreateSyntaxTree()); return; } case TypeKind.Enum: { SaveTypeFile($"{symbols.GetName(type)}.cs", new EnumGenerator(assembly.Name, (EnumType)type, symbols).CreateSyntaxTree()); return; } case TypeKind.Interface: { InterfaceType interfaceType = (InterfaceType)type; SaveTypeFile($"{symbols.GetName(interfaceType)}.cs", new InterfaceGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); SaveTypeFile($"{symbols.GetInterfaceProxyName(interfaceType)}.cs", new InterfaceProxyGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); if (interfaceType.IsDataType) { SaveTypeFile($"{symbols.GetInterfaceDefaultName(interfaceType)}.cs", new InterfaceDefaultGenerator(assembly.Name, interfaceType, symbols) .CreateSyntaxTree()); } return; } default: { throw new ArgumentException($"Unkown type kind: {type.Kind}", nameof(type)); } } void SaveTypeFile(string filename, SyntaxTree syntaxTree) { SaveSyntaxTree(directory, filename, syntaxTree); } } void SaveSyntaxTree(string directory, string filename, SyntaxTree syntaxTree) { if (!_fileSystem.Directory.Exists(directory)) { _fileSystem.Directory.CreateDirectory(directory); } _fileSystem.File.WriteAllText( Path.Combine(directory, filename), syntaxTree.ToString() ); } }
private static MemberDeclarationSyntax GenerateConstructor(string className, List <FieldInfoMember> fields) { var body = new List <StatementSyntax>(); Expression <Action <TypeInfo> > getField = _ => _.GetField(string.Empty, BindingFlags.Default); Expression <Action <Type> > getTypeInfo = _ => _.GetTypeInfo(); 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(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)); 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.GetTypeInfo().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())); }
IEnumerable <MemberDeclarationSyntax> CreateConstructors() { SyntaxToken typeName = Symbols.GetNameSyntaxToken(Type); if (Type.Initializer != null) { yield return(SF.ConstructorDeclaration ( SF.List <AttributeListSyntax>(), SF.TokenList(SF.Token( Type.IsAbstract || Type.Initializer.IsProtected ? SyntaxKind.ProtectedKeyword : SyntaxKind.PublicKeyword )), typeName, Type.Initializer.GetParameterListSyntax(Namespaces, Symbols), SF.ConstructorInitializer ( SyntaxKind.BaseConstructorInitializer, SF.ArgumentList( SF.SeparatedList(new[] { SF.Argument( SF.ObjectCreationExpression( SF.Token(SyntaxKind.NewKeyword), SF.ParseTypeName("DeputyProps"), SF.ArgumentList(SF.SeparatedList( new[] { GetBaseArgument() } )), null ) ) }) ) ), SF.Block(), null )); } yield return(SF.ConstructorDeclaration ( SF.List <AttributeListSyntax>(), SF.TokenList(SF.Token(SyntaxKind.ProtectedKeyword)), typeName, SF.ParseParameterList("(ByRefValue reference)"), SF.ConstructorInitializer ( SyntaxKind.BaseConstructorInitializer, SF.ParseArgumentList("(reference)") ), SF.Block(), null )); // This constructor allows child classes to supply their own parameter lists. It is always protected. yield return(SF.ConstructorDeclaration ( SF.List <AttributeListSyntax>(), SF.TokenList(SF.Token(SyntaxKind.ProtectedKeyword)), typeName, SF.ParseParameterList("(DeputyProps props)"), SF.ConstructorInitializer ( SyntaxKind.BaseConstructorInitializer, SF.ParseArgumentList("(props)") ), SF.Block(), null )); ArgumentSyntax GetBaseArgument() { var deputyArguments = (Type.Initializer.Parameters ?? Enumerable.Empty <Parameter>()) .Select(p => Symbols.GetNameSyntaxToken(p)) .Select(i => SF.IdentifierName(i)); // In C#, arrays of reference types are covariant. Because of this, passing a string[] // to a method that takes `params object[] args` will interperet the string array *as* // args, rather than as args' first element. To workaround with, we remove the params // keyword from DeputyBase's constructor, and always explicitly create an array of // objects when calling it. return(SF.Argument( SF.ArrayCreationExpression( SF.Token(SyntaxKind.NewKeyword), SF.ArrayType(SF.ParseTypeName("object[]")), SF.InitializerExpression( SyntaxKind.ArrayInitializerExpression, SF.SeparatedList <ExpressionSyntax>(deputyArguments) ) ) )); } }
public static byte[] CreateControllerCode(IService service) { var @file = SF.CompilationUnit(); var @namespace = SF.NamespaceDeclaration(SF.ParseName("MBase.ServiceHost.Controllers")).NormalizeWhitespace(); @file = @file .AddUsings(SF.UsingDirective(SF.IdentifierName("System"))); @file = @file .AddUsings(SF.UsingDirective(SF.IdentifierName("Microsoft.AspNetCore.Mvc"))); @file = @file .AddUsings(SF.UsingDirective(SF.IdentifierName("System.Threading.Tasks"))); @file = @file.AddUsings(SF.UsingDirective(SF.IdentifierName(service.GetType().Namespace))); @file = @file.AddUsings(SF.UsingDirective(SF.IdentifierName(service.GetType().Namespace + ".Models"))); foreach (var item in service.Commands.Where(m => typeof(ICommand).IsAssignableFrom(m.GetType()))) { @file = @file.AddUsings(SF.UsingDirective(SF.IdentifierName(item.GetType().Namespace))); } var classDeclaration = SF.ClassDeclaration(service.GetType().Name.ToString() + "Controller") .AddModifiers(SF.Token(SyntaxKind.PublicKeyword)) .AddBaseListTypes(SF.SimpleBaseType(SF.ParseTypeName("ControllerBase"))) .WithAttributeLists( SF.List( new AttributeListSyntax[] { SF.AttributeList( SF.SingletonSeparatedList( SF.Attribute(SF.IdentifierName("Route")) .WithArgumentList( SF.AttributeArgumentList( SF.SingletonSeparatedList( SF.AttributeArgument( SF.LiteralExpression(SyntaxKind.StringLiteralExpression, SF.Literal($"api/[controller]")))))))), SF.AttributeList( SF.SingletonSeparatedList( SF.Attribute(SF.IdentifierName("ApiController")))) })); List <MemberDeclarationSyntax> controllerMembers = new List <MemberDeclarationSyntax>(); controllerMembers.Add( SF.FieldDeclaration( SF.VariableDeclaration( SF.ParseTypeName(service.GetType().Name)) .AddVariables(SF.VariableDeclarator("_service"))) .AddModifiers(SF.Token(SyntaxKind.PrivateKeyword))); controllerMembers.Add( SF.ConstructorDeclaration(service.GetType().Name.ToString() + "Controller") .WithParameterList( SF.ParameterList( SF.SingletonSeparatedList( SF.Parameter( SF.Identifier("service")) .WithType( SF.IdentifierName("IService"))) )) .AddModifiers(SF.Token(SyntaxKind.PublicKeyword)) .WithBody(SF.Block(SF.ParseStatement($"this._service = ({service.GetType().Name})service;")))); foreach (var item in service.Commands.Where(m => typeof(ICommand).IsAssignableFrom(m.GetType()))) { var syntax = @$ " var response = await CommandHelper.ExecuteMethod<{item.Name}>(new {item.Name}(),new Request<{item.Name}>(request, new MessageEnvelope()));