|
1 | | -using Microsoft.CodeAnalysis; |
| 1 | +using Microsoft.CodeAnalysis; |
2 | 2 | using Microsoft.CodeAnalysis.CSharp; |
3 | 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; |
4 | 4 |
|
@@ -321,6 +321,40 @@ internal class Parser(ConsoleAppFrameworkGeneratorOptions generatorOptions, Diag |
321 | 321 | return identifier is "FromServices" or "FromServicesAttribute"; |
322 | 322 | }); |
323 | 323 |
|
| 324 | + object? keyedServiceKey = null; |
| 325 | + var isFromKeyedServices = x.AttributeLists.SelectMany(x => x.Attributes) |
| 326 | + .Any(x => |
| 327 | + { |
| 328 | + var name = x.Name; |
| 329 | + if (x.Name is QualifiedNameSyntax qns) |
| 330 | + { |
| 331 | + name = qns.Right; |
| 332 | + } |
| 333 | + |
| 334 | + var identifier = name.ToString(); |
| 335 | + var result = identifier is "FromKeyedServices" or "FromKeyedServicesAttribute"; |
| 336 | + if (result) |
| 337 | + { |
| 338 | + SemanticModel semanticModel = model; // we can use SemanticModel |
| 339 | + if (x.ArgumentList?.Arguments.Count > 0) |
| 340 | + { |
| 341 | + var argumentExpression = x.ArgumentList.Arguments[0].Expression; |
| 342 | + |
| 343 | + var constantValue = semanticModel.GetConstantValue(argumentExpression); |
| 344 | + if (constantValue.HasValue) |
| 345 | + { |
| 346 | + keyedServiceKey = constantValue.Value; |
| 347 | + } |
| 348 | + else if (argumentExpression is TypeOfExpressionSyntax typeOf) |
| 349 | + { |
| 350 | + var typeInfo = semanticModel.GetTypeInfo(typeOf.Type); |
| 351 | + keyedServiceKey = typeInfo.Type; |
| 352 | + } |
| 353 | + } |
| 354 | + } |
| 355 | + return result; |
| 356 | + }); |
| 357 | + |
324 | 358 | var hasArgument = x.AttributeLists.SelectMany(x => x.Attributes) |
325 | 359 | .Any(x => |
326 | 360 | { |
@@ -368,6 +402,8 @@ internal class Parser(ConsoleAppFrameworkGeneratorOptions generatorOptions, Diag |
368 | 402 | HasValidation = hasValidation, |
369 | 403 | IsCancellationToken = isCancellationToken, |
370 | 404 | IsFromServices = isFromServices, |
| 405 | + IsFromKeyedServices = isFromKeyedServices, |
| 406 | + KeyedServiceKey = keyedServiceKey, |
371 | 407 | Aliases = [], |
372 | 408 | Description = "", |
373 | 409 | ArgumentIndex = argumentIndex, |
@@ -512,11 +548,18 @@ internal class Parser(ConsoleAppFrameworkGeneratorOptions generatorOptions, Diag |
512 | 548 | { |
513 | 549 | var customParserType = x.GetAttributes().FirstOrDefault(x => x.AttributeClass?.AllInterfaces.Any(y => y.Name == "IArgumentParser") ?? false); |
514 | 550 | var hasFromServices = x.GetAttributes().Any(x => x.AttributeClass?.Name == "FromServicesAttribute"); |
| 551 | + var hasFromKeyedServices = x.GetAttributes().Any(x => x.AttributeClass?.Name == "FromKeyedServicesAttribute"); |
515 | 552 | var hasArgument = x.GetAttributes().Any(x => x.AttributeClass?.Name == "ArgumentAttribute"); |
516 | 553 | var hasValidation = x.GetAttributes().Any(x => x.AttributeClass?.GetBaseTypes().Any(y => y.Name == "ValidationAttribute") ?? false); |
517 | 554 | var isCancellationToken = SymbolEqualityComparer.Default.Equals(x.Type, wellKnownTypes.CancellationToken); |
518 | 555 | var isConsoleAppContext = x.Type!.Name == "ConsoleAppContext"; |
519 | 556 |
|
| 557 | + object? keyedServiceKey = null; |
| 558 | + if (hasFromKeyedServices) |
| 559 | + { |
| 560 | + // TODO: try to get keyedservicekey |
| 561 | + } |
| 562 | + |
520 | 563 | string description = ""; |
521 | 564 | string[] aliases = []; |
522 | 565 | if (parameterDescriptions != null && parameterDescriptions.TryGetValue(x.Name, out var desc)) |
@@ -554,6 +597,8 @@ internal class Parser(ConsoleAppFrameworkGeneratorOptions generatorOptions, Diag |
554 | 597 | CustomParserType = customParserType?.AttributeClass?.ToEquatable(), |
555 | 598 | IsCancellationToken = isCancellationToken, |
556 | 599 | IsFromServices = hasFromServices, |
| 600 | + IsFromKeyedServices = hasFromKeyedServices, |
| 601 | + KeyedServiceKey = keyedServiceKey, |
557 | 602 | HasValidation = hasValidation, |
558 | 603 | Aliases = aliases, |
559 | 604 | ArgumentIndex = argumentIndex, |
|
0 commit comments