Generation Update
A few changes to start adding more generation methods.
This commit is contained in:
parent
dd05aca370
commit
0cf7404b85
12
ServerDatabase.SourceGenerator/JsonIgnoreIndexAttribute.cs
Normal file
12
ServerDatabase.SourceGenerator/JsonIgnoreIndexAttribute.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace ServerDatabase.SourceGenerator;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public sealed class JsonIgnoreIndexAttribute : Attribute
|
||||
{
|
||||
public JsonIgnoreIndexAttribute(int index = 0)
|
||||
{
|
||||
this.Index = index;
|
||||
}
|
||||
|
||||
public int Index { get; private set; } = 0;
|
||||
}
|
14
ServerDatabase.SourceGenerator/JsonSubObjectAttribute.cs
Normal file
14
ServerDatabase.SourceGenerator/JsonSubObjectAttribute.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace ServerDatabase.SourceGenerator;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public sealed class JsonSubObjectAttribute : Attribute
|
||||
{
|
||||
public JsonSubObjectAttribute(Type type, int index = 0)
|
||||
{
|
||||
this.Type = type;
|
||||
this.Index = index;
|
||||
}
|
||||
|
||||
public int Index { get; private set; } = 0;
|
||||
public Type Type { get; private set; }
|
||||
}
|
14
ServerDatabase.SourceGenerator/JsonTableRowAttribute.cs
Normal file
14
ServerDatabase.SourceGenerator/JsonTableRowAttribute.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace ServerDatabase.SourceGenerator;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||
public sealed class JsonTableRowAttribute : Attribute
|
||||
{
|
||||
public JsonTableRowAttribute(Type type, int index = 0)
|
||||
{
|
||||
this.Type = type;
|
||||
this.Index = index;
|
||||
}
|
||||
|
||||
public int Index { get; private set; } = 0;
|
||||
public Type Type { get; private set; }
|
||||
}
|
130
ServerDatabase.SourceGenerator/JsonTableRowGenerator.cs
Normal file
130
ServerDatabase.SourceGenerator/JsonTableRowGenerator.cs
Normal file
@ -0,0 +1,130 @@
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using TypeInfo = Microsoft.CodeAnalysis.TypeInfo;
|
||||
|
||||
namespace ServerDatabase.SourceGenerator;
|
||||
|
||||
[Generator]
|
||||
public class JsonTableRowGenerator : ISourceGenerator
|
||||
{
|
||||
public void Initialize(GeneratorInitializationContext context)
|
||||
{
|
||||
#if DEBUG
|
||||
if (!Debugger.IsAttached) Debugger.Launch();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
INamedTypeSymbol? attributeSymbol = context.Compilation.GetTypeByMetadataName(typeof(JsonTableRowAttribute).FullName);
|
||||
|
||||
IEnumerable<SyntaxTree> classWithAttributes = context.Compilation.SyntaxTrees.Where(st => st.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>()
|
||||
.Any(p => p.DescendantNodes().OfType<AttributeSyntax>().Any()));
|
||||
|
||||
foreach (SyntaxTree? tree in classWithAttributes)
|
||||
{
|
||||
if (tree is null) continue;
|
||||
SemanticModel semanticModel = context.Compilation.GetSemanticModel(tree);
|
||||
foreach (ClassDeclarationSyntax? declaredClass in tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().Where(cd => cd.DescendantNodes().OfType<AttributeSyntax>().Any()))
|
||||
{
|
||||
if (declaredClass is null) continue;
|
||||
List<SyntaxToken>? nodes = declaredClass
|
||||
.DescendantNodes()
|
||||
.OfType<AttributeSyntax>()
|
||||
.FirstOrDefault(a => a.DescendantTokens().Any(dt => dt.IsKind(SyntaxKind.IdentifierToken) && dt.Parent is not null && semanticModel.GetTypeInfo(dt.Parent).Type is not null && semanticModel.GetTypeInfo(dt.Parent).Type.Name == attributeSymbol.Name))
|
||||
?.DescendantTokens()
|
||||
?.Where(dt => dt.IsKind(SyntaxKind.IdentifierToken))
|
||||
?.ToList();
|
||||
|
||||
if(nodes == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TypeInfo relatedClass = semanticModel.GetTypeInfo(nodes.Last().Parent);
|
||||
|
||||
StringBuilder generatedClass = this.GenerateClass(tree.GetRoot().DescendantNodes().OfType<FileScopedNamespaceDeclarationSyntax>().First().Name.ToString(), declaredClass);
|
||||
|
||||
foreach(IPropertySymbol? classProperty in relatedClass.Type.GetMembers().OfType<IPropertySymbol>())
|
||||
{
|
||||
this.GenerateProperty(classProperty, ref generatedClass);
|
||||
}
|
||||
|
||||
this.CloseClass(generatedClass);
|
||||
|
||||
context.AddSource($"{declaredClass.Identifier}_{relatedClass.Type.Name}.g.cs", SourceText.From(generatedClass.ToString(), Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
context.AddSource("teste.g.cs", SourceText.From(@$"// <auto-generated/>
|
||||
using System;
|
||||
namespace ServerDatabase.SourceGenerator.Generated
|
||||
{{
|
||||
public class bobe
|
||||
{{
|
||||
public string e = @""{e}"";
|
||||
}}
|
||||
}}", Encoding.UTF8));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private void GenerateProperty(IPropertySymbol prop, ref StringBuilder builder)
|
||||
{
|
||||
prop.GetAttributes().SelectMany(s => s.NamedArguments);
|
||||
string bad = prop.Type.ToString();
|
||||
Console.WriteLine(prop);
|
||||
bad = bad.Replace("ServerDatabase.TableColumn<", "");
|
||||
bad = bad.Remove(bad.LastIndexOf('>'));
|
||||
if (bad.ToLower() == "byte[]") bad = "string";
|
||||
EqualsValueClauseSyntax? equalsSyntax = prop.DeclaringSyntaxReferences[0].GetSyntax() switch
|
||||
{
|
||||
PropertyDeclarationSyntax property => property.Initializer,
|
||||
VariableDeclaratorSyntax variable => variable.Initializer,
|
||||
_ => throw new Exception("Unknown declaration syntax")
|
||||
};
|
||||
|
||||
// If the property/field has an initializer
|
||||
if (equalsSyntax is not null)
|
||||
{
|
||||
string valueAsStr = equalsSyntax.Value.ToString().Split('"')[1];
|
||||
builder.AppendLine($" [JsonInclude]");
|
||||
builder.AppendLine($" [JsonPropertyName(\"{valueAsStr}\")]");
|
||||
builder.AppendLine($" public {bad} {prop.Name} {{ get; set; }}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private StringBuilder GenerateClass(string n, ClassDeclarationSyntax og)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(@$"// <auto-generated/>
|
||||
using System;
|
||||
|
||||
namespace {n}
|
||||
{{
|
||||
public partial class " + og.Identifier);
|
||||
|
||||
sb.Append(@"
|
||||
{
|
||||
");
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
private void CloseClass(StringBuilder generatedClass)
|
||||
{
|
||||
generatedClass.Append(
|
||||
@" }
|
||||
}");
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<IncludeBuildOutput>true</IncludeBuildOutput>
|
||||
<Version>1.0.1</Version>
|
||||
<Version>1.0.2-alpha10</Version>
|
||||
<Title>Server Database Source Generator</Title>
|
||||
<Authors>JacobTech</Authors>
|
||||
</PropertyGroup>
|
||||
|
@ -59,7 +59,6 @@ public class TableRowGenerator : ISourceGenerator
|
||||
this.CloseClass(generatedClass);
|
||||
|
||||
context.AddSource($"{declaredClass.Identifier}_{relatedClass.Type.Name}.g.cs", SourceText.From(generatedClass.ToString(), Encoding.UTF8));
|
||||
//context.AddSource($"{declaredClass.Identifier}_{relatedClass.Type.Name}_goooddddd.g.cs", SourceText.From(generatedClass.ToString().Replace("partial ", "").Replace(declaredClass.Identifier.ToString(), declaredClass.Identifier.ToString() + "GODDD"), Encoding.UTF8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user