diff --git a/Sybil.IntegrationTests/FlowTests.cs b/Sybil.IntegrationTests/FlowTests.cs
new file mode 100644
index 0000000..8cae339
--- /dev/null
+++ b/Sybil.IntegrationTests/FlowTests.cs
@@ -0,0 +1,67 @@
+using FluentAssertions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Sybil.IntegrationTests
+{
+ [TestClass]
+ public sealed class FlowTests
+ {
+ private const string ExpectedNamespace =
+@"namespace TestNamespace
+{
+ using System;
+
+ public sealed class TestClass
+ {
+ TestClass(string fieldString) : base(fieldString)
+ {
+ this.fieldString = fieldString ?? throw new ArgumentNullException();
+ }
+
+ private string fieldString;
+ public string PropertyString { private set; get; }
+
+ public string GetFieldString()
+ {
+ return this.fieldString;
+ }
+ }
+}";
+
+ [TestMethod]
+ public void NewNamespace_GeneratesExpected()
+ {
+ var namespaceSyntax = SyntaxBuilder.CreateNamespace("TestNamespace")
+ .WithUsing("System")
+ .WithClass(
+ SyntaxBuilder.CreateClass("TestClass")
+ .WithModifiers("public sealed")
+ .WithConstructor(
+ SyntaxBuilder.CreateConstructor("TestClass")
+ .WithBase(
+ SyntaxBuilder.CreateBaseConstructor()
+ .WithArgument("fieldString"))
+ .WithParameter("string", "fieldString")
+ .WithBody("this.fieldString = fieldString ?? throw new ArgumentNullException();"))
+ .WithField(
+ SyntaxBuilder.CreateField("string", "fieldString")
+ .WithModifier("private"))
+ .WithProperty(
+ SyntaxBuilder.CreateProperty("string", "PropertyString")
+ .WithModifier("public")
+ .WithAccessor(
+ SyntaxBuilder.CreateSetter()
+ .WithModifier("private"))
+ .WithAccessor(
+ SyntaxBuilder.CreateGetter()))
+ .WithMethod(
+ SyntaxBuilder.CreateMethod("string", "GetFieldString")
+ .WithModifier("public")
+ .WithBody("return this.fieldString;")))
+ .Build();
+
+ var namespaceString = namespaceSyntax.ToFullString();
+ namespaceString.Should().Be(ExpectedNamespace);
+ }
+ }
+}
diff --git a/Sybil.IntegrationTests/Sybil.IntegrationTests.csproj b/Sybil.IntegrationTests/Sybil.IntegrationTests.csproj
new file mode 100644
index 0000000..f2037c1
--- /dev/null
+++ b/Sybil.IntegrationTests/Sybil.IntegrationTests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net6.0
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Sybil.UnitTests/Sybil.UnitTests.csproj b/Sybil.UnitTests/Sybil.UnitTests.csproj
index f72bee8..1982f8c 100644
--- a/Sybil.UnitTests/Sybil.UnitTests.csproj
+++ b/Sybil.UnitTests/Sybil.UnitTests.csproj
@@ -8,10 +8,18 @@
-
-
-
-
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
diff --git a/Sybil.sln b/Sybil.sln
index 22dbd5e..0b2ce68 100644
--- a/Sybil.sln
+++ b/Sybil.sln
@@ -3,9 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32228.430
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sybil", "Sybil\Sybil.csproj", "{5B024A18-C109-4CED-8952-B1793EC634CD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sybil", "Sybil\Sybil.csproj", "{5B024A18-C109-4CED-8952-B1793EC634CD}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sybil.UnitTests", "Sybil.UnitTests\Sybil.UnitTests.csproj", "{458625E9-7427-47C6-BEE9-6269BDA00282}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sybil.UnitTests", "Sybil.UnitTests\Sybil.UnitTests.csproj", "{458625E9-7427-47C6-BEE9-6269BDA00282}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sybil.IntegrationTests", "Sybil.IntegrationTests\Sybil.IntegrationTests.csproj", "{4BE3F7BF-602C-447E-B29B-011AE7274E4A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +23,10 @@ Global
{458625E9-7427-47C6-BEE9-6269BDA00282}.Debug|Any CPU.Build.0 = Debug|Any CPU
{458625E9-7427-47C6-BEE9-6269BDA00282}.Release|Any CPU.ActiveCfg = Release|Any CPU
{458625E9-7427-47C6-BEE9-6269BDA00282}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4BE3F7BF-602C-447E-B29B-011AE7274E4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4BE3F7BF-602C-447E-B29B-011AE7274E4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4BE3F7BF-602C-447E-B29B-011AE7274E4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4BE3F7BF-602C-447E-B29B-011AE7274E4A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Sybil/AccessorBuilder.cs b/Sybil/AccessorBuilder.cs
new file mode 100644
index 0000000..9ff078a
--- /dev/null
+++ b/Sybil/AccessorBuilder.cs
@@ -0,0 +1,79 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+
+namespace Sybil
+{
+ public sealed class AccessorBuilder : IBuilder
+ {
+ private readonly SyntaxKind accessor;
+
+ private SyntaxTokenList Modifiers { get; set; }
+ private BlockSyntax BlockSyntax { get; set; }
+ private ArrowExpressionClauseSyntax ArrowExpressionClauseSyntax { get; set; }
+
+ internal AccessorBuilder(
+ SyntaxKind accessor)
+ {
+ this.accessor = accessor;
+ }
+
+ public AccessorBuilder WithModifier(string modifier)
+ {
+ _ = string.IsNullOrWhiteSpace(modifier) ? throw new ArgumentNullException(nameof(modifier)) : modifier;
+
+ this.Modifiers = SyntaxFactory.TokenList(SyntaxFactory.ParseToken(modifier));
+
+ return this;
+ }
+ public AccessorBuilder WithModifiers(string modifiers)
+ {
+ _ = string.IsNullOrWhiteSpace(modifiers) ? throw new ArgumentNullException(nameof(modifiers)) : modifiers;
+
+ this.Modifiers = SyntaxFactory.TokenList(SyntaxFactory.ParseTokens(modifiers));
+
+ return this;
+ }
+ public AccessorBuilder WithBody(string body)
+ {
+ _ = string.IsNullOrWhiteSpace(body) ? throw new ArgumentNullException(nameof(body)) : body;
+
+ this.ArrowExpressionClauseSyntax = null;
+ this.BlockSyntax = SyntaxFactory.Block(SyntaxFactory.ParseStatement(body));
+
+ return this;
+ }
+ public AccessorBuilder WithArrowExpression(string expression)
+ {
+ _ = string.IsNullOrWhiteSpace(expression) ? throw new ArgumentNullException(nameof(expression)) : expression;
+
+ this.BlockSyntax = null;
+ this.ArrowExpressionClauseSyntax = SyntaxFactory.ArrowExpressionClause(SyntaxFactory.ParseExpression(expression));
+
+ return this;
+ }
+
+ public AccessorDeclarationSyntax Build()
+ {
+ return this.BuildAccessorDeclaration().NormalizeWhitespace();
+ }
+
+ private AccessorDeclarationSyntax BuildAccessorDeclaration()
+ {
+ var accessorDeclaration = SyntaxFactory.AccessorDeclaration(
+ kind: this.accessor,
+ attributeLists: SyntaxFactory.List(),
+ modifiers: this.Modifiers,
+ body: this.BlockSyntax,
+ expressionBody: this.ArrowExpressionClauseSyntax);
+
+ if (this.BlockSyntax is null && this.ArrowExpressionClauseSyntax is null)
+ {
+ accessorDeclaration = accessorDeclaration.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));
+ }
+
+ return accessorDeclaration;
+ }
+ }
+}
diff --git a/Sybil/BaseConstructorBuilder.cs b/Sybil/BaseConstructorBuilder.cs
new file mode 100644
index 0000000..5841d11
--- /dev/null
+++ b/Sybil/BaseConstructorBuilder.cs
@@ -0,0 +1,31 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+
+namespace Sybil
+{
+ public sealed class BaseConstructorBuilder : IBuilder
+ {
+ private ConstructorInitializerSyntax ConstructorInitializerSyntax { get; set; }
+
+ internal BaseConstructorBuilder()
+ {
+ this.ConstructorInitializerSyntax = SyntaxFactory.ConstructorInitializer(SyntaxKind.BaseConstructorInitializer);
+ }
+
+ public BaseConstructorBuilder WithArgument(string argumentName)
+ {
+ _ = string.IsNullOrWhiteSpace(argumentName) ? throw new ArgumentNullException(nameof(argumentName)) : argumentName;
+
+ this.ConstructorInitializerSyntax = this.ConstructorInitializerSyntax.AddArgumentListArguments(SyntaxFactory.Argument(SyntaxFactory.IdentifierName(argumentName)));
+
+ return this;
+ }
+
+ public ConstructorInitializerSyntax Build()
+ {
+ return ConstructorInitializerSyntax.NormalizeWhitespace();
+ }
+ }
+}
diff --git a/Sybil/ClassBuilder.cs b/Sybil/ClassBuilder.cs
new file mode 100644
index 0000000..0a64114
--- /dev/null
+++ b/Sybil/ClassBuilder.cs
@@ -0,0 +1,85 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Sybil
+{
+ public sealed class ClassBuilder : IBuilder
+ {
+ private readonly string className;
+ private ClassDeclarationSyntax ClassDeclaration { get; set; }
+
+ private readonly List Constructors = new List();
+ private readonly List Fields = new List();
+ private readonly List Properties = new List();
+ private readonly List Methods = new List();
+
+ internal ClassBuilder(
+ string className)
+ {
+ _ = string.IsNullOrWhiteSpace(className) ? throw new ArgumentNullException(nameof(className)) : className;
+
+ this.className = className;
+ this.ClassDeclaration = SyntaxFactory.ClassDeclaration(className);
+ }
+
+ public ClassBuilder WithModifier(string modifier)
+ {
+ _ = string.IsNullOrWhiteSpace(modifier) ? throw new ArgumentNullException(nameof(modifier)) : modifier;
+
+ this.ClassDeclaration = this.ClassDeclaration.AddModifiers(SyntaxFactory.ParseToken(modifier));
+
+ return this;
+ }
+
+ public ClassBuilder WithModifiers(string modifiers)
+ {
+ _ = string.IsNullOrWhiteSpace(modifiers) ? throw new ArgumentNullException(nameof(modifiers)) : modifiers;
+
+ this.ClassDeclaration = this.ClassDeclaration.AddModifiers(SyntaxFactory.ParseTokens(modifiers).ToArray());
+
+ return this;
+ }
+
+ public ClassBuilder WithField(FieldBuilder fieldBuilder)
+ {
+ this.Fields.Add(fieldBuilder ?? throw new ArgumentNullException(nameof(fieldBuilder)));
+
+ return this;
+ }
+
+ public ClassBuilder WithProperty(PropertyBuilder propertyBuilder)
+ {
+ this.Properties.Add(propertyBuilder ?? throw new ArgumentNullException(nameof(propertyBuilder)));
+
+ return this;
+ }
+
+ public ClassBuilder WithMethod(MethodBuilder methodBuilder)
+ {
+ this.Methods.Add(methodBuilder ?? throw new ArgumentNullException(nameof(methodBuilder)));
+
+ return this;
+ }
+
+ public ClassBuilder WithConstructor(ConstructorBuilder constructorBuilder)
+ {
+ this.Constructors.Add(constructorBuilder ?? throw new ArgumentNullException(nameof(constructorBuilder)));
+
+ return this;
+ }
+
+ public ClassDeclarationSyntax Build()
+ {
+ return this.ClassDeclaration
+ .AddMembers(this.Constructors.Select(p => p.Build()).ToArray())
+ .AddMembers(this.Fields.Select(p => p.Build()).ToArray())
+ .AddMembers(this.Properties.Select(p => p.Build()).ToArray())
+ .AddMembers(this.Methods.Select(p => p.Build()).ToArray())
+ .NormalizeWhitespace();
+ }
+ }
+}
diff --git a/Sybil/ConstructorBuilder.cs b/Sybil/ConstructorBuilder.cs
new file mode 100644
index 0000000..8e7ce09
--- /dev/null
+++ b/Sybil/ConstructorBuilder.cs
@@ -0,0 +1,86 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+using System.Linq;
+
+namespace Sybil
+{
+ public sealed class ConstructorBuilder : IBuilder
+ {
+ private BaseConstructorBuilder baseConstructorBuilder;
+
+ private ConstructorDeclarationSyntax ConstructorDeclarationSyntax { get; set; }
+
+ internal ConstructorBuilder(
+ string className)
+ {
+ _ = string.IsNullOrWhiteSpace(className) ? throw new ArgumentNullException(nameof(className)) : className;
+
+ this.ConstructorDeclarationSyntax = SyntaxFactory.ConstructorDeclaration(className);
+ this.ConstructorDeclarationSyntax = this.ConstructorDeclarationSyntax.WithBody(SyntaxFactory.Block());
+ }
+
+ public ConstructorBuilder WithBase(BaseConstructorBuilder baseConstructorBuilder)
+ {
+ this.baseConstructorBuilder = baseConstructorBuilder;
+ return this;
+ }
+ public ConstructorBuilder WithModifiers(string modifiers)
+ {
+ _ = string.IsNullOrWhiteSpace(modifiers) ? throw new ArgumentNullException(nameof(modifiers)) : modifiers;
+
+ this.ConstructorDeclarationSyntax = this.ConstructorDeclarationSyntax.AddModifiers(SyntaxFactory.ParseTokens(modifiers).ToArray());
+
+ return this;
+ }
+ public ConstructorBuilder WithModifier(string modifier)
+ {
+ _ = string.IsNullOrWhiteSpace(modifier) ? throw new ArgumentNullException(nameof(modifier)) : modifier;
+
+ this.ConstructorDeclarationSyntax = this.ConstructorDeclarationSyntax.AddModifiers(SyntaxFactory.ParseToken(modifier));
+
+ return this;
+ }
+ public ConstructorBuilder WithParameter(string parameterType, string parameterName, string defaultValue = null)
+ {
+ _ = string.IsNullOrWhiteSpace(parameterName) ? throw new ArgumentNullException(nameof(parameterName)) : parameterName;
+ _ = string.IsNullOrWhiteSpace(parameterType) ? throw new ArgumentNullException(nameof(parameterType)) : parameterType;
+
+ EqualsValueClauseSyntax equalsValueClauseSyntax = null;
+ if (string.IsNullOrWhiteSpace(defaultValue) is false)
+ {
+ equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(
+ SyntaxFactory.ParseExpression(defaultValue));
+ }
+
+ var parameter = SyntaxFactory.Parameter(
+ new SyntaxList(),
+ new SyntaxTokenList(),
+ SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(parameterType)),
+ SyntaxFactory.Identifier(parameterName),
+ equalsValueClauseSyntax);
+ this.ConstructorDeclarationSyntax = this.ConstructorDeclarationSyntax.AddParameterListParameters(parameter);
+
+ return this;
+ }
+ public ConstructorBuilder WithBody(string body)
+ {
+ _ = string.IsNullOrWhiteSpace(body) ? throw new ArgumentNullException(nameof(body)) : body;
+
+ this.ConstructorDeclarationSyntax = this.ConstructorDeclarationSyntax.WithBody(SyntaxFactory.Block(SyntaxFactory.ParseStatement(body)));
+
+ return this;
+ }
+
+ public ConstructorDeclarationSyntax Build()
+ {
+ if (this.baseConstructorBuilder is null is false)
+ {
+ this.ConstructorDeclarationSyntax = this.ConstructorDeclarationSyntax.WithInitializer(this.baseConstructorBuilder.Build());
+ }
+
+ return this.ConstructorDeclarationSyntax.NormalizeWhitespace();
+ }
+ }
+}
diff --git a/Sybil/FieldBuilder.cs b/Sybil/FieldBuilder.cs
new file mode 100644
index 0000000..959a622
--- /dev/null
+++ b/Sybil/FieldBuilder.cs
@@ -0,0 +1,48 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+using System.Linq;
+
+namespace Sybil
+{
+ public sealed class FieldBuilder : IBuilder
+ {
+ private FieldDeclarationSyntax FieldDeclarationSyntax { get; set; }
+
+ internal FieldBuilder(
+ string fieldType,
+ string fieldName)
+ {
+ _ = string.IsNullOrWhiteSpace(fieldType) ? throw new ArgumentNullException(nameof(fieldType)) : fieldType;
+ _ = string.IsNullOrWhiteSpace(fieldName) ? throw new ArgumentNullException(nameof(fieldName)) : fieldName;
+
+ var variableDeclaration = SyntaxFactory.VariableDeclaration(
+ SyntaxFactory.ParseTypeName(fieldType))
+ .AddVariables(SyntaxFactory.VariableDeclarator(fieldName));
+ this.FieldDeclarationSyntax = SyntaxFactory.FieldDeclaration(variableDeclaration);
+ }
+
+ public FieldBuilder WithModifier(string modifier)
+ {
+ _ = string.IsNullOrWhiteSpace(modifier) ? throw new ArgumentNullException(nameof(modifier)) : modifier;
+
+ this.FieldDeclarationSyntax = this.FieldDeclarationSyntax.AddModifiers(SyntaxFactory.ParseToken(modifier));
+
+ return this;
+ }
+ public FieldBuilder WithModifiers(string modifiers)
+ {
+ _ = string.IsNullOrWhiteSpace(modifiers) ? throw new ArgumentNullException(nameof(modifiers)) : modifiers;
+
+ this.FieldDeclarationSyntax = this.FieldDeclarationSyntax.AddModifiers(SyntaxFactory.ParseTokens(modifiers).ToArray());
+
+ return this;
+ }
+
+ public FieldDeclarationSyntax Build()
+ {
+ return this.FieldDeclarationSyntax.NormalizeWhitespace();
+ }
+ }
+}
diff --git a/Sybil/IBuilder.cs b/Sybil/IBuilder.cs
new file mode 100644
index 0000000..eb8620b
--- /dev/null
+++ b/Sybil/IBuilder.cs
@@ -0,0 +1,9 @@
+using Microsoft.CodeAnalysis.CSharp;
+
+namespace Sybil
+{
+ public interface IBuilder where T : CSharpSyntaxNode
+ {
+ T Build();
+ }
+}
diff --git a/Sybil/MethodBuilder.cs b/Sybil/MethodBuilder.cs
new file mode 100644
index 0000000..be10508
--- /dev/null
+++ b/Sybil/MethodBuilder.cs
@@ -0,0 +1,97 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+using System.Linq;
+
+namespace Sybil
+{
+ public sealed class MethodBuilder : IBuilder
+ {
+ private BlockSyntax BlockBody { get; set; }
+ private ArrowExpressionClauseSyntax ArrowExpression { get; set; }
+ private MethodDeclarationSyntax MethodDeclarationSyntax { get; set; }
+
+ internal MethodBuilder(
+ string returnType, string name)
+ {
+ _ = string.IsNullOrWhiteSpace(returnType) ? throw new ArgumentNullException(nameof(returnType)) : returnType;
+ _ = string.IsNullOrWhiteSpace(name) ? throw new ArgumentNullException(nameof(name)) : name;
+
+ this.MethodDeclarationSyntax = SyntaxFactory.MethodDeclaration(SyntaxFactory.ParseTypeName(returnType), SyntaxFactory.ParseToken(name));
+ this.ArrowExpression = SyntaxFactory.ArrowExpressionClause(
+ SyntaxFactory.ParseExpression("throw new NotImplementedException();"));
+ }
+
+ public MethodBuilder WithModifier(string modifier)
+ {
+ _ = string.IsNullOrWhiteSpace(modifier) ? throw new ArgumentNullException(nameof(modifier)) : modifier;
+
+ this.MethodDeclarationSyntax = this.MethodDeclarationSyntax.AddModifiers(SyntaxFactory.ParseToken(modifier));
+
+ return this;
+ }
+ public MethodBuilder WithModifiers(string modifiers)
+ {
+ _ = string.IsNullOrWhiteSpace(modifiers) ? throw new ArgumentNullException(nameof(modifiers)) : modifiers;
+
+ this.MethodDeclarationSyntax = this.MethodDeclarationSyntax.AddModifiers(SyntaxFactory.ParseTokens(modifiers).ToArray());
+
+ return this;
+ }
+ public MethodBuilder WithParameter(string parameterType, string parameterName, string defaultValue = null)
+ {
+ _ = string.IsNullOrWhiteSpace(parameterName) ? throw new ArgumentNullException(nameof(parameterName)) : parameterName;
+ _ = string.IsNullOrWhiteSpace(parameterType) ? throw new ArgumentNullException(nameof(parameterType)) : parameterType;
+
+ EqualsValueClauseSyntax equalsValueClauseSyntax = null;
+ if (string.IsNullOrWhiteSpace(defaultValue) is false)
+ {
+ equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(
+ SyntaxFactory.ParseExpression(defaultValue));
+ }
+
+ var parameter = SyntaxFactory.Parameter(
+ SyntaxFactory.List(),
+ new SyntaxTokenList(),
+ type: SyntaxFactory.ParseTypeName(parameterType),
+ identifier: SyntaxFactory.ParseToken(parameterName),
+ @default: equalsValueClauseSyntax);
+
+ this.MethodDeclarationSyntax = this.MethodDeclarationSyntax.AddParameterListParameters(parameter);
+
+ return this;
+ }
+ public MethodBuilder WithBody(string body)
+ {
+ this.BlockBody = SyntaxFactory.Block(
+ SyntaxFactory.ParseStatement(body));
+ this.ArrowExpression = null;
+
+ return this;
+ }
+ public MethodBuilder WithExpression(string expression)
+ {
+ this.ArrowExpression = SyntaxFactory.ArrowExpressionClause(
+ SyntaxFactory.ParseExpression(expression));
+ this.BlockBody = null;
+
+ return this;
+ }
+
+ public MethodDeclarationSyntax Build()
+ {
+ if (this.BlockBody is null is false)
+ {
+ return this.MethodDeclarationSyntax.WithBody(this.BlockBody);
+ }
+
+ if (this.ArrowExpression is null is false)
+ {
+ return this.MethodDeclarationSyntax.WithExpressionBody(this.ArrowExpression);
+ }
+
+ return this.MethodDeclarationSyntax;
+ }
+ }
+}
diff --git a/Sybil/NamespaceBuilder.cs b/Sybil/NamespaceBuilder.cs
new file mode 100644
index 0000000..13c4a31
--- /dev/null
+++ b/Sybil/NamespaceBuilder.cs
@@ -0,0 +1,51 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Sybil
+{
+ public sealed class NamespaceBuilder : IBuilder
+ {
+ private readonly List classBuilders = new List();
+ private NamespaceDeclarationSyntax NamespaceDeclaration { get; set; }
+
+ internal NamespaceBuilder(
+ string @namespace)
+ {
+ _ = string.IsNullOrWhiteSpace(@namespace) ? throw new ArgumentNullException(nameof(@namespace)) : @namespace;
+
+ this.NamespaceDeclaration = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(@namespace));
+ }
+
+ public NamespaceBuilder WithUsing(string usingName)
+ {
+ _ = string.IsNullOrWhiteSpace(usingName) ? throw new ArgumentNullException(nameof(usingName)) : usingName;
+
+ this.NamespaceDeclaration = this.NamespaceDeclaration.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(usingName)));
+
+ return this;
+ }
+
+ public NamespaceBuilder WithClass(ClassBuilder classBuilder)
+ {
+ this.classBuilders.Add(classBuilder);
+
+ return this;
+ }
+
+ public NamespaceDeclarationSyntax Build()
+ {
+ return this.NamespaceDeclaration
+ .AddMembers(this.classBuilders.Select(c => c.Build()).ToArray())
+ .NormalizeWhitespace();
+ }
+
+ public static NamespaceBuilder Create(string @namespace)
+ {
+ return new NamespaceBuilder(@namespace);
+ }
+ }
+}
diff --git a/Sybil/PropertyBuilder.cs b/Sybil/PropertyBuilder.cs
new file mode 100644
index 0000000..29e4f1d
--- /dev/null
+++ b/Sybil/PropertyBuilder.cs
@@ -0,0 +1,62 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Sybil
+{
+ public sealed class PropertyBuilder : IBuilder
+ {
+ private readonly List accessors = new List();
+
+ private PropertyDeclarationSyntax PropertyDeclarationSyntax { get; set; }
+
+ internal PropertyBuilder(
+ string typeName,
+ string propertyName)
+ {
+ _ = string.IsNullOrWhiteSpace(typeName) ? throw new ArgumentNullException(nameof(typeName)) : typeName;
+ _ = string.IsNullOrWhiteSpace(propertyName) ? throw new ArgumentNullException(nameof(propertyName)) : propertyName;
+
+ this.PropertyDeclarationSyntax = SyntaxFactory.PropertyDeclaration(SyntaxFactory.ParseTypeName(typeName), propertyName);
+ }
+
+ public PropertyBuilder WithModifier(string modifier)
+ {
+ _ = string.IsNullOrWhiteSpace(modifier) ? throw new ArgumentNullException(nameof(modifier)) : modifier;
+
+ this.PropertyDeclarationSyntax = this.PropertyDeclarationSyntax.AddModifiers(SyntaxFactory.ParseToken(modifier));
+
+ return this;
+ }
+ public PropertyBuilder WithModifiers(string modifiers)
+ {
+ _ = string.IsNullOrWhiteSpace(modifiers) ? throw new ArgumentNullException(nameof(modifiers)) : modifiers;
+
+ this.PropertyDeclarationSyntax = this.PropertyDeclarationSyntax.AddModifiers(SyntaxFactory.ParseTokens(modifiers).ToArray());
+
+ return this;
+ }
+ public PropertyBuilder WithAccessor(AccessorBuilder accessorBuilder)
+ {
+ this.accessors.Add(accessorBuilder);
+
+ return this;
+ }
+
+ public PropertyDeclarationSyntax Build()
+ {
+ return this.PropertyDeclarationSyntax.WithAccessorList(this.BuildAccessorList()).NormalizeWhitespace();
+ }
+
+ private AccessorListSyntax BuildAccessorList()
+ {
+ return SyntaxFactory.AccessorList(
+ SyntaxFactory.Token(SyntaxKind.OpenBraceToken),
+ accessors: SyntaxFactory.List(this.accessors.Select(a => a.Build())),
+ SyntaxFactory.Token(SyntaxKind.CloseBraceToken));
+ }
+ }
+}
diff --git a/Sybil/Sybil.csproj b/Sybil/Sybil.csproj
index 3a54d8b..a20e7ff 100644
--- a/Sybil/Sybil.csproj
+++ b/Sybil/Sybil.csproj
@@ -1,4 +1,4 @@
-
+
netstandard2.0
@@ -7,12 +7,12 @@
https://github.com/AlexMacocian/Sybil
git
0.1
- C:\Users\Owner\source\repos\Sybil\LICENSE
- True
-
+
+ Always
+
True
\
diff --git a/Sybil/SyntaxBuilder.cs b/Sybil/SyntaxBuilder.cs
new file mode 100644
index 0000000..5522ab7
--- /dev/null
+++ b/Sybil/SyntaxBuilder.cs
@@ -0,0 +1,44 @@
+using Microsoft.CodeAnalysis.CSharp;
+
+namespace Sybil
+{
+ public static class SyntaxBuilder
+ {
+ public static NamespaceBuilder CreateNamespace(string @namespace)
+ {
+ return new NamespaceBuilder(@namespace);
+ }
+ public static ClassBuilder CreateClass(string className)
+ {
+ return new ClassBuilder(className);
+ }
+ public static ConstructorBuilder CreateConstructor(string className)
+ {
+ return new ConstructorBuilder(className);
+ }
+ public static BaseConstructorBuilder CreateBaseConstructor()
+ {
+ return new BaseConstructorBuilder();
+ }
+ public static PropertyBuilder CreateProperty(string typeName, string propertyName)
+ {
+ return new PropertyBuilder(typeName, propertyName);
+ }
+ public static AccessorBuilder CreateSetter()
+ {
+ return new AccessorBuilder(SyntaxKind.SetAccessorDeclaration);
+ }
+ public static AccessorBuilder CreateGetter()
+ {
+ return new AccessorBuilder(SyntaxKind.GetAccessorDeclaration);
+ }
+ public static FieldBuilder CreateField(string fieldType, string fieldName)
+ {
+ return new FieldBuilder(fieldType, fieldName);
+ }
+ public static MethodBuilder CreateMethod(string returnType, string methodName)
+ {
+ return new MethodBuilder(returnType, methodName);
+ }
+ }
+}