aboutsummaryrefslogtreecommitdiffstats
path: root/src/EndpointGenerator.cs
diff options
context:
space:
mode:
authorivarlovlie <git@ivarlovlie.no>2022-12-21 19:14:48 +0100
committerivarlovlie <git@ivarlovlie.no>2022-12-21 19:14:48 +0100
commitdfb5b08f26573799a7254b64e022759ed4acf102 (patch)
tree0829ea32cbaa82921f75c4bbb09f19925a1078ca /src/EndpointGenerator.cs
parent09250198cdd7a7c13bc50664ef3c8b51bdc1ea8b (diff)
downloaddotnet-endpoints-dfb5b08f26573799a7254b64e022759ed4acf102.tar.xz
dotnet-endpoints-dfb5b08f26573799a7254b64e022759ed4acf102.zip
feat: latest, not working
Diffstat (limited to 'src/EndpointGenerator.cs')
-rw-r--r--src/EndpointGenerator.cs184
1 files changed, 0 insertions, 184 deletions
diff --git a/src/EndpointGenerator.cs b/src/EndpointGenerator.cs
deleted file mode 100644
index c0b7c1b..0000000
--- a/src/EndpointGenerator.cs
+++ /dev/null
@@ -1,184 +0,0 @@
-using System.Text.RegularExpressions;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-
-namespace I2R.Endpoints;
-
-[Generator]
-public class EndpointGenerator : ISourceGenerator
-{
- private const string SourceGenereatedComment = "// Generated, probably smart to leave it be";
-
- public void Initialize(GeneratorInitializationContext context) {
- context.RegisterForSyntaxNotifications(() => new EndpointFinder());
- }
-
- private Diagnostic CreateDebugDiagnostic(string message) {
- var descriptor = new DiagnosticDescriptor("debug", "Debug", message, "debug", DiagnosticSeverity.Warning, true);
- return Diagnostic.Create(descriptor, null, "");
- }
-
- public class NeededInfo
- {
- public string BaseEndpointClassName { get; set; }
- public string BaseEnpointNamespaceName { get; set; }
- }
-
- private NeededInfo ExtractNeededInfo(ClassDeclarationSyntax classDeclarationSyntax) {
- var baseType = classDeclarationSyntax.BaseList?.Types.FirstOrDefault();
- if (baseType == default) {
- return default;
- }
-
- var fullTypeName = baseType?.Type.ToString();
- var typeNamespace = GetNamespace(baseType);
- var className = Regex.Match(fullTypeName, "(!?<).+?(?=>)").Value.Replace("<", "");
- return new NeededInfo() {
- BaseEndpointClassName = className,
- BaseEnpointNamespaceName = typeNamespace
- };
- }
-
- public void Execute(GeneratorExecutionContext context) {
- var asyncEndpoints = ((EndpointFinder) context.SyntaxReceiver)?.AsyncEndpoints;
- var syncEndpoints = ((EndpointFinder) context.SyntaxReceiver)?.SyncEndpoints;
- if (asyncEndpoints == null) {
- context.ReportDiagnostic(CreateDebugDiagnostic("no endpoints were found"));
- return;
- }
-
- foreach (var endpoint in syncEndpoints) {
- var info = ExtractNeededInfo(endpoint);
- context.AddSource(info.BaseEndpointClassName + "s.g.cs", GetSyncSource(info.BaseEndpointClassName, info.BaseEnpointNamespaceName));
- }
-
- foreach (var endpoint in asyncEndpoints) {
- var info = ExtractNeededInfo(endpoint);
- context.AddSource(info.BaseEndpointClassName + "s.g.cs", GetAsyncSource(info.BaseEndpointClassName, info.BaseEnpointNamespaceName));
- }
- }
-
- private string GetSyncSource(string className, string namespaceName) {
- return $@"
-{SourceGenereatedComment}
-namespace {namespaceName};
-public static partial class SyncEndpoint<T{className}>
-{{
- public static class Req<TRequest>
- {{
- public abstract class Res<TResponse> : {className}
- {{
- public abstract TResponse Handle(
- TRequest request
- );
- }}
-
- public abstract class NoRes : {className}
- {{
- public abstract void Handle(
- TRequest request
- );
- }}
- }}
-
- public static class NoReq
- {{
- public abstract class Res<TResponse> : {className}
- {{
- public abstract TResponse Handle();
- }}
-
- public abstract class NoRes : {className}
- {{
- public abstract void Handle();
- }}
- }}
-}}
-";
- }
-
- private string GetAsyncSource(string className, string namespaceName) {
- return $@"
-{SourceGenereatedComment}
-namespace {namespaceName};
-public static partial class AsyncEndpoint<T>
-{{
- public static class Req<TRequest>
- {{
- public abstract class Res<TResponse> : {className}
- {{
- public abstract Task<TResponse> HandleAsync(
- TRequest request,
- CancellationToken cancellationToken = default
- );
- }}
-
- public abstract class NoRes : {className}
- {{
- public abstract Task HandleAsync(
- TRequest request,
- CancellationToken cancellationToken = default
- );
- }}
- }}
-
- public static class NoReq
- {{
- public abstract class Res<TResponse> : {className}
- {{
- public abstract Task<TResponse> HandleAsync(
- CancellationToken cancellationToken = default
- );
- }}
-
- public abstract class NoRes : {className}
- {{
- public abstract Task HandleAsync(
- CancellationToken cancellationToken = default
- );
- }}
- }}
-}}
-";
- }
-
- // determine the namespace the class/enum/struct is declared in, if any
- static string GetNamespace(BaseTypeSyntax syntax) {
- // If we don't have a namespace at all we'll return an empty string
- // This accounts for the "default namespace" case
- var nameSpace = string.Empty;
-
- // Get the containing syntax node for the type declaration
- // (could be a nested type, for example)
- var potentialNamespaceParent = syntax.Parent;
-
- // Keep moving "out" of nested classes etc until we get to a namespace
- // or until we run out of parents
- while (potentialNamespaceParent != null &&
- potentialNamespaceParent is not NamespaceDeclarationSyntax
- && potentialNamespaceParent is not FileScopedNamespaceDeclarationSyntax) {
- potentialNamespaceParent = potentialNamespaceParent.Parent;
- }
-
- // Build up the final namespace by looping until we no longer have a namespace declaration
- if (potentialNamespaceParent is BaseNamespaceDeclarationSyntax namespaceParent) {
- // We have a namespace. Use that as the type
- nameSpace = namespaceParent.Name.ToString();
-
- // Keep moving "out" of the namespace declarations until we
- // run out of nested namespace declarations
- while (true) {
- if (namespaceParent.Parent is not NamespaceDeclarationSyntax parent) {
- break;
- }
-
- // Add the outer namespace as a prefix to the final namespace
- nameSpace = $"{namespaceParent.Name}.{nameSpace}";
- namespaceParent = parent;
- }
- }
-
- // return the final namespace
- return nameSpace;
- }
-} \ No newline at end of file