< Summary - CoreWCF Coverage — PR #1766

Line coverage
94%
Covered lines: 302
Uncovered lines: 18
Coverable lines: 320
Total lines: 633
Line coverage: 94.3%
Branch coverage
77%
Covered branches: 110
Total branches: 142
Branch coverage: 77.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.BuildTools/src/OperationParameterInjectionGenerator.Emitter.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Generic;
 5using System.Linq;
 6using System.Text;
 7using Microsoft.CodeAnalysis;
 8using Microsoft.CodeAnalysis.Text;
 9
 10namespace CoreWCF.BuildTools;
 11
 12public sealed partial class OperationParameterInjectionGenerator
 13{
 14    private record struct MessageProperty(
 415        string PropertyName,
 416        string PropertyTypeFullName,
 417        string OutputVarName);
 18
 1619    private record struct KeyedService(TypedConstant ServiceKey);
 20
 21    private sealed class Emitter
 22    {
 23        private readonly StringBuilder _builder;
 24        private readonly OperationParameterInjectionSourceGenerationContext _sourceGenerationContext;
 25        private readonly SourceGenerationSpec _generationSpec;
 26
 35227        public Emitter(in OperationParameterInjectionSourceGenerationContext sourceGenerationContext, in SourceGeneratio
 28        {
 35229            _sourceGenerationContext = sourceGenerationContext;
 35230            _generationSpec = generationSpec;
 35231            _builder = new StringBuilder();
 35232        }
 33
 34        public void Emit()
 35        {
 35236            _builder.Clear();
 35237            _builder.AppendLine($@"// <auto-generated>
 35238// Generated by the CoreWCF.BuildTools.OperationParameterInjectionGenerator source generator. DO NOT EDIT!
 35239// </auto-generated>
 35240#nullable disable
 35241using System;
 35242using Microsoft.Extensions.DependencyInjection;");
 43
 144044            foreach (var operationContractSpec in _generationSpec.OperationContractSpecs)
 45            {
 36846                EmitOperationContract(operationContractSpec);
 47            }
 48
 35249            if (_generationSpec.OperationContractSpecs.Length > 0)
 50            {
 35251                _builder.AppendLine("#nullable restore");
 35252                _sourceGenerationContext.AddSource("OperationParameterInjection.g.cs", SourceText.From(_builder.ToString
 53            }
 35254        }
 55
 56        private void EmitOperationContract(OperationContractSpec operationContractSpec)
 57        {
 36858            Dictionary<IParameterSymbol, string> messagePropertyNames = new(SymbolEqualityComparer.Default);
 36859            Dictionary<IParameterSymbol, KeyedService> keyedServices = new(SymbolEqualityComparer.Default);
 36860            List<MessageProperty> messageProperties = new();
 61
 236062            foreach (var parameter in operationContractSpec.UserProvidedOperationContractImplementation!.Parameters)
 63            {
 167264                if (operationContractSpec.MissingOperationContract.Parameters.Any(p => p.IsMatchingParameter(parameter))
 65                {
 66                    continue;
 67                }
 68
 172869                foreach (AttributeData attribute in parameter.GetAttributes())
 70                {
 43671                    if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass,
 43672                            _generationSpec.CoreWCFInjectedSymbol))
 73                    {
 24074                        if (attribute.NamedArguments.Length > 1)
 75                        {
 876                            _sourceGenerationContext.ReportDiagnostic(DiagnosticDescriptors.OperationParameterInjectionG
 877                            return;
 78                        }
 79
 48880                        foreach (var namedArgument in attribute.NamedArguments)
 81                        {
 1682                            if (namedArgument.Key == "PropertyName")
 83                            {
 1284                                if (namedArgument.Value.IsNull)
 85                                {
 486                                    _sourceGenerationContext.ReportDiagnostic(
 487                                        DiagnosticDescriptors.OperationParameterInjectionGenerator_01XX
 488                                            .RaisePropertyNameCannotBeNullOrEmptyError(parameter.Locations[0]));
 489                                    return;
 90                                }
 891                                var propertyName = namedArgument.Value.Value!.ToString();
 892                                if (propertyName is "")
 93                                {
 494                                    _sourceGenerationContext.ReportDiagnostic(
 495                                        DiagnosticDescriptors.OperationParameterInjectionGenerator_01XX
 496                                            .RaisePropertyNameCannotBeNullOrEmptyError(parameter.Locations[0]));
 497                                    return;
 98                                }
 499                                var messagePropertyVariableName = propertyName.ToMessagePropertyVariableName();
 4100                                messagePropertyNames[parameter] = messagePropertyVariableName;
 4101                                messageProperties.Add(new MessageProperty(propertyName, parameter.Type.ToDisplayString()
 4102                                    messagePropertyVariableName));
 103                            }
 4104                            else if (namedArgument.Key == "ServiceKey")
 105                            {
 4106                                keyedServices[parameter] = new KeyedService(namedArgument.Value);
 107                            }
 108                        }
 109                    }
 196110                    else if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass,
 196111                                 _generationSpec.MicrosoftExtensionsDependencyInjectionFromKeyedServicesSymbol))
 112                    {
 4113                        keyedServices[parameter] = new KeyedService(attribute.ConstructorArguments.First());
 114                    }
 115                }
 116            }
 117
 352118            Dictionary<ITypeSymbol, string> dependencyNames = new(SymbolEqualityComparer.Default);
 1132119            var dependencies = operationContractSpec.UserProvidedOperationContractImplementation!.Parameters.Where(x => 
 1944120                p.IsMatchingParameter(x))).ToList();
 121
 352122            bool shouldGenerateAsyncAwait = SymbolEqualityComparer.Default.Equals(operationContractSpec.MissingOperation
 352123                                            || (operationContractSpec.MissingOperationContract.ReturnType is INamedTypeS
 352124                                                SymbolEqualityComparer.Default.Equals(symbol.ConstructedFrom, _generatio
 125
 352126            string @async = shouldGenerateAsyncAwait
 352127                ? "async "
 352128                : string.Empty;
 129
 352130            string @await = shouldGenerateAsyncAwait
 352131                ? "await "
 352132                : string.Empty;
 133
 352134            string @return = (operationContractSpec.MissingOperationContract.ReturnsVoid || SymbolEqualityComparer.Defau
 352135                string.Empty
 352136                : "return ";
 137
 456138            string GetAccessibilityModifier(Accessibility accessibility) => accessibility switch
 456139            {
 32140                Accessibility.Private => "private ",
 16141                Accessibility.Protected => "protected ",
 344142                Accessibility.Public => "public ",
 64143                _ => "internal "
 456144            };
 145
 352146            bool isServiceContractImplInGlobalNamespace = operationContractSpec.ServiceContractImplementation!.Containin
 352147                .IsGlobalNamespace;
 148
 352149            string returnType = operationContractSpec.MissingOperationContract.ReturnsVoid
 352150                ? "void"
 352151                : $"{operationContractSpec.MissingOperationContract.ReturnType}";
 152
 352153            string parameters = string.Join(", ", operationContractSpec.MissingOperationContract.Parameters
 720154                .Select(static p => p.RefKind switch
 720155                {
 8156                    RefKind.Ref => $"ref {p.Type} {p.Name}",
 8157                    RefKind.Out => $"out {p.Type} {p.Name}",
 352158                    _ => $"{p.Type} {p.Name}",
 720159                }));
 160
 352161            var indentor = new Indentor();
 162
 352163            if (!isServiceContractImplInGlobalNamespace)
 164            {
 336165                _builder.AppendLine($@"namespace {operationContractSpec.ServiceContractImplementation!.ContainingNamespa
 336166{{");
 336167                indentor.Increment();
 168            }
 169
 352170            Stack<INamedTypeSymbol> classes = new();
 352171            INamedTypeSymbol containingType = operationContractSpec.ServiceContractImplementation;
 808172            while (containingType != null)
 173            {
 456174                classes.Push(containingType);
 456175                containingType = containingType.ContainingType;
 176            }
 177
 808178            while (classes.Count > 0)
 179            {
 456180                containingType = classes.Pop();
 456181                _builder.AppendLine($@"{indentor}{GetAccessibilityModifier(containingType.DeclaredAccessibility)}partial
 456182                _builder.AppendLine($@"{indentor}{{");
 456183                indentor.Increment();
 184            }
 185
 784186            foreach (AttributeData attributeData in operationContractSpec.UserProvidedOperationContractImplementation.Ge
 187            {
 40188                _builder.Append($"{indentor}[{attributeData.AttributeClass}(");
 104189                _builder.Append(string.Join(", ", attributeData.ConstructorArguments.Select(x => x.ToSafeCSharpString())
 40190                _builder.Append(")]");
 40191                _builder.AppendLine();
 192            }
 193
 352194            _builder.AppendLine($@"{indentor}public {@async}{returnType} {operationContractSpec.MissingOperationContract
 352195            _builder.AppendLine($@"{indentor}{{");
 352196            indentor.Increment();
 352197            _builder.AppendLine($@"{indentor}var serviceProvider = CoreWCF.OperationContext.Current.InstanceContext.Exte
 352198            _builder.AppendLine($@"{indentor}if (serviceProvider == null) throw new InvalidOperationException(""Missing 
 199
 352200            int objectIndex = 0;
 748201            if (dependencies.Any(x => SymbolEqualityComparer.Default.Equals(x.Type, operationContractSpec.HttpContextSym
 748202                                      || SymbolEqualityComparer.Default.Equals(x.Type, operationContractSpec.HttpRequest
 748203                                      || SymbolEqualityComparer.Default.Equals(x.Type, operationContractSpec.HttpRespons
 204            {
 32205                _builder.AppendLine($@"{indentor}var httpContext = (CoreWCF.OperationContext.Current.RequestContext.Requ
 32206                indentor.Increment();
 32207                _builder.AppendLine($@"{indentor}&& o{objectIndex} is Microsoft.AspNetCore.Http.HttpContext p{objectInde
 32208                _builder.AppendLine($@"{indentor}? p{objectIndex}");
 32209                _builder.AppendLine($@"{indentor}: null;");
 32210                indentor.Decrement();
 32211                _builder.AppendLine($@"{indentor}if (httpContext == null) throw new InvalidOperationException(""Missing 
 32212                objectIndex++;
 213            }
 214
 712215            foreach ((string propertyName, string propertyTypeFullName, string outputVar) in messageProperties)
 216            {
 4217                _builder.AppendLine($@"{indentor}var {outputVar} = (CoreWCF.OperationContext.Current.IncomingMessageProp
 4218                indentor.Increment();
 4219                _builder.AppendLine($@"{indentor}&& o{objectIndex} is {propertyTypeFullName} p{objectIndex})");
 4220                _builder.AppendLine($@"{indentor}? p{objectIndex}");
 4221                _builder.AppendLine($@"{indentor}: null;");
 4222                indentor.Decrement();
 4223                objectIndex++;
 224            }
 225
 352226            _builder.AppendLine($@"{indentor}if (CoreWCF.OperationContext.Current.InstanceContext.IsSingleton)");
 352227            _builder.AppendLine($@"{indentor}{{");
 352228            indentor.Increment();
 352229            _builder.AppendLine($@"{indentor}using (var scope = serviceProvider.CreateScope())");
 352230            _builder.AppendLine($@"{indentor}{{");
 352231            indentor.Increment();
 232
 352233            string dependencyNamePrefix = "d";
 352234            string serviceProviderName = "scope.ServiceProvider";
 235
 352236            AppendResolveDependencies();
 352237            AppendInvokeUserProvidedImplementation();
 238
 352239            if (operationContractSpec.MissingOperationContract.ReturnsVoid || SymbolEqualityComparer.Default.Equals(oper
 240            {
 16241                _builder.AppendLine($@"{indentor}return;");
 242            }
 243
 352244            indentor.Decrement();
 352245            _builder.AppendLine($@"{indentor}}}");
 352246            indentor.Decrement();
 352247            _builder.AppendLine($@"{indentor}}}");
 248
 352249            dependencyNamePrefix = "e";
 352250            serviceProviderName = "serviceProvider";
 251
 352252            AppendResolveDependencies();
 352253            AppendInvokeUserProvidedImplementation();
 254
 1496255            while (indentor.Level > 0)
 256            {
 1144257                indentor.Decrement();
 1144258                _builder.AppendLine($@"{indentor}}}");
 259            }
 260
 261            void AppendResolveDependencies()
 262            {
 263                for (int i = 0; i < dependencies.Count; i++)
 264                {
 265                    dependencyNames[dependencies[i].Type] = $"{dependencyNamePrefix}{i}";
 266                    if (SymbolEqualityComparer.Default.Equals(operationContractSpec.HttpContextSymbol, dependencies[i].T
 267                    {
 268                        _builder.AppendLine($@"{indentor}var {dependencyNamePrefix}{i} = httpContext;");
 269                    }
 270                    else if (SymbolEqualityComparer.Default.Equals(operationContractSpec.HttpRequestSymbol, dependencies
 271                    {
 272                        _builder.AppendLine($@"{indentor}var {dependencyNamePrefix}{i} = httpContext.Request;");
 273                    }
 274                    else if (SymbolEqualityComparer.Default.Equals(operationContractSpec.HttpResponseSymbol, dependencie
 275                    {
 276                        _builder.AppendLine($@"{indentor}var {dependencyNamePrefix}{i} = httpContext.Response;");
 277                    }
 278                    else if (messagePropertyNames.TryGetValue(dependencies[i], out string messagePropertyVariableName))
 279                    {
 280                        _builder.AppendLine($@"{indentor}var {dependencyNamePrefix}{i} = {messagePropertyVariableName};"
 281                    }
 282                    else if (keyedServices.TryGetValue(dependencies[i], out var keyedService))
 283                    {
 284                        _builder.AppendLine($@"{indentor}var {dependencyNamePrefix}{i} = {serviceProviderName}.GetKeyedS
 285                    }
 286                    else
 287                    {
 288                        _builder.AppendLine($@"{indentor}var {dependencyNamePrefix}{i} = {serviceProviderName}.GetServic
 289                    }
 290                }
 291            }
 292
 293            void AppendInvokeUserProvidedImplementation()
 294            {
 295                _builder.Append($"{indentor}{@return}{@await}{operationContractSpec.UserProvidedOperationContractImpleme
 296                for (int i = 0,j = 0; i < operationContractSpec.UserProvidedOperationContractImplementation.Parameters.L
 297                {
 298                    IParameterSymbol parameter = operationContractSpec.UserProvidedOperationContractImplementation.Param
 299                    if (i != 0)
 300                    {
 301                        _builder.Append(", ");
 302                    }
 303
 304                    if (parameter.GetOneAttributeOf(_generationSpec.CoreWCFInjectedSymbol,
 305                            _generationSpec.MicrosoftAspNetCoreMvcFromServicesSymbol,
 306                            _generationSpec.MicrosoftExtensionsDependencyInjectionFromKeyedServicesSymbol) is not null)
 307                    {
 308                        _builder.Append(dependencyNames[parameter.Type]);
 309                    }
 310                    else
 311                    {
 312                        IParameterSymbol originalParameter = operationContractSpec.MissingOperationContract.Parameters[j
 313                        _builder.Append(originalParameter.RefKind switch
 314                        {
 315                            RefKind.Ref => $"ref {originalParameter.Name}",
 316                            RefKind.Out => $"out {originalParameter.Name}",
 317                            _ => originalParameter.Name,
 318                        });
 319                        j++;
 320                    }
 321                }
 322                _builder.AppendLine(");");
 323            }
 352324        }
 325    }
 326}

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.BuildTools/src/OperationParameterInjectionGenerator.OperationContractSpec.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using Microsoft.CodeAnalysis;
 5
 6namespace CoreWCF.BuildTools;
 7
 8public sealed partial class OperationParameterInjectionGenerator
 9{
 10    internal readonly record struct OperationContractSpec(INamedTypeSymbol? ServiceContract, INamedTypeSymbol? ServiceCo
 11        IMethodSymbol? MissingOperationContract, IMethodSymbol? UserProvidedOperationContractImplementation,
 12        INamedTypeSymbol? HttpContextSymbol, INamedTypeSymbol? HttpRequestSymbol, INamedTypeSymbol? HttpResponseSymbol,
 13        AttributeData OperationContractAttributeData)
 14    {
 36815        public INamedTypeSymbol? ServiceContract { get; } = ServiceContract;
 140816        public INamedTypeSymbol? ServiceContractImplementation { get; } = ServiceContractImplementation;
 619217        public IMethodSymbol? MissingOperationContract { get; } = MissingOperationContract;
 596818        public IMethodSymbol? UserProvidedOperationContractImplementation { get; } = UserProvidedOperationContractImplem
 158819        public INamedTypeSymbol? HttpContextSymbol { get; } = HttpContextSymbol;
 154020        public INamedTypeSymbol? HttpRequestSymbol { get; } = HttpRequestSymbol;
 150021        public INamedTypeSymbol? HttpResponseSymbol { get; } = HttpResponseSymbol;
 36822        public AttributeData OperationContractAttributeData { get; } = OperationContractAttributeData;
 23    }
 24}

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.BuildTools/src/OperationParameterInjectionGenerator.Parser.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Immutable;
 5using System.Linq;
 6using Microsoft.CodeAnalysis;
 7using Microsoft.CodeAnalysis.CSharp;
 8using Microsoft.CodeAnalysis.CSharp.Syntax;
 9
 10namespace CoreWCF.BuildTools;
 11
 12public sealed partial class OperationParameterInjectionGenerator
 13{
 14    private sealed class Parser
 15    {
 16        private readonly Compilation _compilation;
 17        private readonly OperationParameterInjectionSourceGenerationContext _context;
 18        private readonly INamedTypeSymbol? _sSMOperationContractSymbol;
 19        private readonly INamedTypeSymbol? _coreWCFOperationContractSymbol;
 20        private readonly INamedTypeSymbol? _httpContextSymbol;
 21        private readonly INamedTypeSymbol? _httpRequestSymbol;
 22        private readonly INamedTypeSymbol? _httpResponseSymbol;
 23        private readonly INamedTypeSymbol? _sSMServiceContractSymbol;
 24        private readonly INamedTypeSymbol? _coreWCFServiceContractSymbol;
 25
 41426        public Parser(Compilation compilation, in OperationParameterInjectionSourceGenerationContext context)
 27        {
 41428                _compilation = compilation;
 41429                _context = context;
 30
 41431                _sSMOperationContractSymbol = _compilation.GetTypeByMetadataName("System.ServiceModel.OperationContractA
 41432                _coreWCFOperationContractSymbol = _compilation.GetTypeByMetadataName("CoreWCF.OperationContractAttribute
 41433                _sSMServiceContractSymbol = _compilation.GetTypeByMetadataName("System.ServiceModel.ServiceContractAttri
 41434                _coreWCFServiceContractSymbol = _compilation.GetTypeByMetadataName("CoreWCF.ServiceContractAttribute");
 41435                _httpContextSymbol = _compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Http.HttpContext");
 41436                _httpRequestSymbol = _compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Http.HttpRequest");
 41437                _httpResponseSymbol = _compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Http.HttpResponse");
 41438            }
 39
 40        public SourceGenerationSpec GetGenerationSpec(ImmutableArray<MethodDeclarationSyntax> methodDeclarationSyntaxes)
 41        {
 41442                ImmutableArray<IMethodSymbol> methods = (from methodDeclarationSyntax in methodDeclarationSyntaxes
 43043                    let semanticModel = _compilation.GetSemanticModel(methodDeclarationSyntax.SyntaxTree)
 43044                    let symbol = semanticModel.GetDeclaredSymbol(methodDeclarationSyntax)
 43045                    where symbol is not null
 43046                    let methodSymbol = symbol as IMethodSymbol
 84447                    select methodSymbol).ToImmutableArray();
 48
 41449                var methodServiceContractAndOperationContractsValues = from method in methods
 87450                    from @interface in method.ContainingType.AllInterfaces
 44451                    where @interface.GetOneAttributeOf(_sSMServiceContractSymbol, _coreWCFServiceContractSymbol) is not 
 39252                    let methodMembers = (from member in @interface.GetMembers()
 78453                        let methodMember = member as IMethodSymbol
 78454                        where methodMember is not null
 78455                        let operationContractAttribute = methodMember.GetOneAttributeOf(_sSMOperationContractSymbol,
 78456                            _coreWCFOperationContractSymbol)
 78457                        where operationContractAttribute is not null
 117658                        select (MethodMember: methodMember, AttributeData: operationContractAttribute)).ToImmutableArray
 80659                    select (Method: method, ServiceContract: @interface, OperationContracts: methodMembers);
 60
 41461                var methodMissingOperationServiceContractAndOperationContractsValues =
 41462                    from value in methodServiceContractAndOperationContractsValues
 41463                    let missingOperationContract =
 39264                        value.OperationContracts
 117665                            .SingleOrDefault(x => x.MethodMember.Name == value.Method.Name
 117666                                                  && x.MethodMember.Parameters.All(p =>
 160067                                                      value.Method.Parameters.Any(msp =>
 208868                                                          msp.IsMatchingParameter(p))))
 39269                    where missingOperationContract.MethodMember is not null
 39270                    let nonNullMissingOperationContract = missingOperationContract
 80671                    select (value.Method, MissingOperationContract: nonNullMissingOperationContract,
 80672                        value.ServiceContract, value.OperationContracts);
 73
 41474                var builder = ImmutableArray.CreateBuilder<OperationContractSpec>();
 75
 161276                foreach (var value in methodMissingOperationServiceContractAndOperationContractsValues)
 77                {
 39278                    if (!value.Method.ContainingType.IsPartial(out INamedTypeSymbol parentType))
 79                    {
 2480                        _context.ReportDiagnostic(DiagnosticDescriptors.OperationParameterInjectionGenerator_01XX.RaiseP
 2481                        continue;
 82                    }
 83
 36884                    builder.Add(new OperationContractSpec(value.ServiceContract,
 36885                        value.Method.ContainingType, value.MissingOperationContract.MethodMember,
 36886                        value.Method,
 36887                        _httpContextSymbol, _httpRequestSymbol, _httpResponseSymbol, value.MissingOperationContract.Attr
 88                }
 89
 41490                ImmutableArray<OperationContractSpec> operationContractSpecs = builder.ToImmutable();
 91
 41492                if (operationContractSpecs.IsEmpty)
 93                {
 6294                    return SourceGenerationSpec.None;
 95                }
 96
 35297                return new SourceGenerationSpec(operationContractSpecs,
 35298                    _compilation.GetTypeByMetadataName("System.Threading.Tasks.Task"),
 35299                    _compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1"),
 352100                    _compilation.GetTypeByMetadataName("CoreWCF.InjectedAttribute"),
 352101                    _compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Mvc.FromServicesAttribute"),
 352102                    _compilation.GetTypeByMetadataName("Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttrib
 352103                );
 104            }
 105
 0106        internal static bool IsSyntaxTargetForGeneration(SyntaxNode node) => node is MethodDeclarationSyntax methodDecla
 0107                 && methodDeclarationSyntax.ParameterList.Parameters.Count > 0
 0108                 && methodDeclarationSyntax.ParameterList.Parameters.Any(static p => p.AttributeLists.Count > 0)
 0109                 && (methodDeclarationSyntax.Body != null || methodDeclarationSyntax.ExpressionBody != null);
 110
 111        internal static MethodDeclarationSyntax? GetSemanticTargetForGeneration(GeneratorSyntaxContext context)
 112        {
 0113                var methodDeclarationSyntax = (MethodDeclarationSyntax)context.Node;
 0114                foreach (var parameterSyntax in methodDeclarationSyntax.ParameterList.Parameters)
 115                {
 0116                    foreach (var attributeList in parameterSyntax.AttributeLists)
 117                    {
 0118                        foreach (var attributeSyntax in attributeList.Attributes)
 119                        {
 0120                            IMethodSymbol? attributeSymbol = context.SemanticModel.GetSymbolInfo(attributeSyntax).Symbol
 0121                            if (attributeSymbol == null)
 122                            {
 123                                continue;
 124                            }
 125
 0126                            INamedTypeSymbol attributeContainingTypeSymbol = attributeSymbol.ContainingType;
 0127                            string fullName = attributeContainingTypeSymbol.ToDisplayString();
 128
 0129                            if (fullName is "Microsoft.AspNetCore.Mvc.FromServicesAttribute"
 0130                                or "CoreWCF.InjectedAttribute"
 0131                                or "Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttribute")
 132                            {
 0133                                return methodDeclarationSyntax;
 134                            }
 135                        }
 136                    }
 137                }
 138
 0139                return null;
 140            }
 141    }
 142}

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.BuildTools/src/OperationParameterInjectionGenerator.Roslyn4.0.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Collections.Immutable;
 3using Microsoft.CodeAnalysis;
 4using Microsoft.CodeAnalysis.CSharp.Syntax;
 5using Microsoft.CodeAnalysis.Text;
 6
 7namespace CoreWCF.BuildTools;
 8
 9[Generator(LanguageNames.CSharp)]
 10public sealed partial class OperationParameterInjectionGenerator : IIncrementalGenerator
 11{
 12    public void Initialize(IncrementalGeneratorInitializationContext context)
 13    {
 41414        IncrementalValuesProvider<MethodDeclarationSyntax?> coreWCFInjected = context.SyntaxProvider
 41415            .ForAttributeWithMetadataName(
 41416                "CoreWCF.InjectedAttribute",
 41417                predicate: IsInjectedParameter,
 68418                transform: static (ctx, _) => ctx.TargetNode.Parent?.Parent as MethodDeclarationSyntax);
 19
 41420        IncrementalValuesProvider<MethodDeclarationSyntax?> fromServices = context.SyntaxProvider
 41421            .ForAttributeWithMetadataName(
 41422                "Microsoft.AspNetCore.Mvc.FromServicesAttribute",
 41423                predicate: IsInjectedParameter,
 64024                transform: static (ctx, _) => ctx.TargetNode.Parent?.Parent as MethodDeclarationSyntax);
 25
 41426        IncrementalValuesProvider<MethodDeclarationSyntax?> fromKeyedServices = context.SyntaxProvider
 41427            .ForAttributeWithMetadataName(
 41428                "Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttribute",
 41429                predicate: IsInjectedParameter,
 41830                transform: static (ctx, _) => ctx.TargetNode.Parent?.Parent as MethodDeclarationSyntax);
 31
 41432        IncrementalValueProvider<ImmutableArray<MethodDeclarationSyntax>> methodDeclarations = coreWCFInjected.Collect()
 41433            .Combine(fromServices.Collect())
 41434            .Combine(fromKeyedServices.Collect())
 41435            .Select(static (pair, _) =>
 41436            {
 41437                var ((injected, services), keyed) = pair;
 41438                var seen = new HashSet<(string FilePath, TextSpan Span)>();
 41439                var builder = ImmutableArray.CreateBuilder<MethodDeclarationSyntax>();
 136840                foreach (var method in injected)
 41441                {
 27042                    if (method is not null && seen.Add((method.SyntaxTree.FilePath, method.Span)))
 41443                    {
 23044                        builder.Add(method);
 41445                    }
 41446                }
 128047                foreach (var method in services)
 41448                {
 22649                    if (method is not null && seen.Add((method.SyntaxTree.FilePath, method.Span)))
 41450                    {
 19651                        builder.Add(method);
 41452                    }
 41453                }
 83654                foreach (var method in keyed)
 41455                {
 456                    if (method is not null && seen.Add((method.SyntaxTree.FilePath, method.Span)))
 41457                    {
 458                        builder.Add(method);
 41459                    }
 41460                }
 41461                return builder.ToImmutable();
 41462            });
 63
 41464        IncrementalValueProvider<(Compilation Compilation, ImmutableArray<MethodDeclarationSyntax> Methods)> compilation
 41465            context.CompilationProvider.Combine(methodDeclarations);
 66
 41467        context.RegisterSourceOutput(compilationAndMethods, (spc, source)
 82868            => Execute(source.Compilation, source.Methods, spc));
 41469    }
 70
 71    private static bool IsInjectedParameter(SyntaxNode node, System.Threading.CancellationToken _) =>
 50072        node is ParameterSyntax p
 50073        && p.Parent?.Parent is MethodDeclarationSyntax m
 50074        && (m.Body != null || m.ExpressionBody != null);
 75
 76    private void Execute(Compilation compilation, ImmutableArray<MethodDeclarationSyntax> contextMethods, SourceProducti
 77    {
 41478        if (contextMethods.IsDefaultOrEmpty)
 79        {
 080            return;
 81        }
 82
 41483        OperationParameterInjectionSourceGenerationContext context = new(sourceProductionContext);
 41484        Parser parser = new(compilation, context);
 41485        SourceGenerationSpec spec = parser.GetGenerationSpec(contextMethods);
 41486        if (spec != SourceGenerationSpec.None)
 87        {
 35288            Emitter emitter = new(context, spec);
 35289            emitter.Emit();
 90        }
 41491    }
 92
 93    internal readonly struct OperationParameterInjectionSourceGenerationContext
 94    {
 95        private readonly SourceProductionContext _context;
 96
 97        public OperationParameterInjectionSourceGenerationContext(SourceProductionContext context)
 98        {
 41499            _context = context;
 414100        }
 101
 102        public void ReportDiagnostic(Diagnostic diagnostic)
 103        {
 40104            _context.ReportDiagnostic(diagnostic);
 40105        }
 106
 107        public void AddSource(string hintName, SourceText sourceText)
 108        {
 352109            _context.AddSource(hintName, sourceText);
 352110        }
 111    }
 112}

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.BuildTools/src/OperationParameterInjectionGenerator.SourceGenerationSpec.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Immutable;
 5using Microsoft.CodeAnalysis;
 6
 7namespace CoreWCF.BuildTools;
 8
 9public sealed partial class OperationParameterInjectionGenerator
 10{
 11    internal readonly record struct SourceGenerationSpec(in ImmutableArray<OperationContractSpec> OperationContractSpecs
 12        INamedTypeSymbol? TaskSymbol,
 13        INamedTypeSymbol? GenericTaskSymbol,
 14        INamedTypeSymbol? CoreWCFInjectedSymbol,
 15        INamedTypeSymbol? MicrosoftAspNetCoreMvcFromServicesSymbol,
 16        INamedTypeSymbol? MicrosoftExtensionsDependencyInjectionFromKeyedServicesSymbol)
 17    {
 105718        public ImmutableArray<OperationContractSpec> OperationContractSpecs { get; } = OperationContractSpecs;
 139319        public INamedTypeSymbol? TaskSymbol { get; } = TaskSymbol;
 69720        public INamedTypeSymbol? GenericTaskSymbol { get; } = GenericTaskSymbol;
 234921        public INamedTypeSymbol? CoreWCFInjectedSymbol { get; } = CoreWCFInjectedSymbol;
 191322        public INamedTypeSymbol? MicrosoftAspNetCoreMvcFromServicesSymbol { get; } = MicrosoftAspNetCoreMvcFromServicesS
 175623        public INamedTypeSymbol? MicrosoftExtensionsDependencyInjectionFromKeyedServicesSymbol { get; } =
 35324            MicrosoftExtensionsDependencyInjectionFromKeyedServicesSymbol;
 25
 126        public static readonly SourceGenerationSpec None =
 127            new(in ImmutableArray<OperationContractSpec>.Empty, null, null, null, null, null);
 28    }
 29}

Methods/Properties

PropertyName()
PropertyTypeFullName()
OutputVarName()
ServiceKey()
.ctor(CoreWCF.BuildTools.OperationParameterInjectionGenerator/OperationParameterInjectionSourceGenerationContext&,CoreWCF.BuildTools.OperationParameterInjectionGenerator/SourceGenerationSpec&)
Emit()
EmitOperationContract(CoreWCF.BuildTools.OperationParameterInjectionGenerator/OperationContractSpec)
GetAccessibilityModifier(Microsoft.CodeAnalysis.Accessibility)
ServiceContract()
ServiceContractImplementation()
MissingOperationContract()
UserProvidedOperationContractImplementation()
HttpContextSymbol()
HttpRequestSymbol()
HttpResponseSymbol()
OperationContractAttributeData()
.ctor(Microsoft.CodeAnalysis.Compilation,CoreWCF.BuildTools.OperationParameterInjectionGenerator/OperationParameterInjectionSourceGenerationContext&)
GetGenerationSpec(System.Collections.Immutable.ImmutableArray`1<Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax>)
IsSyntaxTargetForGeneration(Microsoft.CodeAnalysis.SyntaxNode)
GetSemanticTargetForGeneration(Microsoft.CodeAnalysis.GeneratorSyntaxContext)
Initialize(Microsoft.CodeAnalysis.IncrementalGeneratorInitializationContext)
IsInjectedParameter(Microsoft.CodeAnalysis.SyntaxNode,System.Threading.CancellationToken)
Execute(Microsoft.CodeAnalysis.Compilation,System.Collections.Immutable.ImmutableArray`1<Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax>,Microsoft.CodeAnalysis.SourceProductionContext)
.ctor(Microsoft.CodeAnalysis.SourceProductionContext)
ReportDiagnostic(Microsoft.CodeAnalysis.Diagnostic)
AddSource(System.String,Microsoft.CodeAnalysis.Text.SourceText)
OperationContractSpecs()
TaskSymbol()
GenericTaskSymbol()
CoreWCFInjectedSymbol()
MicrosoftAspNetCoreMvcFromServicesSymbol()
MicrosoftExtensionsDependencyInjectionFromKeyedServicesSymbol()
.ctor(System.Collections.Immutable.ImmutableArray`1<CoreWCF.BuildTools.OperationParameterInjectionGenerator/OperationContractSpec>&,Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.INamedTypeSymbol)
.cctor()