Skip to content

Commit

Permalink
Release 0.16.0 (#62)
Browse files Browse the repository at this point in the history
* Added support for xml documentation to class, constructot, fields and properties.
* Added support for single line comments to statements.
  • Loading branch information
MilleBo authored Feb 20, 2020
1 parent c2b9ad1 commit ef0201a
Show file tree
Hide file tree
Showing 17 changed files with 277 additions and 117 deletions.
36 changes: 36 additions & 0 deletions src/Testura.Code.Tests/Integration/ModelClassTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Testura.Code.Statements;
using NUnit.Framework;
using Testura.Code.Builders;
using Testura.Code.Builders.BuildMembers;
using Testura.Code.Extensions;
using Testura.Code.Generators.Class;
using Testura.Code.Generators.Common;
using Testura.Code.Models;
Expand Down Expand Up @@ -149,5 +152,38 @@ public void Test_CreateClassWithMethodThatHaveXmlDocumentation()
"usingSystem;namespaceModels{publicclassCat{/// <summary>\n/// Some summary\n/// </summary>\n/// <param name=\"MyParameter\">Some documentation</param>\nvoidMyMethod(stringMyParameter){}}}",
@class.ToString());
}

[Test]
public void Test_CreateClassWithMethodThatHaveMultipleSUmmarysAndSingleLineComments()
{
var classBuilder = new ClassBuilder("Cat", "Models");
var @class = classBuilder
.WithUsings("System")
.WithSummary("My class summary")
.WithConstructor(ConstructorGenerator.Create(
"Cat",
BodyGenerator.Create(
Statement.Declaration.Assign("Name", ReferenceGenerator.Create(new VariableReference("name"))),
Statement.Declaration.Assign("Age", ReferenceGenerator.Create(new VariableReference("age")))),
new List<Parameter> { new Parameter("name", typeof(string)), new Parameter("age", typeof(int), xmlDocumentation: "My parameter") },
new List<Modifiers> { Modifiers.Public },
summary: "MyConstructor summary"))
.WithProperties(new AutoProperty("MyProperty", typeof(int), PropertyTypes.GetAndSet, summary: "MyPropertySummary"))
.WithFields(
new Field("_name", typeof(string), new List<Modifiers>() { Modifiers.Private }, summary: "My field summary"))
.WithMethods(new MethodBuilder("MyMethod")
.WithParameters(new Parameter("MyParameter", typeof(string)))
.WithBody(
BodyGenerator.Create(
Statement.Declaration.Declare("hello", typeof(int)).WithComment("My comment above").WithComment("hej"),
Statement.Declaration.Declare("hello", typeof(int)).WithComment("My comment to the side", CommentPosition.Right)
))
.Build())
.Build();

Assert.AreEqual(
"usingSystem;namespaceModels{/// <summary>\n/// My class summary\n/// </summary>\npublicclassCat{/// <summary>\n/// MyConstructor summary\n/// </summary>\n/// <param name=\"age\">My parameter</param>\npublicCat(stringname,intage){Name=name;Age=age;}/// <summary>\n/// MyPropertySummary\n/// </summary>\nintMyProperty{get;set;}/// <summary>\n/// My field summary\n/// </summary>\nprivatestring_name;voidMyMethod(stringMyParameter){//hej\ninthello;inthello; //My comment to the side\n}}}",
@class.ToString());
}
}
}
19 changes: 16 additions & 3 deletions src/Testura.Code/Builders/Base/TypeBuilderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Testura.Code.Builders.Base;
using Testura.Code.Builders.BuildMembers;
using Testura.Code.Generators.Class;
using Testura.Code.Generators.Common;
using Testura.Code.Generators.Special;
using Testura.Code.Models.Properties;
using Attribute = Testura.Code.Models.Attribute;

namespace Testura.Code.Builders
namespace Testura.Code.Builders.Base
{
public abstract class TypeBuilderBase<TBuilder> : BuilderBase<TBuilder>
where TBuilder : TypeBuilderBase<TBuilder>
{
private readonly List<Type> _inheritance;
private readonly List<Modifiers> _modifiers;
private SyntaxList<AttributeListSyntax> _attributes;
private string _summary;

protected TypeBuilderBase(string name, string @namespace)
: base(@namespace)
Expand Down Expand Up @@ -115,12 +116,23 @@ public TBuilder WithProperties(params PropertyDeclarationSyntax[] properties)
/// Add region.
/// </summary>
/// <param name="regionMember">The region</param>
/// <returns>The current builder</returns>
/// <returns>The current builder.</returns>
public TBuilder WithRegions(params RegionBuildMember[] regionMember)
{
return With(regionMember);
}

/// <summary>
/// Add summary.
/// </summary>
/// <param name="summary">The summary text.</param>
/// <returns>The current builder.</returns>
public TBuilder WithSummary(string summary)
{
_summary = summary;
return (TBuilder)this;
}

/// <summary>
/// Build the type and return the generated code.
/// </summary>
Expand All @@ -140,6 +152,7 @@ public CompilationUnitSyntax Build()
public TypeDeclarationSyntax BuildWithoutNamespace()
{
var @type = BuildBase();
@type = @type.WithSummary(_summary);
@type = BuildAttributes(@type);
@type = BuildMembers(@type);
return @type;
Expand Down
1 change: 1 addition & 0 deletions src/Testura.Code/Builders/ClassBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Linq;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Testura.Code.Builders.Base;
using Testura.Code.Builders.BuildMembers;
using Testura.Code.Generators.Class;
using Testura.Code.Models;
Expand Down
1 change: 1 addition & 0 deletions src/Testura.Code/Builders/InterfaceBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Testura.Code.Builders.Base;

namespace Testura.Code.Builders
{
Expand Down
99 changes: 2 additions & 97 deletions src/Testura.Code/Builders/MethodBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Testura.Code.Generators.Common;
using Testura.Code.Generators.Special;
using Testura.Code.Models;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
using Attribute = Testura.Code.Models.Attribute;
Expand Down Expand Up @@ -155,7 +156,7 @@ public MethodDeclarationSyntax Build()
var method = BuildMethodBase();
method = BuildModifiers(method);
method = BuildAttributes(method);
method = BuildXmlComments(method);
method = method.WithSummary(_summary, _parameterXmlDocumentation);
method = BuildParameters(method);
method = BuildBody(method);
return method;
Expand Down Expand Up @@ -185,31 +186,6 @@ private MethodDeclarationSyntax BuildModifiers(MethodDeclarationSyntax method)
return method.WithModifiers(ModifierGenerator.Create(_modifiers.ToArray()));
}

private MethodDeclarationSyntax BuildXmlComments(MethodDeclarationSyntax method)
{
if (string.IsNullOrEmpty(_summary))
{
return method;
}

var content = List<XmlNodeSyntax>();

content = CreateSummaryDocumentation(content);

foreach (var parameter in _parameterXmlDocumentation)
{
content = CreateParameterDocumentation(content, parameter);
}

content = content.Add(XmlText().WithTextTokens(TokenList(XmlTextNewLine(TriviaList(), "\n", "\n", TriviaList()))));

var trivia = Trivia(
DocumentationCommentTrivia(
SyntaxKind.SingleLineDocumentationCommentTrivia,
content));
return method.WithLeadingTrivia(trivia);
}

private MethodDeclarationSyntax BuildAttributes(MethodDeclarationSyntax method)
{
return !_attributes.Any() ? method : method.WithAttributeLists(_attributes);
Expand All @@ -229,76 +205,5 @@ private MethodDeclarationSyntax BuildBody(MethodDeclarationSyntax method)

return method.WithBody(_body);
}

private SyntaxList<XmlNodeSyntax> CreateSummaryDocumentation(SyntaxList<XmlNodeSyntax> content)
{
var summary = new List<SyntaxToken>();
summary.Add(XmlTextNewLine(TriviaList(), "\n", "\n", TriviaList()));
var commentLines = _summary.Split(new[] { "\n" }, StringSplitOptions.None);
for (int n = 0; n < commentLines.Length; n++)
{
var fixedCommentLine = $" {commentLines[n]}";
if (n != commentLines.Length - 1)
{
fixedCommentLine += "\n";
}

summary.Add(XmlTextLiteral(TriviaList(DocumentationCommentExterior("///")), fixedCommentLine, fixedCommentLine, TriviaList()));
}

summary.Add(XmlTextNewLine(TriviaList(), "\n", "\n", TriviaList()));
summary.Add(XmlTextLiteral(TriviaList(DocumentationCommentExterior("///")), " ", " ", TriviaList()));

return content.AddRange(new List<XmlNodeSyntax>
{
XmlText().WithTextTokens(TokenList(XmlTextLiteral(TriviaList(DocumentationCommentExterior("///")), " ", " ", TriviaList()))),
XmlElement(XmlElementStartTag(XmlName(Identifier("summary"))), XmlElementEndTag(XmlName(Identifier("summary"))))
.WithContent(SingletonList<XmlNodeSyntax>(XmlText().WithTextTokens(TokenList(summary)))),
});
}

private SyntaxList<XmlNodeSyntax> CreateParameterDocumentation(SyntaxList<XmlNodeSyntax> content, Parameter parameter)
{
return content.AddRange(new List<XmlNodeSyntax> {
XmlText().WithTextTokens(
TokenList(
new[]
{
XmlTextNewLine(
TriviaList(),
"\n",
"\n",
TriviaList()),
XmlTextLiteral(
TriviaList(
DocumentationCommentExterior("///")),
" ",
" ",
TriviaList())
})),
XmlExampleElement(SingletonList<XmlNodeSyntax>(
XmlText().WithTextTokens(
TokenList(
XmlTextLiteral(
TriviaList(),
parameter.XmlDocumentation,
parameter.XmlDocumentation,
TriviaList())))))
.WithStartTag(XmlElementStartTag(
XmlName(
Identifier("param")))
.WithAttributes(
SingletonList<XmlAttributeSyntax>(
XmlNameAttribute(
XmlName(
Identifier(" name")),
Token(SyntaxKind.DoubleQuoteToken),
IdentifierName(parameter.Name),
Token(SyntaxKind.DoubleQuoteToken)))))
.WithEndTag(
XmlElementEndTag(
XmlName(
Identifier("param")))) });
}
}
}
13 changes: 13 additions & 0 deletions src/Testura.Code/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,17 @@ public enum ConstructorInitializerTypes
/// </summary>
This
}

public enum CommentPosition
{
/// <summary>
/// Generate comment above statement.
/// </summary>
Above,

/// <summary>
/// Generate comment to the right of statement.
/// </summary>
Right
}
}
124 changes: 124 additions & 0 deletions src/Testura.Code/Extensions/CsharpSyntaxNodeExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Testura.Code.Models;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

namespace Testura.Code.Generators.Special
{
/// <summary>
/// Extension methods to CsharpSyntaxNode.
/// </summary>
public static class CsharpSyntaxNodeExtensions
{
/// <summary>
/// Create summary to syntax node.
/// </summary>
/// <typeparam name="T">Syntax type.</typeparam>
/// <param name="syntax">The syntax.</param>
/// <param name="summary">Summary text.</param>
/// <param name="parameters">Parameters in the summary</param>
/// <returns>Return syntax node with summary.</returns>
public static T WithSummary<T>(this T syntax, string summary, IEnumerable<Parameter> parameters = null)
where T : CSharpSyntaxNode
{
parameters = parameters ?? new List<Parameter>();

if (string.IsNullOrEmpty(summary))
{
return syntax;
}

var content = List<XmlNodeSyntax>();

content = CreateSummaryDocumentation(content, summary);

foreach (var parameter in parameters.Where(p => p.XmlDocumentation != null))
{
content = CreateParameterDocumentation(content, parameter);
}

content = content.Add(XmlText().WithTextTokens(TokenList(XmlTextNewLine(TriviaList(), "\n", "\n", TriviaList()))));

var trivia = Trivia(
DocumentationCommentTrivia(
SyntaxKind.SingleLineDocumentationCommentTrivia,
content));
return syntax.WithLeadingTrivia(trivia);
}

private static SyntaxList<XmlNodeSyntax> CreateSummaryDocumentation(SyntaxList<XmlNodeSyntax> content, string text)
{
var summary = new List<SyntaxToken>();
summary.Add(XmlTextNewLine(TriviaList(), "\n", "\n", TriviaList()));
var commentLines = text.Split(new[] { "\n" }, StringSplitOptions.None);
for (int n = 0; n < commentLines.Length; n++)
{
var fixedCommentLine = $" {commentLines[n]}";
if (n != commentLines.Length - 1)
{
fixedCommentLine += "\n";
}

summary.Add(XmlTextLiteral(TriviaList(DocumentationCommentExterior("///")), fixedCommentLine, fixedCommentLine, TriviaList()));
}

summary.Add(XmlTextNewLine(TriviaList(), "\n", "\n", TriviaList()));
summary.Add(XmlTextLiteral(TriviaList(DocumentationCommentExterior("///")), " ", " ", TriviaList()));

return content.AddRange(new List<XmlNodeSyntax>
{
XmlText().WithTextTokens(TokenList(XmlTextLiteral(TriviaList(DocumentationCommentExterior("///")), " ", " ", TriviaList()))),
XmlElement(XmlElementStartTag(XmlName(Identifier("summary"))), XmlElementEndTag(XmlName(Identifier("summary"))))
.WithContent(SingletonList<XmlNodeSyntax>(XmlText().WithTextTokens(TokenList(summary)))),
});
}

private static SyntaxList<XmlNodeSyntax> CreateParameterDocumentation(SyntaxList<XmlNodeSyntax> content, Parameter parameter)
{
return content.AddRange(new List<XmlNodeSyntax> {
XmlText().WithTextTokens(
TokenList(
new[]
{
XmlTextNewLine(
TriviaList(),
"\n",
"\n",
TriviaList()),
XmlTextLiteral(
TriviaList(
DocumentationCommentExterior("///")),
" ",
" ",
TriviaList())
})),
XmlExampleElement(SingletonList<XmlNodeSyntax>(
XmlText().WithTextTokens(
TokenList(
XmlTextLiteral(
TriviaList(),
parameter.XmlDocumentation,
parameter.XmlDocumentation,
TriviaList())))))
.WithStartTag(XmlElementStartTag(
XmlName(
Identifier("param")))
.WithAttributes(
SingletonList<XmlAttributeSyntax>(
XmlNameAttribute(
XmlName(
Identifier(" name")),
Token(SyntaxKind.DoubleQuoteToken),
IdentifierName(parameter.Name),
Token(SyntaxKind.DoubleQuoteToken)))))
.WithEndTag(
XmlElementEndTag(
XmlName(
Identifier("param")))) });
}
}
}
Loading

0 comments on commit ef0201a

Please sign in to comment.