mirror of
https://git.lewd.wtf/PGR/ascnet
synced 2026-02-04 21:22:10 +01:00
TableReaderV2 finally, caching pending, please migrate carefully
This commit is contained in:
144
AscNet.Table/TableGeneratorV2.cs
Normal file
144
AscNet.Table/TableGeneratorV2.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.IO;
|
||||
// using Newtonsoft.Json;
|
||||
|
||||
namespace AscNet.Table
|
||||
{
|
||||
[Generator]
|
||||
public class TableGeneratorV2 : ISourceGenerator
|
||||
{
|
||||
public void Execute(GeneratorExecutionContext context)
|
||||
{
|
||||
List<object> fails = new();
|
||||
foreach (var table in context.AdditionalFiles.Where(x => x.Path.EndsWith(".tsv")))
|
||||
{
|
||||
try
|
||||
{
|
||||
string ns = string.Join("", Path.GetDirectoryName(table.Path)?.Split(new string[] { "table" }, StringSplitOptions.None).Skip(1)!)
|
||||
.Replace('\\', '/').Replace('/', '.');
|
||||
|
||||
string content = (table.GetText()?.ToString()) ?? throw new FormatException("File is empty!");
|
||||
List<string> lines = content.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
|
||||
List<MemberType> members = new();
|
||||
List<MemberType> membersRealCount = new();
|
||||
string headLine = lines.First();
|
||||
lines.RemoveAt(0);
|
||||
|
||||
foreach (var head in headLine.Split('\t'))
|
||||
{
|
||||
if (head.Contains('['))
|
||||
{
|
||||
if (members.Any(x => x.Name == head.Split('[').First()))
|
||||
{
|
||||
MemberType memberType = members.First(x => x.Name == head.Split('[').First());
|
||||
memberType.Span++;
|
||||
}
|
||||
else
|
||||
{
|
||||
members.Add(new MemberType
|
||||
{
|
||||
Name = head.Split('[').First(),
|
||||
Nullable = false,
|
||||
Span = 1
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
members.Add(new MemberType
|
||||
{
|
||||
Name = head,
|
||||
Nullable = false,
|
||||
Span = 1
|
||||
});
|
||||
}
|
||||
membersRealCount.Add(members.First(x => x.Name == head.Split('[').First()));
|
||||
}
|
||||
|
||||
for (int x = 0; x < lines.Count; x++)
|
||||
{
|
||||
string[] values = lines[x].Split('\t');
|
||||
|
||||
for (int y = 0; y < values.Length; y++)
|
||||
{
|
||||
string value = values[y];
|
||||
MemberType memberType = membersRealCount[y];
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
memberType.Nullable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (int.TryParse(value, out int intVal))
|
||||
{
|
||||
if (memberType.Type != typeof(string).FullName)
|
||||
memberType.Type = typeof(int).FullName;
|
||||
}
|
||||
else
|
||||
{
|
||||
memberType.Type = typeof(string).FullName;
|
||||
}
|
||||
}
|
||||
membersRealCount[y] = memberType;
|
||||
}
|
||||
}
|
||||
|
||||
string propDefs = string.Empty;
|
||||
foreach (MemberType memberType in membersRealCount.GroupBy(x => x.Name).Select(g => g.First()))
|
||||
{
|
||||
if (string.IsNullOrEmpty(memberType.Type) || string.IsNullOrEmpty(memberType.Name))
|
||||
continue;
|
||||
|
||||
if (membersRealCount.Where(x => x.Name == memberType.Name).Count() > 1)
|
||||
{
|
||||
propDefs += $"public List<{memberType.Type}> {memberType.Name} {{ get; set; }}\r\n\t";
|
||||
}
|
||||
else
|
||||
{
|
||||
propDefs += $"public {memberType.Type + (memberType.Nullable ? "?" : string.Empty)} {memberType.Name} {{ get; set; }}\r\n\t";
|
||||
}
|
||||
}
|
||||
|
||||
string file = $@"// <auto-generated/>
|
||||
namespace AscNet.Table.V2{ns}
|
||||
{{
|
||||
#nullable enable
|
||||
#pragma warning disable CS8618, CS8602 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public class {Path.GetFileNameWithoutExtension(table.Path)}Table : global::AscNet.Common.Util.ITable
|
||||
{{
|
||||
public static string File => ""{string.Join("", table.Path.Replace("\\", "/").Split(new string[] { "/Resources/" }, StringSplitOptions.None).Skip(1))}"";
|
||||
|
||||
{propDefs}}}
|
||||
}}";
|
||||
|
||||
context.AddSource($"V2{ns}.{Path.GetFileNameWithoutExtension(table.Path)}V2.g.cs", file);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
fails.Add(new
|
||||
{
|
||||
msg = ex.ToString(),
|
||||
file = table.Path
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// File.WriteAllText("./generator_fails_new.json", JsonConvert.SerializeObject(fails, Formatting.Indented));
|
||||
}
|
||||
|
||||
public void Initialize(GeneratorInitializationContext context) { }
|
||||
|
||||
struct MemberType
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Type { get; set; }
|
||||
public bool Nullable { get; set; }
|
||||
public int Span { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user