Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/ConsoleAppFramework/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ internal class Parser(ConsoleAppFrameworkGeneratorOptions generatorOptions, Diag
{
var commandName = args[0];

if (!commandName.Expression.IsKind(SyntaxKind.StringLiteralExpression))
if (!IsStringLiteralOrNameOf(commandName.Expression))
{
context.ReportDiagnostic(DiagnosticDescriptors.AddCommandMustBeStringLiteral, commandName.GetLocation());
return null;
}

var name = (commandName.Expression as LiteralExpressionSyntax)!.Token.ValueText;
var name = GetStringValue(commandName.Expression);
var command = ExpressionToCommand(args[1].Expression, name);
if (command != null)
{
Expand All @@ -66,13 +66,13 @@ internal class Parser(ConsoleAppFrameworkGeneratorOptions generatorOptions, Diag
if (node2.ArgumentList.Arguments.Count == 1)
{
var commandName = args[0];
if (!commandName.Expression.IsKind(SyntaxKind.StringLiteralExpression))
if (!IsStringLiteralOrNameOf(commandName.Expression))
{
context.ReportDiagnostic(DiagnosticDescriptors.AddCommandMustBeStringLiteral, commandName.GetLocation());
return [];
}

commandPath = (commandName.Expression as LiteralExpressionSyntax)!.Token.ValueText;
commandPath = GetStringValue(commandName.Expression);
}

// T
Expand Down Expand Up @@ -874,4 +874,24 @@ void ParseParameterDescription(string originalDescription, out string[] aliases,
description = originalDescription;
}
}

static bool IsStringLiteralOrNameOf(ExpressionSyntax expression) =>
expression.IsKind(SyntaxKind.StringLiteralExpression) ||
expression is InvocationExpressionSyntax { Expression: IdentifierNameSyntax { Identifier.Text: "nameof" } };

static string GetStringValue(ExpressionSyntax expression) =>
expression switch
{
LiteralExpressionSyntax literal => literal.Token.ValueText,
InvocationExpressionSyntax invocation => GetLastIdentifier(invocation.ArgumentList.Arguments[0].Expression),
_ => throw new InvalidOperationException()
};

static string GetLastIdentifier(ExpressionSyntax expression) =>
expression switch
{
MemberAccessExpressionSyntax memberAccess => memberAccess.Name.Identifier.Text,
AliasQualifiedNameSyntax aliasQualified => aliasQualified.Name.Identifier.Text,
_ => expression.ToString()
};
}
13 changes: 10 additions & 3 deletions tests/ConsoleAppFramework.GeneratorTests/DiagnosticsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,30 @@ public async Task FunctionPointerValidation()
public async Task BuilderAddConstCommandName()
{
await verifier.Verify(6, """
var builder = ConsoleApp.Create();
var builder = ConsoleApp.Create();
var baz = "foo";
builder.Add(baz, (int x, int y) => { } );
""", "baz");

await verifier.Ok("""
var builder = ConsoleApp.Create();
var builder = ConsoleApp.Create();
builder.Add("foo", (int x, int y) => { } );
builder.Run(args);
""");

await verifier.Ok("""
var builder = ConsoleApp.Create();
var baz = string.Empty;
builder.Add(nameof(baz), (int x, int y) => { } );
builder.Run(args);
""");
}

[Test]
public async Task DuplicateCommandName()
{
await verifier.Verify(7, """
var builder = ConsoleApp.Create();
var builder = ConsoleApp.Create();
builder.Add("foo", (int x, int y) => { } );
builder.Add("foo", (int x, int y) => { } );
""", "\"foo\"");
Expand Down