Skip to content

Commit d2dbef9

Browse files
authored
Merge pull request #13 from aka-nse/release/v0.1.4
release/v0.1.4
2 parents b5e20b7 + 762daf2 commit d2dbef9

File tree

8 files changed

+205
-51
lines changed

8 files changed

+205
-51
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,8 @@ Apache License Version 2.0
159159
### v0.1.3
160160

161161
- Supports parameter modifiers (`ref`/`in`/`out`)
162+
163+
### v0.1.4
164+
165+
- Supports struct/interface
166+
- Supports inner type
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// See https://aka.ms/new-console-template for more information
22
using GenericSpecializationGenerator.DebugApp;
33

4+
SampleInnerClass.InnerDerivedClass.Example1Derived(42);
45
Console.WriteLine("Hello, World!");
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Numerics;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using GenericSpecialization;
8+
9+
namespace GenericSpecializationGenerator.DebugApp;
10+
11+
internal partial class SampleInnerClass
12+
{
13+
public partial class InnerBaseClass
14+
{
15+
[PrimaryGeneric(nameof(Example1Default))]
16+
private protected static partial void Example1<T>(T input) where T : unmanaged, INumber<T>;
17+
18+
private static void Example1Default<T>(T input)
19+
{
20+
Console.WriteLine($"default");
21+
}
22+
23+
private static void Example1(int input)
24+
{
25+
Console.WriteLine($"int specialized");
26+
}
27+
28+
private static void Example1(double input)
29+
{
30+
Console.WriteLine($"double specialized");
31+
}
32+
}
33+
34+
public class InnerDerivedClass : InnerBaseClass
35+
{
36+
public static void Example1Derived<T>(T input) where T : unmanaged, INumber<T>
37+
=> Example1(input);
38+
}
39+
}
Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
// #define TEST_STATIC_FOO_1
2-
#define TEST_STATIC_FOO_2
3-
// #define TEST_STATIC_BAR
4-
// #define TEST_STATIC_BAZ
1+
// #define TEST_STATIC_1
2+
// #define TEST_STATIC_2
3+
// #define TEST_STATIC_3
4+
// #define TEST_STATIC_4
5+
// #define TEST_STATIC_5
6+
// #define TEST_STATIC_6
57

68
using System;
79
using System.Collections.Generic;
@@ -15,120 +17,152 @@ namespace GenericSpecializationGenerator.DebugApp;
1517

1618
static partial class SampleStaticClass
1719
{
18-
#if TEST_STATIC_FOO_1
20+
#if TEST_STATIC_1
1921

20-
[PrimaryGeneric(nameof(FooDefault))]
21-
public static partial void Foo<T>(T input) where T : unmanaged, INumber<T>;
22+
[PrimaryGeneric(nameof(Example1Default))]
23+
public static partial void Example1<T>(T input) where T : unmanaged, INumber<T>;
2224

23-
private static void FooDefault<T>(T input)
25+
private static void Example1Default<T>(T input)
2426
{
2527
Console.WriteLine($"default");
2628
}
2729

28-
private static void Foo(int input)
30+
private static void Example1(int input)
2931
{
3032
Console.WriteLine($"int specialized");
3133
}
3234

33-
private static void Foo(double input)
35+
private static void Example1(double input)
3436
{
3537
Console.WriteLine($"double specialized");
3638
}
3739

3840
#endif
3941

40-
#if TEST_STATIC_FOO_2
42+
#if TEST_STATIC_2
4143

42-
[PrimaryGeneric(nameof(FooDefault))]
43-
public static partial void Foo<T>(T input, ref int refArg, in int inArg, out int outArg) where T : unmanaged, INumber<T>;
44+
[PrimaryGeneric(nameof(Example2Default))]
45+
public static partial void Example2<T>(T input, ref int refArg, in int inArg, out int outArg) where T : unmanaged, INumber<T>;
4446

45-
private static void FooDefault<T>(T input, ref int refArg, in int inArg, out int outArg)
47+
private static void Example2Default<T>(T input, ref int refArg, in int inArg, out int outArg)
4648
{
4749
Console.WriteLine($"default");
4850
outArg = refArg + inArg;
4951
}
5052

51-
private static void Foo(int input, ref int refArg, in int inArg, out int outArg)
53+
private static void Example2(int input, ref int refArg, in int inArg, out int outArg)
5254
{
5355
Console.WriteLine($"int specialized");
5456
outArg = refArg + inArg;
5557
}
5658

57-
private static void Foo(double input, ref int refArg, in int inArg, out int outArg)
59+
private static void Example2(double input, ref int refArg, in int inArg, out int outArg)
5860
{
5961
Console.WriteLine($"double specialized");
6062
outArg = refArg + inArg;
6163
}
6264

6365
#endif
6466

65-
#if TEST_STATIC_BAR
67+
#if TEST_STATIC_3
6668

67-
[PrimaryGeneric(nameof(BarDefault))]
68-
public static partial T Bar<T>(T input);
69+
[PrimaryGeneric(nameof(Example3Default))]
70+
public static partial T Example3<T>(T input);
6971

70-
private static T BarDefault<T>(T input)
72+
private static T Example3Default<T>(T input)
7173
{
7274
Console.WriteLine($"default");
7375
return input;
7476
}
7577

76-
private static int Bar(int input)
78+
private static int Example3(int input)
7779
{
7880
Console.WriteLine($"int specialized");
7981
return input;
8082
}
8183

82-
private static double Bar(double input)
84+
private static double Example3(double input)
8385
{
8486
Console.WriteLine($"double specialized");
8587
return input;
8688
}
8789

8890
#endif
8991

90-
#if TEST_STATIC_BAZ
92+
#if TEST_STATIC_4
9193

92-
[PrimaryGeneric(nameof(BazDefault))]
93-
public static partial T1 Baz<T1, T2>(T1 x, T2 y)
94+
[PrimaryGeneric(nameof(Example4Default))]
95+
public static partial T1 Example4<T1, T2>(T1 x, T2 y)
9496
where T1 : unmanaged, INumber<T1>
9597
where T2 : unmanaged, INumberBase<T2>, IComparable<T2>;
9698

97-
private static T1 BazDefault<T1, T2>(T1 x, T2 y)
99+
private static T1 Example4Default<T1, T2>(T1 x, T2 y)
98100
{
99101
Console.WriteLine($"default");
100102
return x;
101103
}
102104

103-
private static int Baz(int x, int y)
105+
private static int Example4(int x, int y)
104106
{
105107
Console.WriteLine($"(int, int) specialized");
106108
return x;
107109
}
108110

109-
private static double Baz(double x, int y)
111+
private static double Example4(double x, int y)
110112
{
111113
Console.WriteLine($"(double, int) specialized");
112114
return x;
113115
}
114116

115-
private static int Baz(int x, double y)
117+
private static int Example4(int x, double y)
116118
{
117119
Console.WriteLine($"(int, double) specialized");
118120
return x;
119121
}
120122

121-
private static double Baz(double x, double y)
123+
private static double Example4(double x, double y)
122124
{
123125
Console.WriteLine($"(double, double) specialized");
124126
return y;
125127
}
126128

127-
private static string Baz(string x, double y)
129+
private static string Example4(string x, double y)
128130
{
129131
Console.WriteLine($"(string, double) specialized");
130132
return x;
131133
}
132134

135+
#endif
136+
137+
#if TEST_STATIC_5
138+
139+
[PrimaryGeneric(nameof(Example5Default))]
140+
public static partial Vector<T> Example5<T>(Vector<T> x, Vector<T> y)
141+
where T : unmanaged, INumber<T>;
142+
143+
144+
private static Vector<T> Example5Default<T>(Vector<T> x, Vector<T> y)
145+
where T : unmanaged, INumber<T>
146+
=> default;
147+
148+
private static Vector<int> Example5(Vector<int> x, Vector<int> y)
149+
=> x + y;
150+
151+
#endif
152+
153+
#if TEST_STATIC_6
154+
155+
[PrimaryGeneric(nameof(Example6Default))]
156+
public static partial Vector<T> Example6<T>(Vector<T> x, T y)
157+
where T : unmanaged, INumber<T>;
158+
159+
160+
private static Vector<T> Example6Default<T>(Vector<T> x, T y)
161+
where T : unmanaged, INumber<T>
162+
=> default;
163+
164+
private static Vector<int> Example6(Vector<int> x, int y)
165+
=> x + new Vector<int>(y);
166+
133167
#endif
134168
}

src/GenericSpecializationGenerator/GenericSpecializationGenerator.MethodImpl.cs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ protected GenerationLogic() { }
1212

1313
public string GenerateSpecializedMethod(
1414
SyntaxList<UsingDirectiveSyntax> usings,
15-
INamedTypeSymbol ownerClass,
15+
INamedTypeSymbol ownerType,
1616
MethodDeclarationInfo method,
1717
string defaultMethodName,
1818
MethodSpecialization[] specializedMethods)
1919
{
20-
var ns = ownerClass.ContainingNamespace.IsGlobalNamespace
20+
var ns = ownerType.ContainingNamespace.IsGlobalNamespace
2121
? ""
22-
: $"namespace {ownerClass.ContainingNamespace};";
22+
: $"namespace {ownerType.ContainingNamespace};";
23+
var (typeInitializer, typeTerminator) = GetTypeDefinition(ownerType);
2324

2425
SourceCodeGenerationHandler generator = $$"""
2526
// <auto-generated/>
@@ -33,8 +34,7 @@ public string GenerateSpecializedMethod(
3334
using __Unsafe = System.Runtime.CompilerServices.Unsafe;
3435
{{ns}}
3536
36-
partial class {{ownerClass.Name}}
37-
{
37+
{{typeInitializer}}
3838
#if NETCOREAPP3_0_OR_GREATER
3939
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
4040
#endif
@@ -43,7 +43,8 @@ partial class {{ownerClass.Name}}
4343
{{specializedMethods.Select(GetSpecializedCode)}}
4444
{{GetDefaultReturn(method.Symbol, defaultMethodName)}}
4545
}
46-
}
46+
47+
{{typeTerminator}}
4748
""";
4849
return generator.ToString();
4950
}
@@ -67,6 +68,26 @@ protected SourceCodeGenerationHandler GetSpecializedCode(MethodSpecialization sp
6768

6869
protected abstract SourceCodeGenerationHandler GetDefaultReturn(IMethodSymbol methodSymbol, string defaultMethodName);
6970

71+
private static (string initializer, string terminator) GetTypeDefinition(INamedTypeSymbol ownerType)
72+
{
73+
var initializer = "";
74+
var terminator = "";
75+
76+
for(var type = ownerType; type is not null; type = type.ContainingType)
77+
{
78+
var typeInitializer = type.TypeKind switch
79+
{
80+
TypeKind.Class => $"partial class {type.Name}",
81+
TypeKind.Struct => $"partial struct {type.Name}",
82+
TypeKind.Interface => $"partial interface {type.Name}",
83+
_ => throw new ArgumentException(),
84+
};
85+
initializer = typeInitializer + " { " + initializer;
86+
terminator += "} ";
87+
}
88+
return (initializer, terminator);
89+
}
90+
7091
private static string GetCondition(IEnumerable<ITypeSymbol> openTypeArgs, IEnumerable<INamedTypeSymbol> closedTypeArgs)
7192
{
7293
static string core(ITypeSymbol open, INamedTypeSymbol closed)
@@ -147,7 +168,7 @@ private class GenerationNonVoidReturnLogic : GenerationLogic
147168
protected override SourceCodeGenerationHandler GetReturn(IMethodSymbol methodSymbol, MethodSpecialization specialized)
148169
=> $$"""
149170
var {{specialized.VariablePrefix}}retval = {{methodSymbol.Name}}({{GetSpecializedCallParameters(methodSymbol, specialized)}});
150-
return System.Runtime.CompilerServices.Unsafe.As<{{specialized.SpecializedMethod.ReturnType}}, {{methodSymbol.ReturnType}}>(ref {{specialized.VariablePrefix}}retval);
171+
return __Unsafe.As<{{specialized.SpecializedMethod.ReturnType}}, {{methodSymbol.ReturnType}}>(ref {{specialized.VariablePrefix}}retval);
151172
""";
152173

153174
protected override SourceCodeGenerationHandler GetDefaultReturn(IMethodSymbol methodSymbol, string defaultMethodName)

src/GenericSpecializationGenerator/GenericSpecializationGenerator.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,20 @@ private static void Emit(
5858
.ToArray();
5959

6060
static string getParamName(IParameterSymbol p)
61-
=> p.RefKind switch
61+
{
62+
var name = $"{p.Type}";
63+
name = name.Replace("<", "_").Replace(">", "_").Replace(",", "_");
64+
return p.RefKind switch
6265
{
63-
RefKind.None => $"{p.Type}",
66+
RefKind.None => $"{name}",
6467
RefKind.Ref or
6568
RefKind.Out or
66-
RefKind.In => $"ref_{p.Type}",
69+
RefKind.In => $"ref_{name}",
6770
_ => throw new InvalidOperationException(),
6871
};
72+
}
6973

70-
var hintName = $"{ownerClass.Name}.{method.Symbol.Name}-{string.Join("-", method.Symbol.Parameters.Select(getParamName))}+Specialized.g.cs";
74+
var hintName = $"{ownerClass.ToDisplayString()}.{method.Symbol.Name}-{string.Join("-", method.Symbol.Parameters.Select(getParamName))}+Specialized.g.cs";
7175
context.AddSource(
7276
hintName,
7377
GenerateSpecializedMethod(usings, ownerClass, method, defaultMethod, specializedMethods));

src/GenericSpecializationGenerator/GenericSpecializationGenerator.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
<PackageId>akanse.$(AssemblyName)</PackageId>
1717
<Title>GenericSpecializationGenerator</Title>
18-
<Version>0.1.3.0</Version>
18+
<Version>0.1.4.0</Version>
1919
<Authors>aka-nse</Authors>
2020
<Company />
2121
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>

0 commit comments

Comments
 (0)