Skip to content

Commit 2b8ec2d

Browse files
authored
Merge pull request #134 from TheBoxyBear/109-use-source-generation-for-metadata-string-conversion
Use source generation for metadata string conversion
2 parents dda1eaf + 9c0b4fc commit 2b8ec2d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1706
-650
lines changed

ChartTools/Assembly.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("ChartTools.Tests")]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
using System.Runtime.CompilerServices;
2+
3+
[assembly: InternalsVisibleTo("ChartTools")]
4+
[assembly: InternalsVisibleTo("ChartTools.Generator")]
5+
[assembly: InternalsVisibleTo("ChartTools.Tests")]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0;net10.0</TargetFrameworks>
5+
<RootNamespace>ChartTools</RootNamespace>
6+
<LangVersion>14.0</LangVersion>
7+
</PropertyGroup>
8+
9+
</Project>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace ChartTools;
2+
3+
public enum FileType : byte { Chart, Ini, Midi }
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#if NETSTANDARD
2+
using System.ComponentModel;
3+
4+
#pragma warning disable IDE0130 // Namespace does not match folder structure
5+
namespace System.Runtime.CompilerServices;
6+
#pragma warning restore IDE0130 // Namespace does not match folder structure
7+
8+
[EditorBrowsable(EditorBrowsableState.Never)]
9+
public record class IsExternalInit;
10+
#endif
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using System;
2+
3+
namespace ChartTools.Meta;
4+
5+
[AttributeUsage(AttributeTargets.Property)]
6+
internal class MetadataGroupAttribute : Attribute { }
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
3+
namespace ChartTools.Meta;
4+
5+
/// <summary>
6+
/// Indicates that a property should be serialized with a specific key in a specific file format
7+
/// </summary>
8+
/// <param name="key"></param>
9+
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
10+
internal class MetadataKeyAttribute(FileType fileType, string key)
11+
: Attribute, IEquatable<MetadataKeyAttribute>
12+
{
13+
public FileType FileType { get; } = fileType;
14+
15+
/// <summary>
16+
/// Target key
17+
/// </summary>
18+
public string Key { get; } = key;
19+
20+
public bool ValueMappable = true;
21+
22+
public bool Equals(MetadataKeyAttribute other) =>
23+
ReferenceEquals(other, this) ||
24+
other.FileType == FileType &&
25+
other.Key == Key &&
26+
other.ValueMappable == ValueMappable;
27+
28+
public override bool Equals(object obj)
29+
=> obj is MetadataKeyAttribute other && Equals(other);
30+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<LangVersion>14.0</LangVersion>
6+
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
12+
<PrivateAssets>all</PrivateAssets>
13+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
14+
</PackageReference>
15+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<ProjectReference Include="..\ChartTools.Common\ChartTools.Common.csproj" OutputItemType="Analyzer" />
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace ChartTools.Generator;
6+
7+
internal class CodeBuilder(StringBuilder? builder = default)
8+
{
9+
public CodeBuilder(string value)
10+
: this(new StringBuilder(value)) { }
11+
12+
public CodeBuilder(int indent, StringBuilder? builder = default)
13+
: this(builder)
14+
=> m_indent = new('\t', indent);
15+
16+
public StringBuilder StringBuilder { get; } = builder ?? new();
17+
18+
private readonly Stack<char> m_contextStack = [];
19+
private string m_indent = string.Empty;
20+
21+
private static readonly Dictionary<char, char> m_contextClosers = new()
22+
{
23+
{ '(', ')' },
24+
{ '{', '}' },
25+
{ '[', ']' },
26+
{ '"', '"' }
27+
};
28+
29+
public CodeBuilder StartContext(char openChar, bool newLine = true)
30+
{
31+
if (newLine)
32+
StringBuilder.AppendLine(m_indent + openChar);
33+
else
34+
StringBuilder.Append(m_indent + openChar);
35+
36+
m_contextStack.Push(openChar);
37+
m_indent += '\t';
38+
39+
return this;
40+
}
41+
42+
public CodeBuilder EndContext(bool newLine = true)
43+
{
44+
if (m_contextStack.Count == 0)
45+
throw new InvalidOperationException("No context to end.");
46+
47+
char openChar = m_contextStack.Pop();
48+
49+
if (!m_contextClosers.TryGetValue(openChar, out char closeChar))
50+
throw new InvalidOperationException($"No closing character defined for '{openChar}'.");
51+
52+
m_indent = m_indent.Substring(0, m_indent.Length - 2);
53+
54+
if (newLine)
55+
StringBuilder.AppendLine(m_indent + closeChar);
56+
else
57+
StringBuilder.Append(m_indent + closeChar);
58+
59+
return this;
60+
}
61+
62+
public CodeBuilder AppendLine(string line)
63+
{
64+
StringBuilder.AppendLine(m_indent + line);
65+
return this;
66+
}
67+
68+
public CodeBuilder AppendLine()
69+
{
70+
StringBuilder.AppendLine(m_indent);
71+
return this;
72+
}
73+
74+
public CodeBuilder Append(string text)
75+
{
76+
StringBuilder.Append(m_indent + text);
77+
return this;
78+
}
79+
80+
public override string ToString()
81+
=> StringBuilder.ToString();
82+
83+
public static implicit operator StringBuilder(CodeBuilder builder)
84+
=> builder.StringBuilder;
85+
}

0 commit comments

Comments
 (0)