< Summary

Information
Class: NexusLabs.Needlr.Generators.RecordConstructorOverloadDiscoveryHelper
Assembly: NexusLabs.Needlr.Generators
File(s): /home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/RecordConstructorOverloadDiscoveryHelper.cs
Line coverage
95%
Covered lines: 317
Uncovered lines: 14
Coverable lines: 331
Total lines: 672
Line coverage: 95.7%
Branch coverage
88%
Covered branches: 189
Total branches: 214
Branch coverage: 88.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/needlr/needlr/src/NexusLabs.Needlr.Generators/RecordConstructorOverloadDiscoveryHelper.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Linq;
 3
 4using Microsoft.CodeAnalysis;
 5using Microsoft.CodeAnalysis.CSharp;
 6using Microsoft.CodeAnalysis.CSharp.Syntax;
 7
 8using NexusLabs.Needlr.Generators.CodeGen;
 9using NexusLabs.Needlr.Generators.Models;
 10using NexusLabs.Needlr.Roslyn.Shared;
 11
 12namespace NexusLabs.Needlr.Generators;
 13
 14/// <summary>
 15/// Discovers top-level partial positional record classes with marked property
 16/// parameters and builds equatable constructor-overload models.
 17/// </summary>
 18internal static class RecordConstructorOverloadDiscoveryHelper
 19{
 20    private const string GenerateConstructorAttributeName =
 21        "GenerateConstructorAttribute";
 22    private const string RecordConstructorOverloadParameterAttributeName =
 23        "RecordConstructorOverloadParameterAttribute";
 24    private const string GeneratedFileSuffix =
 25        ".RecordConstructorOverload.g.cs";
 26
 27    /// <summary>
 28    /// Cheap syntax predicate for the per-record incremental pipeline.
 29    /// </summary>
 30    internal static bool IsCandidateRecordDeclaration(SyntaxNode node)
 31    {
 298032        return node is RecordDeclarationSyntax;
 33    }
 34
 35    /// <summary>
 36    /// Builds one canonical model for a record, or <see langword="null"/> when the
 37    /// record does not participate or any declaration is invalid.
 38    /// </summary>
 39    internal static RecordConstructorOverloadModel? TryCreateCanonicalModel(
 40        GeneratorSyntaxContext context)
 41    {
 7442        var recordDeclaration = (RecordDeclarationSyntax)context.Node;
 7443        if (context.SemanticModel.GetDeclaredSymbol(recordDeclaration) is not
 7444            INamedTypeSymbol typeSymbol ||
 7445            !GeneratedConstructorEligibility.IsCanonicalDeclaration(
 7446                typeSymbol,
 7447                recordDeclaration))
 48        {
 249            return null;
 50        }
 51
 7252        return TryGetModel(
 7253            typeSymbol,
 7254            context.SemanticModel.Compilation);
 55    }
 56
 57    /// <summary>
 58    /// Returns every directly declared property carrying the record-overload marker in
 59    /// deterministic source order.
 60    /// </summary>
 61    internal static IReadOnlyList<IPropertySymbol> GetMarkedProperties(
 62        INamedTypeSymbol typeSymbol)
 63    {
 16364        return typeSymbol.GetMembers()
 16365            .OfType<IPropertySymbol>()
 16366            .Where(HasMarker)
 16367            .OrderBy(
 16368                property =>
 3969                    property.Locations.FirstOrDefault()?.SourceTree?.FilePath ??
 3970                    string.Empty,
 16371                System.StringComparer.Ordinal)
 16372            .ThenBy(
 16373                property =>
 3974                    property.Locations.FirstOrDefault()?.SourceSpan.Start ?? 0)
 16375            .ToArray();
 76    }
 77
 78    /// <summary>
 79    /// Returns whether a property carries Needlr's record-overload marker.
 80    /// </summary>
 81    internal static bool HasMarker(IPropertySymbol property)
 82    {
 390783        return GetMarkerAttribute(property) is not null;
 84    }
 85
 86    /// <summary>
 87    /// Gets the marker attribute applied to a property.
 88    /// </summary>
 89    internal static AttributeData? GetMarkerAttribute(IPropertySymbol property)
 90    {
 821491        foreach (var attribute in property.GetAttributes())
 92        {
 34793            if (attribute.AttributeClass is { } attributeClass &&
 34794                GeneratedConstructorEligibility.IsNeedlrGeneratorsAttribute(
 34795                    attributeClass,
 34796                    RecordConstructorOverloadParameterAttributeName))
 97            {
 34298                return attribute;
 99            }
 100        }
 101
 3589102        return null;
 103    }
 104
 105    /// <summary>
 106    /// Gets the positional record declaration containing the primary parameter list.
 107    /// </summary>
 108    internal static RecordDeclarationSyntax? GetPrimaryRecordDeclaration(
 109        INamedTypeSymbol typeSymbol)
 110    {
 330111        return typeSymbol.DeclaringSyntaxReferences
 330112            .Select(reference => reference.GetSyntax())
 330113            .OfType<RecordDeclarationSyntax>()
 660114            .FirstOrDefault(declaration => declaration.ParameterList is not null);
 115    }
 116
 117    /// <summary>
 118    /// Returns why a marked property's containing type is outside the supported
 119    /// record-only contract.
 120    /// </summary>
 121    internal static string? GetTypeIneligibilityReason(
 122        INamedTypeSymbol typeSymbol)
 123    {
 133124        if (!typeSymbol.IsRecord)
 125        {
 2126            return typeSymbol.TypeKind == TypeKind.Class
 2127                ? "an ordinary class rather than a positional record class"
 2128                : $"a {typeSymbol.TypeKind.ToString().ToLowerInvariant()} rather than a positional record class";
 129        }
 130
 131131        if (typeSymbol.TypeKind == TypeKind.Struct)
 2132            return "a record struct";
 133
 129134        if (typeSymbol.IsFileLocal)
 2135            return "a file-local record that cannot be extended from a generated file";
 136
 127137        if (typeSymbol.ContainingType is not null)
 2138            return "a nested record";
 139
 125140        var primaryDeclaration = GetPrimaryRecordDeclaration(typeSymbol);
 125141        if (primaryDeclaration is null)
 2142            return "a non-positional record with no primary parameter list";
 143
 123144        if (typeSymbol.BaseType is not null &&
 123145            typeSymbol.BaseType.SpecialType != SpecialType.System_Object)
 146        {
 2147            return "an inherited record";
 148        }
 149
 121150        if (GetPrimaryConstructor(typeSymbol, primaryDeclaration) is
 121151            { } primaryConstructor)
 152        {
 499153            foreach (var parameter in primaryConstructor.Parameters)
 154            {
 130155                if (ContainsPointerType(parameter.Type))
 156                {
 3157                    return $"a positional record whose primary constructor parameter '{parameter.Name}' is typed as '{pa
 158                }
 159            }
 160        }
 161
 118162        return null;
 163    }
 164
 165    /// <summary>
 166    /// Gets the primary constructor declared by the positional record declaration.
 167    /// </summary>
 168    internal static IMethodSymbol? GetPrimaryConstructor(
 169        INamedTypeSymbol typeSymbol,
 170        RecordDeclarationSyntax primaryDeclaration)
 171    {
 363172        foreach (var constructor in typeSymbol.InstanceConstructors)
 173        {
 363174            foreach (var reference in constructor.DeclaringSyntaxReferences)
 175            {
 121176                if (reference.GetSyntax() == primaryDeclaration)
 121177                    return constructor;
 178            }
 179        }
 180
 0181        return null;
 182    }
 183
 184    /// <summary>
 185    /// Returns why a marked property cannot participate, or
 186    /// <see langword="null"/> when it is assignable by the generated constructor.
 187    /// </summary>
 188    internal static string? GetPropertyIneligibilityReason(
 189        INamedTypeSymbol containingType,
 190        IPropertySymbol property,
 191        RecordDeclarationSyntax primaryDeclaration)
 192    {
 128193        if (!SymbolEqualityComparer.Default.Equals(
 128194            property.ContainingType,
 128195            containingType))
 196        {
 0197            return "inherited rather than declared directly by the record";
 198        }
 199
 128200        if (property.IsStatic)
 2201            return "static";
 202
 126203        if (property.IsIndexer)
 2204            return "an indexer";
 205
 124206        if (IsPositionalProperty(property, primaryDeclaration))
 207        {
 2208            return "a positional property synthesized from a primary constructor parameter";
 209        }
 210
 122211        if (property.SetMethod is null)
 212        {
 2213            return "get-only and cannot be assigned by the generated constructor";
 214        }
 215
 120216        if (property.ExplicitInterfaceImplementations.Length > 0)
 217        {
 0218            return "an explicit interface implementation and cannot be assigned by name";
 219        }
 220
 120221        if (property.IsAbstract)
 222        {
 0223            return "abstract and has no assignable implementation on the record";
 224        }
 225
 120226        if (property.IsRequired)
 227        {
 2228            return "required; the generated overload does not claim to satisfy the record's complete required-member con
 229        }
 230
 118231        if (ContainsPointerType(property.Type))
 232        {
 4233            return $"typed as '{property.Type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)}', which the
 234        }
 235
 114236        if (!IsTypeAccessibleFromGeneratedConstructor(
 114237            property.Type,
 114238            containingType.DeclaredAccessibility))
 239        {
 13240            return $"typed as '{property.Type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)}', which is 
 241        }
 242
 101243        return null;
 244    }
 245
 246    /// <summary>
 247    /// Returns whether the record also participates in field-based
 248    /// <c>GenerateConstructor</c> generation.
 249    /// </summary>
 250    internal static bool HasFieldBasedGeneratedConstructorTrigger(
 251        INamedTypeSymbol typeSymbol)
 252    {
 276253        foreach (var attribute in typeSymbol.GetAttributes())
 254        {
 4255            if (attribute.AttributeClass is { } attributeClass &&
 4256                GeneratedConstructorEligibility.IsNeedlrGeneratorsAttribute(
 4257                    attributeClass,
 4258                    GenerateConstructorAttributeName))
 259            {
 4260                return true;
 261            }
 262        }
 263
 132264        return GeneratedConstructorEligibility.HasPositiveFieldGuardTrigger(
 132265            typeSymbol);
 266    }
 267
 268    /// <summary>
 269    /// Finds an existing constructor whose C# signature collides with the proposed
 270    /// overload, ignoring names, nullable annotations, optional values, and
 271    /// <c>params</c>.
 272    /// </summary>
 273    internal static bool TryGetSignatureCollision(
 274        INamedTypeSymbol typeSymbol,
 275        Compilation compilation,
 276        out string collisionDisplay)
 277    {
 89278        var primaryDeclaration = GetPrimaryRecordDeclaration(typeSymbol);
 89279        if (primaryDeclaration?.ParameterList is null)
 280        {
 0281            collisionDisplay = string.Empty;
 0282            return false;
 283        }
 284
 89285        var semanticModel = compilation.GetSemanticModel(
 89286            primaryDeclaration.SyntaxTree);
 89287        var proposed = new List<(ITypeSymbol Type, RefKind RefKind)>();
 374288        foreach (var parameter in primaryDeclaration.ParameterList.Parameters)
 289        {
 98290            if (semanticModel.GetDeclaredSymbol(parameter) is not
 98291                IParameterSymbol parameterSymbol)
 292            {
 0293                collisionDisplay = string.Empty;
 0294                return false;
 295            }
 296
 98297            proposed.Add((parameterSymbol.Type, parameterSymbol.RefKind));
 298        }
 299
 380300        foreach (var property in GetMarkedProperties(typeSymbol))
 301        {
 101302            proposed.Add((property.Type, RefKind.None));
 303        }
 304
 559305        foreach (var constructor in typeSymbol.InstanceConstructors)
 306        {
 197307            if (IsDeclaredInGeneratedFile(constructor) ||
 197308                constructor.Parameters.Length != proposed.Count)
 309            {
 310                continue;
 311            }
 312
 22313            var matches = true;
 108314            for (var i = 0; i < proposed.Count; i++)
 315            {
 41316                if (constructor.Parameters[i].RefKind != proposed[i].RefKind ||
 41317                    !AreSignatureTypesEquivalent(
 41318                        constructor.Parameters[i].Type,
 41319                        proposed[i].Type))
 320                {
 9321                    matches = false;
 9322                    break;
 323                }
 324            }
 325
 22326            if (!matches)
 327                continue;
 328
 13329            collisionDisplay = BuildConstructorDisplay(constructor);
 13330            return true;
 331        }
 332
 76333        collisionDisplay = string.Empty;
 76334        return false;
 335    }
 336
 337    private static RecordConstructorOverloadModel? TryGetModel(
 338        INamedTypeSymbol typeSymbol,
 339        Compilation compilation)
 340    {
 72341        var markedProperties = GetMarkedProperties(typeSymbol);
 72342        if (markedProperties.Count == 0 ||
 72343            GetTypeIneligibilityReason(typeSymbol) is not null ||
 72344            !GeneratedConstructorEligibility.IsDeclaredPartial(typeSymbol) ||
 72345            HasFieldBasedGeneratedConstructorTrigger(typeSymbol))
 346        {
 2347            return null;
 348        }
 349
 70350        var primaryDeclaration = GetPrimaryRecordDeclaration(typeSymbol);
 70351        if (primaryDeclaration?.ParameterList is null)
 0352            return null;
 353
 70354        var semanticModel = compilation.GetSemanticModel(
 70355            primaryDeclaration.SyntaxTree);
 70356        var primaryParameters =
 70357            new RecordConstructorPrimaryParameter[
 70358                primaryDeclaration.ParameterList.Parameters.Count];
 70359        var primaryParameterNames = new HashSet<string>(
 70360            System.StringComparer.Ordinal);
 361
 70362        for (var i = 0;
 151363            i < primaryDeclaration.ParameterList.Parameters.Count;
 81364            i++)
 365        {
 81366            var parameterSyntax =
 81367                primaryDeclaration.ParameterList.Parameters[i];
 81368            if (semanticModel.GetDeclaredSymbol(parameterSyntax) is not
 81369                IParameterSymbol parameterSymbol ||
 81370                !primaryParameterNames.Add(parameterSymbol.Name))
 371            {
 0372                return null;
 373            }
 374
 81375            var documentation =
 81376                DocumentationCommentHelper.GetParameterDocumentation(
 81377                    typeSymbol,
 81378                    parameterSymbol.Name) ??
 81379                $"The value forwarded to the positional primary constructor parameter <paramref name=\"{parameterSymbol.
 81380            primaryParameters[i] = new RecordConstructorPrimaryParameter(
 81381                parameterSymbol.Name,
 81382                GeneratorHelpers.EscapeIdentifier(parameterSymbol.Name),
 81383                parameterSymbol.Type.ToDisplayString(
 81384                    ConstructorGenerationDiscoveryHelper.NullableAwareFormat),
 81385                documentation);
 386        }
 387
 70388        var propertyParameters =
 70389            new RecordConstructorPropertyParameter[markedProperties.Count];
 294390        for (var i = 0; i < markedProperties.Count; i++)
 391        {
 80392            var property = markedProperties[i];
 80393            if (GetPropertyIneligibilityReason(
 80394                typeSymbol,
 80395                property,
 80396                primaryDeclaration) is not null ||
 80397                !primaryParameterNames.Add(property.Name))
 398            {
 3399                return null;
 400            }
 401
 77402            var effectiveGuards =
 77403                ConstructorGuardCodeGenerator.ComposeEffectiveGuards(
 77404                    false,
 77405                    ConstructorGuardDiscoveryHelper.GetExplicitGuards(property));
 77406            if (!ArePropertyGuardsValid(
 77407                compilation,
 77408                typeSymbol,
 77409                property))
 410            {
 0411                return null;
 412            }
 413
 77414            var parameterType = property.Type;
 77415            if (parameterType.IsReferenceType &&
 77416                parameterType.NullableAnnotation ==
 77417                    NullableAnnotation.Annotated &&
 77418                ConstructorGuardCodeGenerator.HasBuiltInNullRejectingGuard(
 77419                    effectiveGuards))
 420            {
 5421                parameterType = parameterType.WithNullableAnnotation(
 5422                    NullableAnnotation.NotAnnotated);
 423            }
 424
 77425            var escapedName = GeneratorHelpers.EscapeIdentifier(property.Name);
 77426            var documentation =
 77427                DocumentationCommentHelper.GetSummaryDocumentation(property) ??
 77428                $"The value assigned to <see cref=\"{escapedName}\"/>.";
 77429            propertyParameters[i] =
 77430                new RecordConstructorPropertyParameter(
 77431                    property.Name,
 77432                    escapedName,
 77433                    parameterType.ToDisplayString(
 77434                        ConstructorGenerationDiscoveryHelper.NullableAwareFormat),
 77435                    documentation,
 77436                    effectiveGuards);
 437        }
 438
 67439        if (TryGetSignatureCollision(
 67440            typeSymbol,
 67441            compilation,
 67442            out _))
 443        {
 3444            return null;
 445        }
 446
 64447        var typeParameterList = typeSymbol.TypeParameters.Length == 0
 64448            ? string.Empty
 64449            : "<" + string.Join(
 64450                ", ",
 64451                typeSymbol.TypeParameters.Select(
 64452                    parameter =>
 4453                        GeneratorHelpers.EscapeIdentifier(parameter.Name))) +
 64454                ">";
 64455        var containingNamespace =
 64456            typeSymbol.ContainingNamespace is { IsGlobalNamespace: false }
 64457                ? typeSymbol.ContainingNamespace.ToDisplayString()
 64458                : string.Empty;
 459
 64460        return new RecordConstructorOverloadModel(
 64461            containingNamespace,
 64462            typeSymbol.Name,
 64463            GeneratorHelpers.EscapeIdentifier(typeSymbol.Name),
 64464            typeParameterList,
 64465            typeSymbol.TypeParameters.Length,
 64466            primaryParameters,
 64467            propertyParameters,
 64468            primaryDeclaration.SyntaxTree.FilePath);
 469    }
 470
 471    private static bool ArePropertyGuardsValid(
 472        Compilation compilation,
 473        INamedTypeSymbol containingType,
 474        IPropertySymbol property)
 475    {
 334476        foreach (var attribute in property.GetAttributes())
 477        {
 90478            if (attribute.AttributeClass is not { } attributeClass)
 479                continue;
 480
 481            ConstructorGuardOccurrence occurrence;
 90482            if (ConstructorGuardDiscoveryHelper.IsConstructorGuardAttributeClass(
 90483                attributeClass))
 484            {
 9485                occurrence =
 9486                    ConstructorGuardAnalysisHelper.BuildDirectGuardOccurrence(
 9487                        property,
 9488                        property.Type,
 9489                        "property",
 9490                        attribute,
 9491                        null);
 492            }
 81493            else if (ConstructorGuardAnalysisHelper.TryGetGuardDefinition(
 81494                attributeClass,
 81495                out var guardType,
 81496                out var methodName,
 81497                out var methodNameExplicit))
 498            {
 4499                occurrence =
 4500                    ConstructorGuardAnalysisHelper.BuildAliasOccurrence(
 4501                        property,
 4502                        property.Type,
 4503                        "property",
 4504                        attribute,
 4505                        null,
 4506                        guardType,
 4507                        methodName,
 4508                        methodNameExplicit,
 4509                        attributeClass.DeclaringSyntaxReferences.Length > 0);
 510            }
 511            else
 512            {
 513                continue;
 514            }
 515
 13516            if (!ConstructorGuardAnalysisHelper
 13517                .IsPositiveGuardOccurrenceValidForGeneration(
 13518                    compilation,
 13519                    containingType,
 13520                    occurrence))
 521            {
 0522                return false;
 523            }
 524        }
 525
 77526        return true;
 527    }
 528
 529    private static bool IsPositionalProperty(
 530        IPropertySymbol property,
 531        RecordDeclarationSyntax primaryDeclaration)
 532    {
 124533        return primaryDeclaration.ParameterList?.Parameters.Any(
 257534            parameter => parameter.Identifier.ValueText == property.Name) == true;
 535    }
 536
 537    private static bool IsDeclaredInGeneratedFile(ISymbol symbol)
 538    {
 197539        return symbol.Locations.Any(location =>
 396540            location.SourceTree?.FilePath.EndsWith(
 396541                GeneratedFileSuffix,
 396542                System.StringComparison.Ordinal) == true);
 543    }
 544
 545    private static string BuildConstructorDisplay(IMethodSymbol constructor)
 546    {
 36547        return $"{constructor.ContainingType.Name}({string.Join(", ", constructor.Parameters.Select(parameter => paramet
 548    }
 549
 550    private static bool ContainsPointerType(ITypeSymbol type)
 551    {
 260552        return type switch
 260553        {
 7554            IPointerTypeSymbol => true,
 0555            IFunctionPointerTypeSymbol => true,
 12556            IArrayTypeSymbol arrayType => ContainsPointerType(
 12557                arrayType.ElementType),
 241558            _ => false,
 260559        };
 560    }
 561
 562    private static bool AreSignatureTypesEquivalent(
 563        ITypeSymbol left,
 564        ITypeSymbol right)
 565    {
 59566        if (SymbolEqualityComparer.Default.Equals(left, right))
 29567            return true;
 568
 30569        if ((left is IDynamicTypeSymbol &&
 30570                right.SpecialType == SpecialType.System_Object) ||
 30571            (right is IDynamicTypeSymbol &&
 30572                left.SpecialType == SpecialType.System_Object))
 573        {
 7574            return true;
 575        }
 576
 23577        if (left is IArrayTypeSymbol leftArray &&
 23578            right is IArrayTypeSymbol rightArray)
 579        {
 5580            return leftArray.Rank == rightArray.Rank &&
 5581                AreSignatureTypesEquivalent(
 5582                    leftArray.ElementType,
 5583                    rightArray.ElementType);
 584        }
 585
 18586        if (left is not INamedTypeSymbol leftNamed ||
 18587            right is not INamedTypeSymbol rightNamed ||
 18588            !SymbolEqualityComparer.Default.Equals(
 18589                leftNamed.OriginalDefinition,
 18590                rightNamed.OriginalDefinition))
 591        {
 5592            return false;
 593        }
 594
 13595        if (leftNamed.ContainingType is not null &&
 13596            rightNamed.ContainingType is not null &&
 13597            !AreSignatureTypesEquivalent(
 13598                leftNamed.ContainingType,
 13599                rightNamed.ContainingType))
 600        {
 3601            return false;
 602        }
 603
 40604        for (var i = 0; i < leftNamed.TypeArguments.Length; i++)
 605        {
 14606            if (!AreSignatureTypesEquivalent(
 14607                leftNamed.TypeArguments[i],
 14608                rightNamed.TypeArguments[i]))
 609            {
 4610                return false;
 611            }
 612        }
 613
 6614        return true;
 615    }
 616
 617    private static bool IsTypeAccessibleFromGeneratedConstructor(
 618        ITypeSymbol type,
 619        Accessibility containingTypeAccessibility)
 620    {
 621        switch (type)
 622        {
 623            case IArrayTypeSymbol arrayType:
 9624                return IsTypeAccessibleFromGeneratedConstructor(
 9625                    arrayType.ElementType,
 9626                    containingTypeAccessibility);
 627            case ITypeParameterSymbol:
 628            case IDynamicTypeSymbol:
 11629                return true;
 630            case INamedTypeSymbol namedType:
 122631                if (!IsNamedTypeAccessibleFromGeneratedConstructor(
 122632                    namedType,
 122633                    containingTypeAccessibility))
 634                {
 13635                    return false;
 636                }
 637
 109638                return namedType.TypeArguments.All(typeArgument =>
 128639                    IsTypeAccessibleFromGeneratedConstructor(
 128640                        typeArgument,
 128641                        containingTypeAccessibility));
 642            default:
 0643                return true;
 644        }
 645    }
 646
 647    private static bool IsNamedTypeAccessibleFromGeneratedConstructor(
 648        INamedTypeSymbol type,
 649        Accessibility containingTypeAccessibility)
 650    {
 470651        for (var current = type; current is not null; current = current.ContainingType)
 652        {
 126653            if (current.SpecialType != SpecialType.None)
 654                continue;
 655
 45656            if (containingTypeAccessibility == Accessibility.Public)
 657            {
 40658                if (current.DeclaredAccessibility != Accessibility.Public)
 11659                    return false;
 660            }
 5661            else if (current.DeclaredAccessibility is not (
 5662                Accessibility.Public or
 5663                Accessibility.Internal or
 5664                Accessibility.ProtectedOrInternal))
 665            {
 2666                return false;
 667            }
 668        }
 669
 109670        return true;
 671    }
 672}

Methods/Properties

IsCandidateRecordDeclaration(Microsoft.CodeAnalysis.SyntaxNode)
TryCreateCanonicalModel(Microsoft.CodeAnalysis.GeneratorSyntaxContext)
GetMarkedProperties(Microsoft.CodeAnalysis.INamedTypeSymbol)
HasMarker(Microsoft.CodeAnalysis.IPropertySymbol)
GetMarkerAttribute(Microsoft.CodeAnalysis.IPropertySymbol)
GetPrimaryRecordDeclaration(Microsoft.CodeAnalysis.INamedTypeSymbol)
GetTypeIneligibilityReason(Microsoft.CodeAnalysis.INamedTypeSymbol)
GetPrimaryConstructor(Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax)
GetPropertyIneligibilityReason(Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.IPropertySymbol,Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax)
HasFieldBasedGeneratedConstructorTrigger(Microsoft.CodeAnalysis.INamedTypeSymbol)
TryGetSignatureCollision(Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.Compilation,System.String&)
TryGetModel(Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.Compilation)
ArePropertyGuardsValid(Microsoft.CodeAnalysis.Compilation,Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.IPropertySymbol)
IsPositionalProperty(Microsoft.CodeAnalysis.IPropertySymbol,Microsoft.CodeAnalysis.CSharp.Syntax.RecordDeclarationSyntax)
IsDeclaredInGeneratedFile(Microsoft.CodeAnalysis.ISymbol)
BuildConstructorDisplay(Microsoft.CodeAnalysis.IMethodSymbol)
ContainsPointerType(Microsoft.CodeAnalysis.ITypeSymbol)
AreSignatureTypesEquivalent(Microsoft.CodeAnalysis.ITypeSymbol,Microsoft.CodeAnalysis.ITypeSymbol)
IsTypeAccessibleFromGeneratedConstructor(Microsoft.CodeAnalysis.ITypeSymbol,Microsoft.CodeAnalysis.Accessibility)
IsNamedTypeAccessibleFromGeneratedConstructor(Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.Accessibility)