У меня есть генератор кода Roslyn, который сканирует проект на предмет классов, украшенных одним из атрибутов X, и генерирует код.
В рамках этого процесса мне нужен Dictionary хранение всех значений аргументов, используемых для построения атрибут. Вот код, который работает...
Код: Выделить всё
internal static class AttributeSyntaxExtensions
{
public static ImmutableDictionary GetArguments(
this AttributeSyntax source,
SemanticModel semanticModel,
CancellationToken cancellationToken)
{
SeparatedSyntaxList? arguments = source.ArgumentList?.Arguments;
if (arguments is null)
return ImmutableDictionary.Empty;
var builder = ImmutableDictionary.CreateBuilder(StringComparer.CurrentCultureIgnoreCase);
// Get the symbol for the attribute type
SymbolInfo attributeSymbolInfo = semanticModel.GetSymbolInfo(source);
var attributeSymbol = attributeSymbolInfo.Symbol?.ContainingType;
// Retrieve constructor parameters if available
IMethodSymbol constructor = attributeSymbol!.Constructors.First();
ImmutableArray parameters = constructor.Parameters;
for (int argumentIndex = 0; argumentIndex < arguments.Value.Count; argumentIndex++)
{
AttributeArgumentSyntax argument = arguments.Value[argumentIndex];
// Retrieve the argument name or fall back to the constructor parameter name
string argumentName =
argument.NameEquals is not null
? argument.NameEquals.Name.Identifier.ValueText
: argument.NameColon is not null
? argument.NameColon.Name.Identifier.ValueText
: parameters != null && argumentIndex < parameters.Length
? parameters[argumentIndex].Name
: $"arg{argumentIndex}";
ExpressionSyntax argumentExpression = argument.Expression;
object? argumentValue = argumentExpression.GetValue(semanticModel, cancellationToken);
builder[argumentName] = argumentValue;
}
return builder.ToImmutable();
}
}
Это связано с тем, что атрибуты находятся в библиотеке классов, отличной от генератора кода Roslyn. Сейчас я пытаюсь перенести библиотеку, чтобы эти атрибуты также генерировались.
Итак, теперь я генерирую атрибуты следующим образом...
Код: Выделить всё
[Generator]
public class StaticResourcesSourceGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
context.RegisterPostInitializationOutput(ctx =>
{
string sourceCode = "whatever...";
ctx.AddSource("MyLibraryName.g.cs", sourceCode);
});
}
}
Подробнее здесь: https://stackoverflow.com/questions/792 ... -attribute
Мобильная версия