Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
11 changes: 11 additions & 0 deletions DecoratorGenerator.UnitTests/ITigerConstraints.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using DecoratorGenerator;

namespace SampleLibrary;

[Decorate]
public interface ITigerConstraints
{
string Roar();

string Trait<T>(T trait) where T : class, ICat, new();
}
23 changes: 23 additions & 0 deletions DecoratorGenerator.UnitTests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@
}.RunAsync();
}

[Test]
public async Task OneInterface_Constraints() {
var source = await ReadCSharpFile<ITigerConstraints>();
var generated = await ReadCSharpFile<TigerConstraintsDecorator>();

await new VerifyCS.Test
{
TestState = {
ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
AdditionalReferences =
{
implementationAssembly,
Assembly.GetExecutingAssembly()
},
Sources = { source },
GeneratedSources =
{
(typeof(Main), "TigerConstraintsDecorator.generated.cs", SourceText.From(generated, Encoding.UTF8, SourceHashAlgorithm.Sha256)),
},
},
}.RunAsync();
}

[Test]
public async Task OneInterface_NestedNamespace() {
var source = await ReadCSharpFile<INested>();
Expand Down Expand Up @@ -142,10 +165,10 @@
}

private static async Task<string> ReadCSharpFile<T>() {
var currentDirectory = Directory.GetParent(Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.Parent.FullName);

Check warning on line 168 in DecoratorGenerator.UnitTests/Tests.cs

View workflow job for this annotation

GitHub Actions / Unit tests (8.0.x)

Dereference of a possibly null reference.

Check warning on line 168 in DecoratorGenerator.UnitTests/Tests.cs

View workflow job for this annotation

GitHub Actions / Unit tests (8.0.x)

Dereference of a possibly null reference.

Check warning on line 168 in DecoratorGenerator.UnitTests/Tests.cs

View workflow job for this annotation

GitHub Actions / Unit tests (8.0.x)

Dereference of a possibly null reference.

Check warning on line 168 in DecoratorGenerator.UnitTests/Tests.cs

View workflow job for this annotation

GitHub Actions / Unit tests (8.0.x)

Dereference of a possibly null reference.

var searchPattern = $"{typeof(T).Name}*.cs";
var file = currentDirectory.GetFiles(searchPattern).First();

Check warning on line 171 in DecoratorGenerator.UnitTests/Tests.cs

View workflow job for this annotation

GitHub Actions / Unit tests (8.0.x)

Dereference of a possibly null reference.

using var fileReader = new StreamReader(file.OpenRead());
return await fileReader.ReadToEndAsync();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// <auto-generated/>
#nullable restore
namespace SampleLibrary;

public abstract class TigerConstraintsDecorator : ITigerConstraints
{
private ITigerConstraints tigerConstraints;

protected TigerConstraintsDecorator(ITigerConstraints tigerConstraints) {
this.tigerConstraints = tigerConstraints;
}



public virtual string Roar() {
return tigerConstraints.Roar();
}

public virtual string Trait<T>(T trait) where T : class, SampleLibrary.ICat, new() {
return tigerConstraints.Trait<T>(trait);
}
}
23 changes: 22 additions & 1 deletion DecoratorGenerator/OutputGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,28 @@ public abstract class {className} : {@interface.Name}
var typeParametersStrings = method.TypeParameters.Select(t => t.ToDisplayString());
var parametersStrings = method.Parameters.Select(p => $@"{p.Type} {p.Name}");
var formattedAccessibility = (method.ReturnType.DeclaredAccessibility != Accessibility.NotApplicable ? method.ReturnType.DeclaredAccessibility : Accessibility.Public).ToString().ToLower();
var signature = $@"{formattedAccessibility} virtual {method.ReturnType} {method.Name}{(method.IsGenericMethod ? $@"<{string.Join(", ", typeParametersStrings)}>" : string.Empty)}({string.Join(", ", parametersStrings)})";
var formattedGenericTypeParameters = method.IsGenericMethod ? $@"<{string.Join(", ", typeParametersStrings)}>" : string.Empty;
var formattedConstraintsStrings = method.TypeParameters.Select(t => {
var constraintsStrings = new List<string>();

if (t.HasReferenceTypeConstraint) {
constraintsStrings.Add("class");
}

if (t.HasNotNullConstraint) {
constraintsStrings.Add("notnull");
}
constraintsStrings = constraintsStrings.Concat(t.ConstraintTypes.ToList().Select(ct => ct.ToDisplayString())).ToList();

if (t.HasConstructorConstraint) {
constraintsStrings.Add("new()");
}

return constraintsStrings.Any() ? $@"where {t.ToDisplayString()} : {string.Join(", ", constraintsStrings)}" : string.Empty;
})
.Where(cs => cs != string.Empty);
var formattedConstraints = string.Join(" ", formattedConstraintsStrings);
var signature = $@"{formattedAccessibility} virtual {method.ReturnType} {method.Name}{formattedGenericTypeParameters}({string.Join(", ", parametersStrings)}){(formattedConstraints != string.Empty ? $@" {formattedConstraints}" : string.Empty)}";
var callParameters = $@"{string.Join(", ", method.Parameters.Select(p => p.Name))}";

var call = $@"{targetFieldName}.{method.Name}{(method.IsGenericMethod ? $@"<{string.Join(", ", typeParametersStrings)}>" : string.Empty)}({callParameters})";
Expand Down
Loading