mirror of
https://github.com/AlexMacocian/Sybil.git
synced 2026-07-15 15:19:59 +00:00
Support for filescoped namespaces
Closes #7 Support for compilation units Closes #8
This commit is contained in:
@@ -7,44 +7,44 @@ namespace Sybil.IntegrationTests;
|
||||
[TestClass]
|
||||
public sealed class FlowTests
|
||||
{
|
||||
private const string ExpectedNamespace =
|
||||
@"[InternalsVisibleTo(""FlowTests"")]
|
||||
namespace TestNamespace
|
||||
private const string ExpectedSyntax =
|
||||
@"using System;
|
||||
|
||||
[InternalsVisibleTo(""FlowTests"")]
|
||||
namespace TestNamespace;
|
||||
[SomeAttribute(SomeIntProperty = 1, SomeStringProperty = ""Hello"", SomeEnumProperty = MyEnum.Value, SomeTypeProperty = typeof(String), SomeNullProperty = null)]
|
||||
public sealed class TestClass : BaseTestClass
|
||||
{
|
||||
using System;
|
||||
|
||||
[SomeAttribute(SomeIntProperty = 1, SomeStringProperty = ""Hello"", SomeEnumProperty = MyEnum.Value, SomeTypeProperty = typeof(String), SomeNullProperty = null)]
|
||||
public sealed class TestClass : BaseTestClass
|
||||
[SomeAttribute5(null)]
|
||||
TestClass(string fieldString) : base(fieldString)
|
||||
{
|
||||
[SomeAttribute5(null)]
|
||||
TestClass(string fieldString) : base(fieldString)
|
||||
{
|
||||
this.fieldString = fieldString ?? throw new ArgumentNullException();
|
||||
this.PropertyString = string.Empty;
|
||||
}
|
||||
this.fieldString = fieldString ?? throw new ArgumentNullException();
|
||||
this.PropertyString = string.Empty;
|
||||
}
|
||||
|
||||
private string someTypeString = $""{typeof(string)}"";
|
||||
[SomeAttribute2]
|
||||
private string fieldString;
|
||||
[SomeAttribute3(typeof(String))]
|
||||
public string PropertyString { private set; get; }
|
||||
private string someTypeString = $""{typeof(string)}"";
|
||||
[SomeAttribute2]
|
||||
private string fieldString;
|
||||
[SomeAttribute3(typeof(String))]
|
||||
public string PropertyString { private set; get; }
|
||||
|
||||
[SomeAttribute4(0.5F)]
|
||||
public string GetFieldString()
|
||||
{
|
||||
this.fieldString = 0;
|
||||
return this.fieldString;
|
||||
}
|
||||
[SomeAttribute4(0.5F)]
|
||||
public string GetFieldString()
|
||||
{
|
||||
this.fieldString = 0;
|
||||
return this.fieldString;
|
||||
}
|
||||
}";
|
||||
|
||||
[TestMethod]
|
||||
public void NewNamespace_GeneratesExpected()
|
||||
{
|
||||
var namespaceSyntax = SyntaxBuilder.CreateNamespace("TestNamespace")
|
||||
var compilationUnitSyntax = SyntaxBuilder.CreateCompilationUnit()
|
||||
.WithUsing("System")
|
||||
.WithNamespace(
|
||||
SyntaxBuilder.CreateFileScopedNamespace("TestNamespace")
|
||||
.WithAttribute(SyntaxBuilder.CreateAttribute("InternalsVisibleTo")
|
||||
.WithArgument("FlowTests"))
|
||||
.WithUsing("System")
|
||||
.WithClass(
|
||||
SyntaxBuilder.CreateClass("TestClass")
|
||||
.WithBaseClass("BaseTestClass")
|
||||
@@ -88,10 +88,10 @@ namespace TestNamespace
|
||||
.WithModifier("public")
|
||||
.WithAttribute(SyntaxBuilder.CreateAttribute("SomeAttribute4")
|
||||
.WithArgument(0.5f))
|
||||
.WithBody("this.fieldString = 0;\r\nreturn this.fieldString;")))
|
||||
.WithBody("this.fieldString = 0;\r\nreturn this.fieldString;"))))
|
||||
.Build();
|
||||
|
||||
var namespaceString = namespaceSyntax.ToFullString();
|
||||
namespaceString.Should().Be(ExpectedNamespace);
|
||||
var compilationUnit = compilationUnitSyntax.ToFullString();
|
||||
compilationUnit.Should().Be(ExpectedSyntax);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
using FluentAssertions;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
|
||||
namespace Sybil.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class CompilationUnitTests
|
||||
{
|
||||
private const string UsingSystemWindows = "using System.Windows;";
|
||||
|
||||
private readonly CompilationUnitBuilder compilationUnitBuilder = new();
|
||||
|
||||
[TestMethod]
|
||||
public void WithUsing_NullUsing_ThrowsArgumentNullException()
|
||||
{
|
||||
var action = () =>
|
||||
{
|
||||
this.compilationUnitBuilder.WithUsing(null);
|
||||
};
|
||||
|
||||
action.Should().Throw<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WithNamespace_NullNamespaceBuilder_ThrowsArgumentNullException()
|
||||
{
|
||||
var action = () =>
|
||||
{
|
||||
this.compilationUnitBuilder.WithNamespace(null);
|
||||
};
|
||||
|
||||
action.Should().Throw<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WithUsing_ReturnsExpected()
|
||||
{
|
||||
var result = this.compilationUnitBuilder.WithUsing("System.Windows").Build().ToFullString();
|
||||
|
||||
result.Should().Be(UsingSystemWindows);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,9 @@ public class NamespaceBuilderTests
|
||||
{
|
||||
using System;
|
||||
}";
|
||||
private const string FileScopedNamespaceWithUsing =
|
||||
@"namespace Test;
|
||||
using System;";
|
||||
|
||||
private readonly NamespaceBuilder builder;
|
||||
|
||||
@@ -65,21 +68,40 @@ public class NamespaceBuilderTests
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Build_ReturnsNamespaceDeclarationSyntax()
|
||||
public void Build_ReturnsFileScopedNamespaceDeclarationSyntax()
|
||||
{
|
||||
var syntax = this.builder.Build();
|
||||
|
||||
syntax.Should().NotBeNull().And.Subject.Should().BeOfType<FileScopedNamespaceDeclarationSyntax>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Build_ReturnsNamespaceDeclarationSyntax()
|
||||
{
|
||||
var syntax = new NamespaceBuilder(Namespace, false).Build();
|
||||
|
||||
syntax.Should().NotBeNull().And.Subject.Should().BeOfType<NamespaceDeclarationSyntax>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WithUsing_ReturnsExpectedString()
|
||||
public void FileScoped_WithUsing_ReturnsExpectedString()
|
||||
{
|
||||
var result = this.builder
|
||||
.WithUsing(Using)
|
||||
.Build()
|
||||
.ToFullString();
|
||||
|
||||
result.Should().Be(FileScopedNamespaceWithUsing);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Enclosed_WithUsing_ReturnsExpectedString()
|
||||
{
|
||||
var result = new NamespaceBuilder(Namespace, false)
|
||||
.WithUsing(Using)
|
||||
.Build()
|
||||
.ToFullString();
|
||||
|
||||
result.Should().Be(NamespaceWithUsing);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
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 CompilationUnitBuilder : IBuilder<CompilationUnitSyntax>
|
||||
{
|
||||
private readonly List<NamespaceBuilder> namespaceBuilders = new List<NamespaceBuilder>();
|
||||
|
||||
private CompilationUnitSyntax CompilationUnitSyntax { get; set; }
|
||||
|
||||
internal CompilationUnitBuilder()
|
||||
{
|
||||
this.CompilationUnitSyntax = SyntaxFactory.CompilationUnit();
|
||||
}
|
||||
|
||||
public CompilationUnitBuilder WithUsing(string usingName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(usingName))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(usingName));
|
||||
}
|
||||
|
||||
this.CompilationUnitSyntax = this.CompilationUnitSyntax.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.IdentifierName(usingName)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CompilationUnitBuilder WithNamespace(NamespaceBuilder namespaceBuilder)
|
||||
{
|
||||
this.namespaceBuilders.Add(namespaceBuilder ?? throw new ArgumentNullException(nameof(namespaceBuilder)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CompilationUnitSyntax Build()
|
||||
{
|
||||
this.CompilationUnitSyntax = this.CompilationUnitSyntax.AddMembers(this.namespaceBuilders.Select(n => n.Build()).ToArray());
|
||||
return this.CompilationUnitSyntax.NormalizeWhitespace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,20 @@ using System.Linq;
|
||||
|
||||
namespace Sybil
|
||||
{
|
||||
public sealed class NamespaceBuilder : IBuilder<NamespaceDeclarationSyntax>
|
||||
public sealed class NamespaceBuilder : IBuilder<BaseNamespaceDeclarationSyntax>
|
||||
{
|
||||
private readonly List<AttributeBuilder> attributeBuilders = new List<AttributeBuilder>();
|
||||
private readonly List<ClassBuilder> classBuilders = new List<ClassBuilder>();
|
||||
private NamespaceDeclarationSyntax NamespaceDeclaration { get; set; }
|
||||
private BaseNamespaceDeclarationSyntax NamespaceDeclaration { get; set; }
|
||||
|
||||
internal NamespaceBuilder(
|
||||
string @namespace)
|
||||
string @namespace, bool fileScoped = true)
|
||||
{
|
||||
_ = string.IsNullOrWhiteSpace(@namespace) ? throw new ArgumentNullException(nameof(@namespace)) : @namespace;
|
||||
|
||||
this.NamespaceDeclaration = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(@namespace));
|
||||
this.NamespaceDeclaration = fileScoped ?
|
||||
(BaseNamespaceDeclarationSyntax)SyntaxFactory.FileScopedNamespaceDeclaration(SyntaxFactory.ParseName(@namespace)) :
|
||||
(BaseNamespaceDeclarationSyntax)SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(@namespace));
|
||||
}
|
||||
|
||||
public NamespaceBuilder WithUsing(string usingName)
|
||||
@@ -48,7 +50,7 @@ namespace Sybil
|
||||
return this;
|
||||
}
|
||||
|
||||
public NamespaceDeclarationSyntax Build()
|
||||
public BaseNamespaceDeclarationSyntax Build()
|
||||
{
|
||||
if (this.attributeBuilders.Count > 0)
|
||||
{
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<Version>0.5.0</Version>
|
||||
<Version>0.6.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -4,7 +4,8 @@ namespace Sybil
|
||||
{
|
||||
public static class SyntaxBuilder
|
||||
{
|
||||
public static NamespaceBuilder CreateNamespace(string @namespace) => new NamespaceBuilder(@namespace);
|
||||
public static NamespaceBuilder CreateNamespace(string @namespace) => new NamespaceBuilder(@namespace, false);
|
||||
public static NamespaceBuilder CreateFileScopedNamespace(string @namespace) => new NamespaceBuilder(@namespace, true);
|
||||
public static ClassBuilder CreateClass(string className) => new ClassBuilder(className);
|
||||
public static ConstructorBuilder CreateConstructor(string className) => new ConstructorBuilder(className);
|
||||
public static BaseConstructorBuilder CreateBaseConstructor() => new BaseConstructorBuilder();
|
||||
@@ -14,5 +15,6 @@ namespace Sybil
|
||||
public static FieldBuilder CreateField(string fieldType, string fieldName) => new FieldBuilder(fieldType, fieldName);
|
||||
public static MethodBuilder CreateMethod(string returnType, string methodName) => new MethodBuilder(returnType, methodName);
|
||||
public static AttributeBuilder CreateAttribute(string attributeName) => new AttributeBuilder(attributeName);
|
||||
public static CompilationUnitBuilder CreateCompilationUnit() => new CompilationUnitBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user