Fixed some crashes in response strings source generator, reorganized more submodules into their folders

This commit is contained in:
Kwoth
2022-01-02 03:49:54 +01:00
parent 9c590668df
commit 4b6af0e4ef
191 changed files with 120 additions and 80 deletions

View File

@@ -1,7 +1,8 @@
using System.CodeDom.Compiler;
using System.Collections;
#nullable enable
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -29,18 +30,34 @@ public class CmdAttribute : System.Attribute
public class MethodModel
{
public string Namespace { get; set; }
public IReadOnlyCollection<string> Classes { get; set; }
public string ReturnType { get; set; }
public string MethodName { get; set; }
public IEnumerable<string> Params { get; set; }
public string? Namespace { get; }
public IReadOnlyCollection<string> Classes { get; }
public string ReturnType { get; }
public string MethodName { get; }
public IEnumerable<string> Params { get; }
public MethodModel(string? ns, IReadOnlyCollection<string> classes, string returnType, string methodName, IEnumerable<string> @params)
{
Namespace = ns;
Classes = classes;
ReturnType = returnType;
MethodName = methodName;
Params = @params;
}
}
public class FileModel
{
public string Namespace { get; set; }
public IReadOnlyCollection<string> ClassHierarchy { get; set; }
public IReadOnlyCollection<MethodModel> Methods { get; set; }
public string? Namespace { get; }
public IReadOnlyCollection<string> ClassHierarchy { get; }
public IReadOnlyCollection<MethodModel> Methods { get; }
public FileModel(string? ns, IReadOnlyCollection<string> classHierarchy, IReadOnlyCollection<MethodModel> methods)
{
Namespace = ns;
ClassHierarchy = classHierarchy;
Methods = methods;
}
}
public void Initialize(IncrementalGeneratorInitializationContext context)
@@ -53,13 +70,13 @@ public class CmdAttribute : System.Attribute
.CreateSyntaxProvider(
static (node, _) => node is MethodDeclarationSyntax { AttributeLists.Count: > 0 },
static (ctx, cancel) => Transform(ctx, cancel))
.Where(static m => m != default)
.Where(static m => m.ChildTokens().Any(static x => x.IsKind(SyntaxKind.PublicKeyword)));
.Where(static m => m is not null)
.Where(static m => m!.ChildTokens().Any(static x => x.IsKind(SyntaxKind.PublicKeyword)));
var compilationMethods = context.CompilationProvider.Combine(methods.Collect());
context.RegisterSourceOutput(compilationMethods,
static (ctx, tuple) => RegisterAction(in ctx, tuple.Left, in tuple.Right));
static (ctx, tuple) => RegisterAction(in ctx, tuple.Left, in tuple.Right!));
}
private static void RegisterAction(in SourceProductionContext ctx,
@@ -137,8 +154,13 @@ public class CmdAttribute : System.Attribute
tw.WriteLine("// <AutoGenerated />");
tw.WriteLine("#pragma warning disable CS1066");
tw.WriteLine($"namespace {model.Namespace};");
if (model.Namespace is not null)
{
tw.WriteLine($"namespace {model.Namespace};");
tw.WriteLine();
}
foreach (var className in model.ClassHierarchy)
{
tw.WriteLine($"public partial class {className}");
@@ -176,13 +198,15 @@ public class CmdAttribute : System.Attribute
foreach (var group in groups)
{
if (cancel.IsCancellationRequested)
return new Collection<FileModel>();
var elems = group.ToList();
var model = new FileModel()
{
Methods = elems,
Namespace = elems[0].Namespace,
ClassHierarchy = elems[0].Classes
};
var model = new FileModel(
methods: elems,
ns: elems[0].Namespace,
classHierarchy: elems[0].Classes
);
models.Add(model);
}
@@ -195,53 +219,53 @@ public class CmdAttribute : System.Attribute
{
// SpinWait.SpinUntil(static () => Debugger.IsAttached);
var methodModel = new MethodModel();
var semanticModel = comp.GetSemanticModel(decl.SyntaxTree);
methodModel.Params = decl.ParameterList.Parameters
.Select(p =>
{
var prefix = p.Modifiers.Any(static x => x.IsKind(SyntaxKind.ParamsKeyword))
? "params "
: string.Empty;
var type = semanticModel
.GetTypeInfo(p.Type!)
.Type!
.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
var name = p.Identifier.Text;
var suffix = string.Empty;
if (p.Default is not null)
var methodModel = new MethodModel(
@params: decl.ParameterList.Parameters
.Select(p =>
{
if (p.Default.Value is LiteralExpressionSyntax)
var prefix = p.Modifiers.Any(static x => x.IsKind(SyntaxKind.ParamsKeyword))
? "params "
: string.Empty;
var type = semanticModel
.GetTypeInfo(p.Type!)
.Type!
.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
var name = p.Identifier.Text;
var suffix = string.Empty;
if (p.Default is not null)
{
suffix = " = " + p.Default.Value;
}
else if (p.Default.Value is MemberAccessExpressionSyntax maes)
{
var maesSemModel = comp.GetSemanticModel(maes.SyntaxTree);
var sym = maesSemModel.GetSymbolInfo(maes.Name);
if (sym.Symbol is null)
if (p.Default.Value is LiteralExpressionSyntax)
{
suffix = " = " + p.Default.Value;
}
else
else if (p.Default.Value is MemberAccessExpressionSyntax maes)
{
suffix = " = " + sym.Symbol.ToDisplayString();
var maesSemModel = comp.GetSemanticModel(maes.SyntaxTree);
var sym = maesSemModel.GetSymbolInfo(maes.Name);
if (sym.Symbol is null)
{
suffix = " = " + p.Default.Value;
}
else
{
suffix = " = " + sym.Symbol.ToDisplayString();
}
}
}
}
return $"{prefix}{type} {name}{suffix}";
})
.ToList();
methodModel.MethodName = decl.Identifier.Text;
methodModel.ReturnType = decl.ReturnType.ToString();
methodModel.Namespace = GetNamespace(decl);
methodModel.Classes = GetClasses(decl);
return $"{prefix}{type} {name}{suffix}";
})
.ToList(),
methodName: decl.Identifier.Text,
returnType: decl.ReturnType.ToString(),
ns: GetNamespace(decl),
classes: GetClasses(decl)
);
return methodModel;
}
@@ -266,10 +290,10 @@ public class CmdAttribute : System.Attribute
// }
//https://github.com/andrewlock/NetEscapades.EnumGenerators/blob/main/src/NetEscapades.EnumGenerators/EnumGenerator.cs
static string GetNamespace(MethodDeclarationSyntax declarationSyntax)
static string? GetNamespace(MethodDeclarationSyntax declarationSyntax)
{
// determine the namespace the class is declared in, if any
var nameSpace = string.Empty;
string? nameSpace = null;
var parentOfInterest = declarationSyntax.Parent;
while (parentOfInterest is not null)
{
@@ -294,7 +318,7 @@ public class CmdAttribute : System.Attribute
}
return default;
return nameSpace;
}
static IReadOnlyCollection<string> GetClasses(MethodDeclarationSyntax declarationSyntax)
@@ -317,7 +341,7 @@ public class CmdAttribute : System.Attribute
return classes;
}
private static MethodDeclarationSyntax Transform(GeneratorSyntaxContext ctx, CancellationToken cancel)
private static MethodDeclarationSyntax? Transform(GeneratorSyntaxContext ctx, CancellationToken cancel)
{
var methodDecl = (MethodDeclarationSyntax)ctx.Node;