Skip to content

Commit 1532364

Browse files
committed
Init
1 parent b549af2 commit 1532364

13 files changed

+646
-48
lines changed

src/Files.App.CsWin32/Files.App.CsWin32.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,9 @@
1818
<PackageReference Include="Dongle.GuidRVAGen" />
1919
</ItemGroup>
2020

21+
<ItemGroup>
22+
<ProjectReference Include="..\Files.Shared\Files.Shared.csproj" />
23+
<ProjectReference Include="..\Files.Core.SourceGenerator\Files.Core.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
24+
</ItemGroup>
25+
2126
</Project>

src/Files.App.CsWin32/IStorageProviderQuotaUI.cs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,19 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4+
using Files.Shared.Attributes;
45
using System;
5-
using System.Runtime.CompilerServices;
66
using Windows.Win32.Foundation;
77

88
namespace Windows.Win32.System.WinRT
99
{
1010
public unsafe partial struct IStorageProviderQuotaUI : IComIID
1111
{
12-
#pragma warning disable CS0649 // Field 'field' is never assigned to, and will always have its default value 'value'
13-
private void** lpVtbl;
14-
#pragma warning restore CS0649 // Field 'field' is never assigned to, and will always have its default value 'value'
12+
[GeneratedVTableFunction(Index = 6)]
13+
public partial HRESULT GetQuotaTotalInBytes(ulong* value);
1514

16-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
17-
public HRESULT GetQuotaTotalInBytes(ulong* value)
18-
{
19-
return (HRESULT)((delegate* unmanaged[MemberFunction]<IStorageProviderQuotaUI*, ulong*, int>)(lpVtbl[6]))((IStorageProviderQuotaUI*)Unsafe.AsPointer(ref this), value);
20-
}
21-
22-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
23-
public HRESULT GetQuotaUsedInBytes(ulong* value)
24-
{
25-
return (HRESULT)((delegate* unmanaged[MemberFunction]<IStorageProviderQuotaUI*, ulong*, int>)(lpVtbl[8]))((IStorageProviderQuotaUI*)Unsafe.AsPointer(ref this), value);
26-
}
15+
[GeneratedVTableFunction(Index = 8)]
16+
public partial HRESULT GetQuotaUsedInBytes(ulong* value);
2717

2818
[GuidRVAGen.Guid("BA6295C3-312E-544F-9FD5-1F81B21F3649")]
2919
public static partial ref readonly Guid Guid { get; }

src/Files.App.CsWin32/IStorageProviderStatusUI.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4+
using Files.Shared.Attributes;
45
using System;
5-
using System.Runtime.CompilerServices;
66
using Windows.Win32.Foundation;
77

88
namespace Windows.Win32.System.WinRT
99
{
1010
public unsafe partial struct IStorageProviderStatusUI : IComIID
1111
{
12-
#pragma warning disable CS0649 // Field 'field' is never assigned to, and will always have its default value 'value'
13-
private void** lpVtbl;
14-
#pragma warning restore CS0649 // Field 'field' is never assigned to, and will always have its default value 'value'
15-
16-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
17-
public HRESULT GetQuotaUI(IStorageProviderQuotaUI** result)
18-
{
19-
return (HRESULT)((delegate* unmanaged[MemberFunction]<IStorageProviderStatusUI*, IStorageProviderQuotaUI**, int>)lpVtbl[14])((IStorageProviderStatusUI*)Unsafe.AsPointer(ref this), result);
20-
}
12+
[GeneratedVTableFunction(Index = 14)]
13+
public partial HRESULT GetQuotaUI(IStorageProviderQuotaUI** result);
2114

2215
[GuidRVAGen.Guid("D6B6A758-198D-5B80-977F-5FF73DA33118")]
2316
public static partial ref readonly Guid Guid { get; }

src/Files.App.CsWin32/IStorageProviderStatusUISource.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4+
using Files.Shared.Attributes;
45
using System;
5-
using System.Runtime.CompilerServices;
66
using Windows.Win32.Foundation;
77

88
namespace Windows.Win32.System.WinRT
99
{
1010
public unsafe partial struct IStorageProviderStatusUISource : IComIID
1111
{
12-
#pragma warning disable CS0649 // Field 'field' is never assigned to, and will always have its default value 'value'
13-
private void** lpVtbl;
14-
#pragma warning restore CS0649 // Field 'field' is never assigned to, and will always have its default value 'value'
15-
16-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
17-
public HRESULT GetStatusUI(IStorageProviderStatusUI** result)
18-
{
19-
return (HRESULT)((delegate* unmanaged[MemberFunction]<IStorageProviderStatusUISource*, IStorageProviderStatusUI**, int>)lpVtbl[6])((IStorageProviderStatusUISource*)Unsafe.AsPointer(ref this), result);
20-
}
12+
[GeneratedVTableFunction(Index = 6)]
13+
public partial HRESULT GetStatusUI(IStorageProviderStatusUI** result);
2114

2215
[GuidRVAGen.Guid("A306C249-3D66-5E70-9007-E43DF96051FF")]
2316
public static partial ref readonly Guid Guid { get; }

src/Files.App.CsWin32/IStorageProviderStatusUISourceFactory.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,16 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4+
using Files.Shared.Attributes;
45
using System;
5-
using System.Runtime.CompilerServices;
66
using Windows.Win32.Foundation;
77

88
namespace Windows.Win32.System.WinRT
99
{
1010
public unsafe partial struct IStorageProviderStatusUISourceFactory : IComIID
1111
{
12-
#pragma warning disable CS0649 // Field 'field' is never assigned to, and will always have its default value 'value'
13-
private void** lpVtbl;
14-
#pragma warning restore CS0649 // Field 'field' is never assigned to, and will always have its default value 'value'
15-
16-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
17-
public HRESULT GetStatusUISource(nint syncRootId, IStorageProviderStatusUISource** result)
18-
{
19-
return (HRESULT)((delegate* unmanaged[MemberFunction]<IStorageProviderStatusUISourceFactory*, nint, IStorageProviderStatusUISource**, int>)lpVtbl[6])((IStorageProviderStatusUISourceFactory*)Unsafe.AsPointer(ref this), syncRootId, result);
20-
}
12+
[GeneratedVTableFunction(Index = 6)]
13+
public partial HRESULT GetStatusUISource(nint syncRootId, IStorageProviderStatusUISource** result);
2114

2215
[GuidRVAGen.Guid("12E46B74-4E5A-58D1-A62F-0376E8EE7DD8")]
2316
public static partial ref readonly Guid Guid { get; }

src/Files.App.CsWin32/NativeMethods.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,7 @@ WinVerifyTrust
251251
FileTimeToSystemTime
252252
FileTimeToLocalFileTime
253253
SystemTimeToFileTime
254-
CRYPTOAPI_BLOB
255254
CMSG_SIGNER_INFO
256-
SignDataHandle
257255
CRYPT_ATTRIBUTE
258256
FILETIME
259257
CRYPT_BIT_BLOB
@@ -266,6 +264,5 @@ CATALOG_INFO
266264
WINTRUST_FILE_INFO
267265
WINTRUST_DATA
268266
HCERTSTORE
269-
HCRYPTMSG
270267
CERT_QUERY_ENCODING_TYPE
271268
CertGetNameString
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.Core.SourceGenerator.Data
5+
{
6+
internal record ParameterTypeNamePair(string FullyQualifiedTypeName, string ValueName);
7+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.Core.SourceGenerator.Data
5+
{
6+
internal record VTableFunctionInfo(
7+
string FullyQualifiedParentTypeName,
8+
string ParentTypeNamespace,
9+
string ParentTypeName,
10+
string Name,
11+
string ReturnTypeName,
12+
int Index,
13+
EquatableArray<ParameterTypeNamePair> Parameters);
14+
}

src/Files.Core.SourceGenerator/Files.Core.SourceGenerator.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<PlatformTarget>AnyCPU</PlatformTarget>
1010
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
1111
<Configurations>Debug;Release</Configurations>
12+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
1213
</PropertyGroup>
1314

1415
<ItemGroup>
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright (c) Files Community
2+
// Licensed under the MIT License.
3+
4+
namespace Files.Core.SourceGenerator.Generators
5+
{
6+
[Generator(LanguageNames.CSharp)]
7+
internal class VTableFunctionGenerator : IIncrementalGenerator
8+
{
9+
public void Initialize(IncrementalGeneratorInitializationContext context)
10+
{
11+
var sources = context.SyntaxProvider.ForAttributeWithMetadataName(
12+
"Files.Shared.Attributes.GeneratedVTableFunctionAttribute",
13+
static (node, token) =>
14+
{
15+
token.ThrowIfCancellationRequested();
16+
17+
// Check if the method has partial modifier and is public or internal (and not static)
18+
if (node is not MethodDeclarationSyntax { AttributeLists.Count: > 0 } method ||
19+
!method.Modifiers.Any(SyntaxKind.PartialKeyword) ||
20+
!(method.Modifiers.Any(SyntaxKind.PublicKeyword) || method.Modifiers.Any(SyntaxKind.InternalKeyword)) ||
21+
method.Modifiers.Any(SyntaxKind.StaticKeyword))
22+
return false;
23+
24+
// Check if the type containing the method has partial modifier and is a struct
25+
if (node.Parent is not TypeDeclarationSyntax { Keyword.RawKind: (int)SyntaxKind.StructKeyword, Modifiers: { } modifiers } ||
26+
!modifiers.Any(SyntaxKind.PartialKeyword))
27+
return false;
28+
29+
return true;
30+
},
31+
static (context, token) =>
32+
{
33+
token.ThrowIfCancellationRequested();
34+
35+
var fullyQualifiedParentTypeName = context.TargetSymbol.ContainingType.ToString();
36+
var structNamespace = context.TargetSymbol.ContainingType.ContainingNamespace.ToString();
37+
var structName = context.TargetSymbol.ContainingType.Name;
38+
var methodSymbol = (IMethodSymbol)context.TargetSymbol;
39+
var functionName = methodSymbol.Name;
40+
var returnTypeName = methodSymbol.ReturnType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
41+
var parameters = methodSymbol.Parameters.Select(x => new ParameterTypeNamePair(x.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), x.Name));
42+
var index = (int)context.Attributes[0].NamedArguments.FirstOrDefault(x => x.Key.Equals("Index")).Value.Value!;
43+
44+
return new VTableFunctionInfo(fullyQualifiedParentTypeName, structNamespace, structName, functionName, returnTypeName, index, new(parameters.ToImmutableArray()));
45+
})
46+
.Where(static item => item is not null)
47+
.Collect()
48+
.Select((items, token) =>
49+
{
50+
token.ThrowIfCancellationRequested();
51+
52+
return items.GroupBy(source => source.FullyQualifiedParentTypeName, StringComparer.OrdinalIgnoreCase).ToImmutableArray();
53+
});
54+
55+
56+
context.RegisterSourceOutput(sources, (context, sources) =>
57+
{
58+
foreach (var source in sources)
59+
{
60+
string vtableFunctionsCode = GenerateVtableFunctionsForStruct(source.ToImmutableArray());
61+
context.AddSource($"{source.Key}_VTableFunctions.g.cs", vtableFunctionsCode);
62+
}
63+
});
64+
}
65+
66+
private string GenerateVtableFunctionsForStruct(ImmutableArray<VTableFunctionInfo> sources)
67+
{
68+
StringBuilder builder = new();
69+
70+
builder.AppendLine($"// <auto-generated/>");
71+
builder.AppendLine();
72+
builder.AppendLine($"using global::System.Runtime.CompilerServices;");
73+
builder.AppendLine();
74+
builder.AppendLine($"#pragma warning disable");
75+
builder.AppendLine();
76+
77+
builder.AppendLine($"namespace {sources.ElementAt(0).ParentTypeNamespace};");
78+
builder.AppendLine();
79+
80+
builder.AppendLine($"public unsafe partial struct {sources.ElementAt(0).ParentTypeName}");
81+
builder.AppendLine($"{{");
82+
83+
builder.AppendLine($" private void** lpVtbl;");
84+
builder.AppendLine();
85+
86+
var sourceIndex = 0;
87+
var sourceCount = sources.Count();
88+
89+
foreach (var source in sources)
90+
{
91+
builder.AppendLine($" [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]");
92+
93+
builder.AppendLine($" public partial {source.ReturnTypeName} {source.Name}({string.Join(", ", source.Parameters.Select(x => $"{x.FullyQualifiedTypeName} {x.ValueName}"))})");
94+
builder.AppendLine($" {{");
95+
builder.AppendLine($" return ({source.ReturnTypeName})((delegate* unmanaged[MemberFunction]<{sources.ElementAt(0).ParentTypeName}*, {string.Join(", ", source.Parameters.Select(x => $"{x.FullyQualifiedTypeName}"))}, int>)(lpVtbl[{source.Index}]))");
96+
builder.AppendLine($" (({sources.ElementAt(0).ParentTypeName}*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref this), {string.Join(", ", source.Parameters.Select(x => $"{x.ValueName}"))});");
97+
builder.AppendLine($" }}");
98+
99+
if (sourceIndex < sourceCount - 1)
100+
builder.AppendLine();
101+
102+
sourceIndex++;
103+
}
104+
105+
builder.AppendLine($"}}");
106+
107+
return builder.ToString();
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)