90 lines
3 KiB
C#
90 lines
3 KiB
C#
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
|
namespace LANCommander.SDK.SourceGenerators;
|
|
|
|
[Generator]
|
|
public class CmdletRegistrationGenerator : IIncrementalGenerator
|
|
{
|
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
|
{
|
|
var cmdletClasses = context.SyntaxProvider
|
|
.ForAttributeWithMetadataName(
|
|
"System.Management.Automation.CmdletAttribute",
|
|
predicate: static (node, _) => node is ClassDeclarationSyntax,
|
|
transform: static (ctx, _) => GetCmdletInfo(ctx))
|
|
.Where(static info => info is not null)
|
|
.Select(static (info, _) => info!.Value);
|
|
|
|
context.RegisterSourceOutput(
|
|
cmdletClasses.Collect(),
|
|
static (spc, cmdlets) => Execute(spc, cmdlets));
|
|
}
|
|
|
|
private static CmdletInfo? GetCmdletInfo(GeneratorAttributeSyntaxContext context)
|
|
{
|
|
var typeSymbol = (INamedTypeSymbol)context.TargetSymbol;
|
|
|
|
foreach (var attr in typeSymbol.GetAttributes())
|
|
{
|
|
if (attr.AttributeClass?.ToDisplayString() != "System.Management.Automation.CmdletAttribute")
|
|
continue;
|
|
|
|
if (attr.ConstructorArguments.Length < 2)
|
|
continue;
|
|
|
|
var verb = attr.ConstructorArguments[0].Value?.ToString();
|
|
var noun = attr.ConstructorArguments[1].Value?.ToString();
|
|
|
|
if (verb is null || noun is null)
|
|
continue;
|
|
|
|
return new CmdletInfo
|
|
{
|
|
CmdletName = $"{verb}-{noun}",
|
|
FullTypeName = typeSymbol.ToDisplayString()
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static void Execute(SourceProductionContext context, ImmutableArray<CmdletInfo> cmdlets)
|
|
{
|
|
if (cmdlets.IsDefaultOrEmpty)
|
|
return;
|
|
|
|
var sorted = cmdlets.OrderBy(c => c.CmdletName).ToList();
|
|
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("// <auto-generated/>");
|
|
sb.AppendLine("using System.Management.Automation.Runspaces;");
|
|
sb.AppendLine();
|
|
sb.AppendLine("namespace LANCommander.SDK.PowerShell.Extensions;");
|
|
sb.AppendLine();
|
|
sb.AppendLine("public static class InitialSessionStateExtensions");
|
|
sb.AppendLine("{");
|
|
sb.AppendLine(" public static void AddCustomCmdlets(this InitialSessionState initialSessionState)");
|
|
sb.AppendLine(" {");
|
|
|
|
foreach (var cmdlet in sorted)
|
|
{
|
|
sb.AppendLine($" initialSessionState.Commands.Add(new SessionStateCmdletEntry(\"{cmdlet.CmdletName}\", typeof({cmdlet.FullTypeName}), null));");
|
|
}
|
|
|
|
sb.AppendLine(" }");
|
|
sb.AppendLine("}");
|
|
|
|
context.AddSource("InitialSessionStateExtensions.g.cs", sb.ToString());
|
|
}
|
|
|
|
private struct CmdletInfo
|
|
{
|
|
public string CmdletName;
|
|
public string FullTypeName;
|
|
}
|
|
}
|