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>
|
<Nullable>enable</Nullable>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<IncludeBuildOutput>true</IncludeBuildOutput>
|
<IncludeBuildOutput>true</IncludeBuildOutput>
|
||||||
<Version>1.0.1</Version>
|
<Version>1.0.2-alpha10</Version>
|
||||||
<Title>Server Database Source Generator</Title>
|
<Title>Server Database Source Generator</Title>
|
||||||
<Authors>JacobTech</Authors>
|
<Authors>JacobTech</Authors>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -59,7 +59,6 @@ public class TableRowGenerator : ISourceGenerator
|
|||||||
this.CloseClass(generatedClass);
|
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}.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