Upstream Tyrrrz/CliFx state of the touched files before 9ef5dcb635

This commit is contained in:
upstream committed 2026-08-28 10:12:58 +02:00
commit e3e64a40e4
6 files changed
+2165

No files matched your search

+80
View File
@@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Linq;
using CliFx.Generators.Utils;
using CliFx.Generators.Utils.Extensions;
using Microsoft.CodeAnalysis;
namespace CliFx.Generators.Binding;
internal partial record CommandSymbol(
INamedTypeSymbol Type,
string? Name,
string? Description,
IReadOnlyList<CommandInputSymbol> Inputs
)
{
public bool IsDefault => string.IsNullOrWhiteSpace(Name);
public IReadOnlyList<CommandParameterSymbol> Parameters { get; } =
Inputs.OfType<CommandParameterSymbol>().ToArray();
public IReadOnlyList<CommandOptionSymbol> Options { get; } =
Inputs.OfType<CommandOptionSymbol>().ToArray();
public override string ToString() => !string.IsNullOrWhiteSpace(Name) ? Name : "<default>";
}
internal partial record CommandSymbol
{
internal static CommandSymbol? TryResolve(INamedTypeSymbol type, DiagnosticReporter diagnostics)
{
// Must have the [Command] attribute
var attribute = type.TryGetAttribute("CliFx.Binding.CommandAttribute");
if (attribute is null)
{
// Shouldn't happen when called by the generator since it filters types by attribute,
// so not worth the effort to produce a diagnostic.
return null;
}
// Must be partial by itself, along with all containing types
foreach (var declaration in type.GetDeclarations().ToArray())
{
if (!declaration.IsFullyPartial())
{
diagnostics.Report(
DiagnosticDescriptors.CommandTypeMustBePartial,
declaration.Identifier.GetLocation(),
type.Name
);
}
}
// Must implement ICommand
if (!type.Implements("CliFx.ICommand"))
{
diagnostics.Report(
DiagnosticDescriptors.CommandTypeMustImplementICommand,
type.Locations.FirstOrDefault(),
type.Name
);
}
var name =
attribute?.NamedArguments.FirstOrDefault(a => a.Key == "Name").Value.Value as string
?? attribute
?.ConstructorArguments.Where(a => a.Type?.SpecialType == SpecialType.System_String)
.Select(a => a.Value as string)
.FirstOrDefault();
var description =
attribute?.NamedArguments.FirstOrDefault(a => a.Key == "Description").Value.Value
as string;
var properties = type.GetProperties().ToArray();
var parameters = CommandParameterSymbol.Resolve(properties, diagnostics);
var options = CommandOptionSymbol.Resolve(properties, diagnostics);
return new CommandSymbol(type, name, description, [.. parameters, .. options]);
}
}