Skip to content

Commit

Permalink
Add option for not generating async methods
Browse files Browse the repository at this point in the history
  • Loading branch information
maca88 committed Sep 14, 2022
1 parent 16b3c39 commit 1dd3d94
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using AsyncGenerator.Core.Transformation;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace AsyncGenerator.Core.Configuration
Expand Down Expand Up @@ -60,5 +61,11 @@ public interface IFluentProjectTransformConfiguration
/// Add a callback to configure the preprocessor directives generation
/// </summary>
IFluentProjectTransformConfiguration PreprocessorDirectives(Action<IFluentProjectPreprocessorDirectivesConfiguration> action);

/// <summary>
/// Set a function that will decide what type of generation to apply for a given method.
/// <para>Default <see cref="F:AsyncGenerator.Core.MethodGeneration.Generate"/> is chosen for all methods.</para>
/// </summary>
IFluentProjectTransformConfiguration MethodGeneration(Func<IMethodSymbol, MethodGeneration> func);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
</xs:restriction>
</xs:simpleType>

<xs:simpleType name="MethodGeneration">
<xs:restriction base="xs:string">
<xs:enumeration value="Ignore"/>
<xs:enumeration value="Generate"/>
</xs:restriction>
</xs:simpleType>

<xs:simpleType name="TypeConversion">
<xs:restriction base="xs:string">
<xs:enumeration value="Ignore"/>
Expand Down Expand Up @@ -117,6 +124,14 @@
</xs:complexContent>
</xs:complexType>

<xs:complexType name="MethodGenerationFilter">
<xs:complexContent>
<xs:extension base="MethodFilter">
<xs:attribute name="generation" type="MethodGeneration" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>

<xs:complexType name="AsyncReturnTypeFilter">
<xs:complexContent>
<xs:extension base="MethodFilter">
Expand Down Expand Up @@ -219,16 +234,28 @@
<xs:attribute name="fileName" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="AssemblyType">
<xs:attribute name="assemblyName" type="xs:string" use="required"/>
<xs:attribute name="fullTypeName" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="AsyncExtensionMethods">
<xs:sequence>
<xs:all>
<xs:element name="ProjectFiles" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="ProjectFile" type="ProjectFile" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:element name="AssemblyTypes" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="AssemblyType" type="AssemblyType" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>

<xs:complexType name="CancellationTokens">
Expand Down Expand Up @@ -464,9 +491,15 @@
</xs:all>
</xs:complexType>


<xs:complexType name="Transformation">
<xs:all>
<xs:element name="MethodGeneration" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="Method" type="MethodGenerationFilter" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Disable" type="xs:boolean" nillable="true" minOccurs="0" />
<xs:element name="AsyncFolder" type="xs:string" minOccurs="0" />
<xs:element name="ConfigureAwaitArgument" type="xs:boolean" nillable="true" minOccurs="0" />
Expand All @@ -481,7 +514,7 @@
</xs:element>
</xs:all>
</xs:complexType>

<xs:complexType name="Project">
<xs:all>
<xs:element name="ConcurrentRun" type="xs:boolean" nillable="true" minOccurs="0"/>
Expand Down
17 changes: 17 additions & 0 deletions Source/AsyncGenerator.Core/FileConfiguration/FileConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,18 @@ public class MethodConversionFilter : MethodFilter
public MethodConversion Conversion { get; set; }
}

[Serializable]
[DebuggerStepThrough]
[DesignerCategory("code")]
[XmlType(Namespace = "https://github.com/maca88/AsyncGenerator")]
[XmlRoot("MethodGenerationFilter")]
[EditorBrowsable(EditorBrowsableState.Never)]
public class MethodGenerationFilter : MethodFilter
{
[XmlAttribute(AttributeName = "generation")]
public MethodGeneration Generation { get; set; }
}

[Serializable]
[DebuggerStepThrough]
[DesignerCategory("code")]
Expand All @@ -233,6 +245,7 @@ public class MethodPredicateFilter : MethodFilter

[XmlInclude(typeof(MethodCancellationTokenFilter))]
[XmlInclude(typeof(MethodConversionFilter))]
[XmlInclude(typeof(MethodGenerationFilter))]
[XmlInclude(typeof(MethodPredicateFilter))]
[XmlInclude(typeof(AsyncReturnTypeFilter))]
[Serializable]
Expand Down Expand Up @@ -268,6 +281,7 @@ public string ReturnsVoidString
[XmlInclude(typeof(MethodFilter))]
[XmlInclude(typeof(MethodCancellationTokenFilter))]
[XmlInclude(typeof(MethodConversionFilter))]
[XmlInclude(typeof(MethodGenerationFilter))]
[XmlInclude(typeof(MethodPredicateFilter))]
[XmlInclude(typeof(AsyncReturnTypeFilter))]
[Serializable]
Expand Down Expand Up @@ -462,6 +476,8 @@ public MethodRule()
[EditorBrowsable(EditorBrowsableState.Never)]
public class Transformation
{
[XmlArrayItem("Method", IsNullable = false)]
public List<MethodGenerationFilter> MethodGeneration { get; set; }
[XmlElement(IsNullable = true)]
public bool? Disable { get; set; }
[XmlElement("AsyncFolder")]
Expand All @@ -479,6 +495,7 @@ public class Transformation

public Transformation()
{
MethodGeneration = new List<MethodGenerationFilter>();
AsyncLock = new TransformationAsyncLock();
DocumentationComments = new DocumentationComments();
PreprocessorDirectives = new PreprocessorDirectives();
Expand Down
20 changes: 20 additions & 0 deletions Source/AsyncGenerator.Core/FileConfiguration/FileConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,10 @@ private static void Configure(AsyncGenerator configuration, CancellationTokens c

private static void Configure(AsyncGenerator configuration, Transformation config, IFluentProjectTransformConfiguration fluentConfig)
{
if (config.MethodGeneration.Any())
{
fluentConfig.MethodGeneration(CreateMethodGenerationFunction(configuration, config.MethodGeneration));
}
if (config.LocalFunctions.HasValue)
{
fluentConfig.LocalFunctions(config.LocalFunctions.Value);
Expand Down Expand Up @@ -566,6 +570,22 @@ private static Func<IMethodSymbol, MethodConversion> CreateMethodConversionFunct
};
}

private static Func<IMethodSymbol, MethodGeneration> CreateMethodGenerationFunction(AsyncGenerator globalConfig, IList<MethodGenerationFilter> filters)
{
var rules = globalConfig.MethodRules.ToDictionary(o => o.Name, o => o.Filters);
return symbol =>
{
foreach (var filter in filters)
{
if (CanApply(symbol, filter, rules))
{
return filter.Generation;
}
}
return MethodGeneration.Generate; // Default value
};
}

private static Func<IMethodSymbol, AsyncReturnType?> CreateAsyncReturnTypeFunction(AsyncGenerator globalConfig, IList<AsyncReturnTypeFilter> filters)
{
var rules = globalConfig.MethodRules.ToDictionary(o => o.Name, o => o.Filters);
Expand Down
14 changes: 14 additions & 0 deletions Source/AsyncGenerator.Core/MethodGeneration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace AsyncGenerator.Core
{
public enum MethodGeneration
{
/// <summary>
/// The method will be generated
/// </summary>
Generate = 1,
/// <summary>
/// The method won't be generated
/// </summary>
Ignore = 2
}
}
1 change: 0 additions & 1 deletion Source/AsyncGenerator.Tests/AsyncGenerator.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
Expand Down
84 changes: 84 additions & 0 deletions Source/AsyncGenerator.Tests/MethodGeneration/Fixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System.Threading.Tasks;
using AsyncGenerator.Core;
using AsyncGenerator.Core.Transformation;
using NUnit.Framework;
using AsyncGenerator.Tests.Cref.Input;

namespace AsyncGenerator.Tests.MethodGeneration
{
[TestFixture]
public class Fixture : BaseFixture<TestCase>
{
[Test]
public Task TestAfterTransformation()
{
return ReadonlyTest(p => p
.ConfigureAnalyzation(a => a
.MethodConversion(symbol => MethodConversion.Smart)
)
.ConfigureTransformation(t => t
.MethodGeneration(m => m.Name == "Read" ? Core.MethodGeneration.Ignore : Core.MethodGeneration.Generate)
.AfterTransformation(ValidateDocument)
)
);
}

[Test]
public Task TestYamlAfterTransformation()
{
return YamlReadonlyTest(nameof(TestCase),
@"projects:
- filePath: AsyncGenerator.Tests.csproj
analyzation:
methodConversion:
- conversion: Smart
all: true
transformation:
methodGeneration:
- generation: Ignore
name: Read
",
p => p
.ConfigureTransformation(t => t
.AfterTransformation(ValidateDocument))
);
}

[Test]
public Task TestXmlAfterTransformation()
{
return XmlReadonlyTest(nameof(TestCase),
@"
<AsyncGenerator xmlns=""https://github.com/maca88/AsyncGenerator"">
<Projects>
<Project filePath=""AsyncGenerator.Tests.csproj"">
<Analyzation>
<MethodConversion>
<Method conversion=""Smart"" all=""true"" />
</MethodConversion>
</Analyzation>
<Transformation>
<MethodGeneration>
<Method generation=""Ignore"" name=""Read"" />
</MethodGeneration>
</Transformation>
</Project>
</Projects>
</AsyncGenerator>
",
p => p
.ConfigureTransformation(t => t
.AfterTransformation(ValidateDocument))
);
}

private void ValidateDocument(IProjectTransformationResult result)
{
AssertValidAnnotations(result);
Assert.AreEqual(1, result.Documents.Count);
var document = result.Documents[0];
Assert.NotNull(document.OriginalModified);
Assert.AreEqual(GetOutputFile(nameof(TestCase)), document.Transformed.ToFullString());
}
}
}
17 changes: 17 additions & 0 deletions Source/AsyncGenerator.Tests/MethodGeneration/Input/TestCase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using AsyncGenerator.TestCases;

namespace AsyncGenerator.Tests.MethodGeneration.Input
{
public class TestCase
{
public void Read()
{
SimpleFile.Read();
}

public void Read2()
{
Read();
}
}
}
24 changes: 24 additions & 0 deletions Source/AsyncGenerator.Tests/MethodGeneration/Output/TestCase.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by AsyncGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------


using AsyncGenerator.TestCases;

namespace AsyncGenerator.Tests.MethodGeneration.Input
{
using System.Threading.Tasks;
public partial class TestCase
{

public Task Read2Async()
{
return ReadAsync();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using AsyncGenerator.Core;
using AsyncGenerator.Core.Configuration;
using AsyncGenerator.Core.Plugins;
using AsyncGenerator.Core.Transformation;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

Expand All @@ -11,6 +13,7 @@ namespace AsyncGenerator.Configuration.Internal
internal class ProjectTransformConfiguration : IFluentProjectTransformConfiguration, IProjectTransformConfiguration
{
private readonly IProjectConfiguration _projectConfiguration;
private Func<IMethodSymbol, MethodGeneration> _methodGenerationFunction;

public ProjectTransformConfiguration(IProjectConfiguration projectConfiguration)
{
Expand Down Expand Up @@ -49,6 +52,11 @@ public ProjectTransformConfiguration(IProjectConfiguration projectConfiguration)

public List<Action<IProjectTransformationResult>> AfterTransformation { get; } = new List<Action<IProjectTransformationResult>>();

public MethodGeneration GetMethodGeneration(IMethodSymbol methodSymbol)
{
return _methodGenerationFunction?.Invoke(methodSymbol) ?? MethodGeneration.Generate;
}

#region IFluentProjectTransformConfiguration

IProjectDocumentationCommentConfiguration IProjectTransformConfiguration.DocumentationComments => DocumentationComments;
Expand Down Expand Up @@ -133,6 +141,12 @@ IFluentProjectTransformConfiguration IFluentProjectTransformConfiguration.AfterT
return this;
}

IFluentProjectTransformConfiguration IFluentProjectTransformConfiguration.MethodGeneration(Func<IMethodSymbol, MethodGeneration> func)
{
_methodGenerationFunction = func ?? throw new ArgumentNullException(nameof(func));
return this;
}

#endregion

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,9 @@ private TypeDeclarationSyntax TransformField(FieldTransformationResult fieldTran
private TypeDeclarationSyntax TransformMethod(MethodTransformationResult methodTransform, TypeDeclarationSyntax newTypeNode, TypeTransformationResult transformResult,
INamespaceTransformationMetadata namespaceMetadata, SyntaxTrivia memberWhitespace, bool onlyMissingMembers)
{
if (methodTransform.AnalyzationResult.Conversion == MethodConversion.Ignore || (onlyMissingMembers && !methodTransform.AnalyzationResult.Missing))
if (methodTransform.AnalyzationResult.Conversion == MethodConversion.Ignore ||
(onlyMissingMembers && !methodTransform.AnalyzationResult.Missing) ||
_configuration.GetMethodGeneration(methodTransform.AnalyzationResult.Symbol) == MethodGeneration.Ignore)
{
// We need to add a whitespace trivia to keep directives as they will not have any leading whitespace
newTypeNode = newTypeNode.RemoveNodeKeepDirectives(methodTransform.Annotation, memberWhitespace, transformResult.EndOfLineTrivia);
Expand Down

0 comments on commit 1dd3d94

Please sign in to comment.