Add attributes to namespaces

Fix builders with empty attributes
This commit is contained in:
2024-04-10 15:15:47 +02:00
parent 975ab883fd
commit df191bf053
8 changed files with 89 additions and 49 deletions
+45 -42
View File
@@ -8,59 +8,62 @@ Sybil supports building of namespaces with classes, constructors, parameters, pr
Example of creating a namespace with one class with one constructor and base class, multiple fields, properties and methods:
```C#
var namespaceSyntax = SyntaxBuilder.CreateNamespace("TestNamespace")
.WithUsing("System")
.WithClass(
SyntaxBuilder.CreateClass("TestClass")
.WithBaseClass("BaseTestClass")
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute")
.WithArgument("SomeIntProperty", 1)
.WithArgument("SomeStringProperty", "Hello")
.WithArgument("SomeEnumProperty", MyEnum.Value)
.WithArgument("SomeTypeProperty", typeof(string))
.WithNullArgument("SomeNullProperty"))
.WithModifiers("public sealed")
.WithConstructor(
SyntaxBuilder.CreateConstructor("TestClass")
.WithBase(
SyntaxBuilder.CreateBaseConstructor()
.WithArgument("fieldString"))
.WithAttribute(
SyntaxBuilder.CreateAttribute("SomeAttribute5")
.WithNullArgument())
.WithParameter("string", "fieldString")
.WithBody("this.fieldString = fieldString ?? throw new ArgumentNullException();"))
.WithField(
SyntaxBuilder.CreateField("string", "fieldString")
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute2"))
.WithAttribute(SyntaxBuilder.CreateAttribute("InternalsVisibleTo")
.WithArgument("FlowTests"))
.WithUsing("System")
.WithClass(
SyntaxBuilder.CreateClass("TestClass")
.WithBaseClass("BaseTestClass")
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute")
.WithArgument("SomeIntProperty", 1)
.WithArgument("SomeStringProperty", "Hello")
.WithArgument("SomeEnumProperty", MyEnum.Value)
.WithArgument("SomeTypeProperty", typeof(string))
.WithNullArgument("SomeNullProperty"))
.WithModifiers("public sealed")
.WithConstructor(
SyntaxBuilder.CreateConstructor("TestClass")
.WithBase(
SyntaxBuilder.CreateBaseConstructor()
.WithArgument("fieldString"))
.WithAttribute(
SyntaxBuilder.CreateAttribute("SomeAttribute5")
.WithNullArgument())
.WithParameter("string", "fieldString")
.WithBody("this.fieldString = fieldString ?? throw new ArgumentNullException();"))
.WithField(
SyntaxBuilder.CreateField("string", "fieldString")
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute2"))
.WithModifier("private"))
.WithProperty(
SyntaxBuilder.CreateProperty("string", "PropertyString")
.WithModifier("public")
.WithAccessor(
SyntaxBuilder.CreateSetter()
.WithModifier("private"))
.WithProperty(
SyntaxBuilder.CreateProperty("string", "PropertyString")
.WithModifier("public")
.WithAccessor(
SyntaxBuilder.CreateSetter()
.WithModifier("private"))
.WithAccessor(
SyntaxBuilder.CreateGetter())
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute3")
.WithArgument(typeof(string))))
.WithMethod(
SyntaxBuilder.CreateMethod("string", "GetFieldString")
.WithModifier("public")
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute4")
.WithArgument(0.5f))
.WithBody("return this.fieldString;")))
.Build();
.WithAccessor(
SyntaxBuilder.CreateGetter())
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute3")
.WithArgument(typeof(string))))
.WithMethod(
SyntaxBuilder.CreateMethod("string", "GetFieldString")
.WithModifier("public")
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute4")
.WithArgument(0.5f))
.WithBody("return this.fieldString;")))
.Build();
var namespaceString = namespaceSyntax.ToFullString();
```
This generates the following syntax:
```C#
[InternalsVisibleTo(""FlowTests"")]
namespace TestNamespace
{
using System;
[SomeAttribute(SomeIntProperty = 1, SomeStringProperty = "Hello", SomeEnumProperty = MyEnum.Value, SomeTypeProperty = typeof(String), SomeNullProperty = null)]
[SomeAttribute(SomeIntProperty = 1, SomeStringProperty = ""Hello"", SomeEnumProperty = MyEnum.Value, SomeTypeProperty = typeof(String), SomeNullProperty = null)]
public sealed class TestClass : BaseTestClass
{
[SomeAttribute5(null)]
+4 -1
View File
@@ -8,7 +8,8 @@ namespace Sybil.IntegrationTests;
public sealed class FlowTests
{
private const string ExpectedNamespace =
@"namespace TestNamespace
@"[InternalsVisibleTo(""FlowTests"")]
namespace TestNamespace
{
using System;
@@ -38,6 +39,8 @@ public sealed class FlowTests
public void NewNamespace_GeneratesExpected()
{
var namespaceSyntax = SyntaxBuilder.CreateNamespace("TestNamespace")
.WithAttribute(SyntaxBuilder.CreateAttribute("InternalsVisibleTo")
.WithArgument("FlowTests"))
.WithUsing("System")
.WithClass(
SyntaxBuilder.CreateClass("TestClass")
+5 -1
View File
@@ -90,8 +90,12 @@ namespace Sybil
public ClassDeclarationSyntax Build()
{
if (this.Attributes.Count > 0)
{
this.ClassDeclaration = this.ClassDeclaration.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.Attributes.Select(p => p.Build()).ToArray())));
}
return this.ClassDeclaration
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.Attributes.Select(p => p.Build()).ToArray())))
.AddMembers(this.Constructors.Select(p => p.Build()).ToArray())
.AddMembers(this.Fields.Select(p => p.Build()).ToArray())
.AddMembers(this.Properties.Select(p => p.Build()).ToArray())
+5 -1
View File
@@ -97,8 +97,12 @@ namespace Sybil
this.ConstructorDeclarationSyntax = this.ConstructorDeclarationSyntax.WithInitializer(this.baseConstructorBuilder.Build());
}
if (this.attributes.Count > 0)
{
this.ConstructorDeclarationSyntax = this.ConstructorDeclarationSyntax.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributes.Select(p => p.Build()).ToArray())));
}
return this.ConstructorDeclarationSyntax
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributes.Select(p => p.Build()).ToArray())))
.NormalizeWhitespace();
}
}
+5 -1
View File
@@ -52,8 +52,12 @@ namespace Sybil
public FieldDeclarationSyntax Build()
{
if (this.attributeBuilders.Count > 0)
{
this.FieldDeclarationSyntax = this.FieldDeclarationSyntax.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributeBuilders.Select(p => p.Build()).ToArray())));
}
return this.FieldDeclarationSyntax
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributeBuilders.Select(p => p.Build()).ToArray())))
.NormalizeWhitespace();
}
}
+5 -2
View File
@@ -112,16 +112,19 @@ namespace Sybil
public MethodDeclarationSyntax Build()
{
if (this.attributeBuilders.Count > 0)
{
this.MethodDeclarationSyntax = this.MethodDeclarationSyntax.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributeBuilders.Select(p => p.Build()).ToArray())));
}
if (this.BlockBody is null is false)
{
return this.MethodDeclarationSyntax
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributeBuilders.Select(p => p.Build()).ToArray())))
.WithBody(this.BlockBody)
.NormalizeWhitespace();
}
return this.MethodDeclarationSyntax
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributeBuilders.Select(p => p.Build()).ToArray())))
.WithExpressionBody(this.ArrowExpression)
.NormalizeWhitespace();
}
+15
View File
@@ -9,6 +9,7 @@ namespace Sybil
{
public sealed class NamespaceBuilder : IBuilder<NamespaceDeclarationSyntax>
{
private readonly List<AttributeBuilder> attributeBuilders = new List<AttributeBuilder>();
private readonly List<ClassBuilder> classBuilders = new List<ClassBuilder>();
private NamespaceDeclarationSyntax NamespaceDeclaration { get; set; }
@@ -38,8 +39,22 @@ namespace Sybil
return this;
}
public NamespaceBuilder WithAttribute(AttributeBuilder attributeBuilder)
{
_ = attributeBuilder ?? throw new ArgumentNullException(nameof(attributeBuilder));
this.attributeBuilders.Add(attributeBuilder);
return this;
}
public NamespaceDeclarationSyntax Build()
{
if (this.attributeBuilders.Count > 0)
{
this.NamespaceDeclaration = this.NamespaceDeclaration.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributeBuilders.Select(p => p.Build()).ToArray())));
}
return this.NamespaceDeclaration
.AddMembers(this.classBuilders.Select(c => c.Build()).ToArray())
.NormalizeWhitespace();
+5 -1
View File
@@ -60,9 +60,13 @@ namespace Sybil
public PropertyDeclarationSyntax Build()
{
if (this.attributes.Count > 0)
{
this.PropertyDeclarationSyntax = this.PropertyDeclarationSyntax.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributes.Select(p => p.Build()).ToArray())));
}
return this.PropertyDeclarationSyntax
.WithAccessorList(this.BuildAccessorList())
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(this.attributes.Select(p => p.Build()).ToArray())))
.NormalizeWhitespace();
}