< Summary

Information
Class: NexusLabs.Needlr.Generators.RecordConstructorOverloadDiscoveryHelper
Assembly: NexusLabs.Needlr.Generators
File(s): /_work/nick-alienware-needlr-1-1784953859-3e8997/needlr/needlr/src/NexusLabs.Needlr.Generators/RecordConstructorOverloadDiscoveryHelper.cs
Line coverage
85%
Covered lines: 267
Uncovered lines: 46
Coverable lines: 313
Total lines: 627
Line coverage: 85.3%
Branch coverage
71%
Covered branches: 141
Total branches: 196
Branch coverage: 71.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/_work/nick-alienware-needlr-1-1784953859-3e8997/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    {
 70132        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    {
 2342        var recordDeclaration = (RecordDeclarationSyntax)context.Node;
 2343        if (context.SemanticModel.GetDeclaredSymbol(recordDeclaration) is not
 2344            INamedTypeSymbol typeSymbol ||
 2345            !GeneratedConstructorEligibility.IsCanonicalDeclaration(
 2346                typeSymbol,
 2347                recordDeclaration))
 48        {
 249            return null;
 50        }
 51
 2152        return TryGetModel(
 2153            typeSymbol,
 2154            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    {
 5464        return typeSymbol.GetMembers()
 5465            .OfType<IPropertySymbol>()
 5466            .Where(HasMarker)
 5467            .OrderBy(
 5468                property =>
 1669                    property.Locations.FirstOrDefault()?.SourceTree?.FilePath ??
 1670                    string.Empty,
 5471                System.StringComparer.Ordinal)
 5472            .ThenBy(
 5473                property =>
 1674                    property.Locations.FirstOrDefault()?.SourceSpan.Start ?? 0)
 5475            .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    {
 230883        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    {
 480391        foreach (var attribute in property.GetAttributes())
 92        {
 15893            if (attribute.AttributeClass is { } attributeClass &&
 15894                GeneratedConstructorEligibility.IsNeedlrGeneratorsAttribute(
 15895                    attributeClass,
 15896                    RecordConstructorOverloadParameterAttributeName))
 97            {
 15398                return attribute;
 99            }
 100        }
 101
 2167102        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    {
 123111        return typeSymbol.DeclaringSyntaxReferences
 123112            .Select(reference => reference.GetSyntax())
 123113            .OfType<RecordDeclarationSyntax>()
 246114            .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    {
 57124        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
 55131        if (typeSymbol.TypeKind == TypeKind.Struct)
 2132            return "a record struct";
 133
 53134        if (typeSymbol.IsFileLocal)
 2135            return "a file-local record that cannot be extended from a generated file";
 136
 51137        if (typeSymbol.ContainingType is not null)
 2138            return "a nested record";
 139
 49140        if (GetPrimaryRecordDeclaration(typeSymbol) is null)
 2141            return "a non-positional record with no primary parameter list";
 142
 47143        if (typeSymbol.BaseType is not null &&
 47144            typeSymbol.BaseType.SpecialType != SpecialType.System_Object)
 145        {
 2146            return "an inherited record";
 147        }
 148
 45149        return null;
 150    }
 151
 152    /// <summary>
 153    /// Returns why a marked property cannot participate, or
 154    /// <see langword="null"/> when it is assignable by the generated constructor.
 155    /// </summary>
 156    internal static string? GetPropertyIneligibilityReason(
 157        INamedTypeSymbol containingType,
 158        IPropertySymbol property,
 159        RecordDeclarationSyntax primaryDeclaration)
 160    {
 47161        if (!SymbolEqualityComparer.Default.Equals(
 47162            property.ContainingType,
 47163            containingType))
 164        {
 0165            return "inherited rather than declared directly by the record";
 166        }
 167
 47168        if (property.IsStatic)
 2169            return "static";
 170
 45171        if (property.IsIndexer)
 2172            return "an indexer";
 173
 43174        if (IsPositionalProperty(property, primaryDeclaration))
 175        {
 2176            return "a positional property synthesized from a primary constructor parameter";
 177        }
 178
 41179        if (property.SetMethod is null)
 180        {
 2181            return "get-only and cannot be assigned by the generated constructor";
 182        }
 183
 39184        if (property.ExplicitInterfaceImplementations.Length > 0)
 185        {
 0186            return "an explicit interface implementation and cannot be assigned by name";
 187        }
 188
 39189        if (property.IsAbstract)
 190        {
 0191            return "abstract and has no assignable implementation on the record";
 192        }
 193
 39194        if (property.IsRequired)
 195        {
 2196            return "required; the generated overload does not claim to satisfy the record's complete required-member con
 197        }
 198
 37199        if (!IsTypeAccessibleFromGeneratedConstructor(
 37200            property.Type,
 37201            containingType.DeclaredAccessibility))
 202        {
 2203            return $"typed as '{property.Type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)}', which is 
 204        }
 205
 35206        return null;
 207    }
 208
 209    /// <summary>
 210    /// Returns whether the record also participates in field-based
 211    /// <c>GenerateConstructor</c> generation.
 212    /// </summary>
 213    internal static bool HasFieldBasedGeneratedConstructorTrigger(
 214        INamedTypeSymbol typeSymbol)
 215    {
 126216        foreach (var attribute in typeSymbol.GetAttributes())
 217        {
 4218            if (attribute.AttributeClass is { } attributeClass &&
 4219                GeneratedConstructorEligibility.IsNeedlrGeneratorsAttribute(
 4220                    attributeClass,
 4221                    GenerateConstructorAttributeName))
 222            {
 4223                return true;
 224            }
 225        }
 226
 57227        return GeneratedConstructorEligibility.HasPositiveFieldGuardTrigger(
 57228            typeSymbol);
 229    }
 230
 231    /// <summary>
 232    /// Finds an existing constructor whose C# signature collides with the proposed
 233    /// overload, ignoring names, nullable annotations, optional values, and
 234    /// <c>params</c>.
 235    /// </summary>
 236    internal static bool TryGetSignatureCollision(
 237        INamedTypeSymbol typeSymbol,
 238        Compilation compilation,
 239        out string collisionDisplay)
 240    {
 31241        var primaryDeclaration = GetPrimaryRecordDeclaration(typeSymbol);
 31242        if (primaryDeclaration?.ParameterList is null)
 243        {
 0244            collisionDisplay = string.Empty;
 0245            return false;
 246        }
 247
 31248        var semanticModel = compilation.GetSemanticModel(
 31249            primaryDeclaration.SyntaxTree);
 31250        var proposed = new List<(ITypeSymbol Type, RefKind RefKind)>();
 138251        foreach (var parameter in primaryDeclaration.ParameterList.Parameters)
 252        {
 38253            if (semanticModel.GetDeclaredSymbol(parameter) is not
 38254                IParameterSymbol parameterSymbol)
 255            {
 0256                collisionDisplay = string.Empty;
 0257                return false;
 258            }
 259
 38260            proposed.Add((parameterSymbol.Type, parameterSymbol.RefKind));
 261        }
 262
 132263        foreach (var property in GetMarkedProperties(typeSymbol))
 264        {
 35265            proposed.Add((property.Type, RefKind.None));
 266        }
 267
 188268        foreach (var constructor in typeSymbol.InstanceConstructors)
 269        {
 67270            if (IsDeclaredInGeneratedFile(constructor) ||
 67271                constructor.Parameters.Length != proposed.Count)
 272            {
 273                continue;
 274            }
 275
 8276            var matches = true;
 42277            for (var i = 0; i < proposed.Count; i++)
 278            {
 13279                if (constructor.Parameters[i].RefKind != proposed[i].RefKind ||
 13280                    !AreSignatureTypesEquivalent(
 13281                        constructor.Parameters[i].Type,
 13282                        proposed[i].Type))
 283                {
 0284                    matches = false;
 0285                    break;
 286                }
 287            }
 288
 8289            if (!matches)
 290                continue;
 291
 8292            collisionDisplay = BuildConstructorDisplay(constructor);
 8293            return true;
 294        }
 295
 23296        collisionDisplay = string.Empty;
 23297        return false;
 298    }
 299
 300    private static RecordConstructorOverloadModel? TryGetModel(
 301        INamedTypeSymbol typeSymbol,
 302        Compilation compilation)
 303    {
 21304        var markedProperties = GetMarkedProperties(typeSymbol);
 21305        if (markedProperties.Count == 0 ||
 21306            GetTypeIneligibilityReason(typeSymbol) is not null ||
 21307            !GeneratedConstructorEligibility.IsDeclaredPartial(typeSymbol) ||
 21308            HasFieldBasedGeneratedConstructorTrigger(typeSymbol))
 309        {
 1310            return null;
 311        }
 312
 20313        var primaryDeclaration = GetPrimaryRecordDeclaration(typeSymbol);
 20314        if (primaryDeclaration?.ParameterList is null)
 0315            return null;
 316
 20317        var semanticModel = compilation.GetSemanticModel(
 20318            primaryDeclaration.SyntaxTree);
 20319        var primaryParameters =
 20320            new RecordConstructorPrimaryParameter[
 20321                primaryDeclaration.ParameterList.Parameters.Count];
 20322        var primaryParameterNames = new HashSet<string>(
 20323            System.StringComparer.Ordinal);
 324
 20325        for (var i = 0;
 49326            i < primaryDeclaration.ParameterList.Parameters.Count;
 29327            i++)
 328        {
 29329            var parameterSyntax =
 29330                primaryDeclaration.ParameterList.Parameters[i];
 29331            if (semanticModel.GetDeclaredSymbol(parameterSyntax) is not
 29332                IParameterSymbol parameterSymbol ||
 29333                !primaryParameterNames.Add(parameterSymbol.Name))
 334            {
 0335                return null;
 336            }
 337
 29338            var documentation =
 29339                DocumentationCommentHelper.GetParameterDocumentation(
 29340                    typeSymbol,
 29341                    parameterSymbol.Name) ??
 29342                $"The value forwarded to the positional primary constructor parameter <paramref name=\"{parameterSymbol.
 29343            primaryParameters[i] = new RecordConstructorPrimaryParameter(
 29344                parameterSymbol.Name,
 29345                GeneratorHelpers.EscapeIdentifier(parameterSymbol.Name),
 29346                parameterSymbol.Type.ToDisplayString(
 29347                    ConstructorGenerationDiscoveryHelper.NullableAwareFormat),
 29348                documentation);
 349        }
 350
 20351        var propertyParameters =
 20352            new RecordConstructorPropertyParameter[markedProperties.Count];
 88353        for (var i = 0; i < markedProperties.Count; i++)
 354        {
 24355            var property = markedProperties[i];
 24356            if (GetPropertyIneligibilityReason(
 24357                typeSymbol,
 24358                property,
 24359                primaryDeclaration) is not null ||
 24360                !primaryParameterNames.Add(property.Name))
 361            {
 0362                return null;
 363            }
 364
 24365            var effectiveGuards =
 24366                ConstructorGuardCodeGenerator.ComposeEffectiveGuards(
 24367                    false,
 24368                    ConstructorGuardDiscoveryHelper.GetExplicitGuards(property));
 24369            if (!ArePropertyGuardsValid(
 24370                compilation,
 24371                typeSymbol,
 24372                property))
 373            {
 0374                return null;
 375            }
 376
 24377            var parameterType = property.Type;
 24378            if (parameterType.IsReferenceType &&
 24379                parameterType.NullableAnnotation ==
 24380                    NullableAnnotation.Annotated &&
 24381                ConstructorGuardCodeGenerator.HasBuiltInNullRejectingGuard(
 24382                    effectiveGuards))
 383            {
 3384                parameterType = parameterType.WithNullableAnnotation(
 3385                    NullableAnnotation.NotAnnotated);
 386            }
 387
 24388            var escapedName = GeneratorHelpers.EscapeIdentifier(property.Name);
 24389            var documentation =
 24390                DocumentationCommentHelper.GetSummaryDocumentation(property) ??
 24391                $"The value assigned to <see cref=\"{escapedName}\"/>.";
 24392            propertyParameters[i] =
 24393                new RecordConstructorPropertyParameter(
 24394                    property.Name,
 24395                    escapedName,
 24396                    parameterType.ToDisplayString(
 24397                        ConstructorGenerationDiscoveryHelper.NullableAwareFormat),
 24398                    documentation,
 24399                    effectiveGuards);
 400        }
 401
 20402        if (TryGetSignatureCollision(
 20403            typeSymbol,
 20404            compilation,
 20405            out _))
 406        {
 2407            return null;
 408        }
 409
 18410        var typeParameterList = typeSymbol.TypeParameters.Length == 0
 18411            ? string.Empty
 18412            : "<" + string.Join(
 18413                ", ",
 18414                typeSymbol.TypeParameters.Select(
 18415                    parameter =>
 2416                        GeneratorHelpers.EscapeIdentifier(parameter.Name))) +
 18417                ">";
 18418        var containingNamespace =
 18419            typeSymbol.ContainingNamespace is { IsGlobalNamespace: false }
 18420                ? typeSymbol.ContainingNamespace.ToDisplayString()
 18421                : string.Empty;
 422
 18423        return new RecordConstructorOverloadModel(
 18424            containingNamespace,
 18425            typeSymbol.Name,
 18426            GeneratorHelpers.EscapeIdentifier(typeSymbol.Name),
 18427            typeParameterList,
 18428            typeSymbol.TypeParameters.Length,
 18429            primaryParameters,
 18430            propertyParameters,
 18431            primaryDeclaration.SyntaxTree.FilePath);
 432    }
 433
 434    private static bool ArePropertyGuardsValid(
 435        Compilation compilation,
 436        INamedTypeSymbol containingType,
 437        IPropertySymbol property)
 438    {
 110439        foreach (var attribute in property.GetAttributes())
 440        {
 31441            if (attribute.AttributeClass is not { } attributeClass)
 442                continue;
 443
 444            ConstructorGuardOccurrence occurrence;
 31445            if (ConstructorGuardDiscoveryHelper.IsConstructorGuardAttributeClass(
 31446                attributeClass))
 447            {
 5448                occurrence =
 5449                    ConstructorGuardAnalysisHelper.BuildDirectGuardOccurrence(
 5450                        property,
 5451                        property.Type,
 5452                        "property",
 5453                        attribute,
 5454                        null);
 455            }
 26456            else if (ConstructorGuardAnalysisHelper.TryGetGuardDefinition(
 26457                attributeClass,
 26458                out var guardType,
 26459                out var methodName,
 26460                out var methodNameExplicit))
 461            {
 2462                occurrence =
 2463                    ConstructorGuardAnalysisHelper.BuildAliasOccurrence(
 2464                        property,
 2465                        property.Type,
 2466                        "property",
 2467                        attribute,
 2468                        null,
 2469                        guardType,
 2470                        methodName,
 2471                        methodNameExplicit,
 2472                        attributeClass.DeclaringSyntaxReferences.Length > 0);
 473            }
 474            else
 475            {
 476                continue;
 477            }
 478
 7479            if (!ConstructorGuardAnalysisHelper
 7480                .IsPositiveGuardOccurrenceValidForGeneration(
 7481                    compilation,
 7482                    containingType,
 7483                    occurrence))
 484            {
 0485                return false;
 486            }
 487        }
 488
 24489        return true;
 490    }
 491
 492    private static bool IsPositionalProperty(
 493        IPropertySymbol property,
 494        RecordDeclarationSyntax primaryDeclaration)
 495    {
 43496        return primaryDeclaration.ParameterList?.Parameters.Any(
 93497            parameter => parameter.Identifier.ValueText == property.Name) == true;
 498    }
 499
 500    private static bool IsDeclaredInGeneratedFile(ISymbol symbol)
 501    {
 67502        return symbol.Locations.Any(location =>
 136503            location.SourceTree?.FilePath.EndsWith(
 136504                GeneratedFileSuffix,
 136505                System.StringComparison.Ordinal) == true);
 506    }
 507
 508    private static string BuildConstructorDisplay(IMethodSymbol constructor)
 509    {
 21510        return $"{constructor.ContainingType.Name}({string.Join(", ", constructor.Parameters.Select(parameter => paramet
 511    }
 512
 513    private static bool AreSignatureTypesEquivalent(
 514        ITypeSymbol left,
 515        ITypeSymbol right)
 516    {
 13517        if (SymbolEqualityComparer.Default.Equals(left, right))
 11518            return true;
 519
 2520        if ((left is IDynamicTypeSymbol &&
 2521                right.SpecialType == SpecialType.System_Object) ||
 2522            (right is IDynamicTypeSymbol &&
 2523                left.SpecialType == SpecialType.System_Object))
 524        {
 2525            return true;
 526        }
 527
 0528        if (left is IArrayTypeSymbol leftArray &&
 0529            right is IArrayTypeSymbol rightArray)
 530        {
 0531            return leftArray.Rank == rightArray.Rank &&
 0532                AreSignatureTypesEquivalent(
 0533                    leftArray.ElementType,
 0534                    rightArray.ElementType);
 535        }
 536
 0537        if (left is IPointerTypeSymbol leftPointer &&
 0538            right is IPointerTypeSymbol rightPointer)
 539        {
 0540            return AreSignatureTypesEquivalent(
 0541                leftPointer.PointedAtType,
 0542                rightPointer.PointedAtType);
 543        }
 544
 0545        if (left is not INamedTypeSymbol leftNamed ||
 0546            right is not INamedTypeSymbol rightNamed ||
 0547            !SymbolEqualityComparer.Default.Equals(
 0548                leftNamed.OriginalDefinition,
 0549                rightNamed.OriginalDefinition) ||
 0550            leftNamed.TypeArguments.Length != rightNamed.TypeArguments.Length)
 551        {
 0552            return false;
 553        }
 554
 0555        for (var i = 0; i < leftNamed.TypeArguments.Length; i++)
 556        {
 0557            if (!AreSignatureTypesEquivalent(
 0558                leftNamed.TypeArguments[i],
 0559                rightNamed.TypeArguments[i]))
 560            {
 0561                return false;
 562            }
 563        }
 564
 0565        return true;
 566    }
 567
 568    private static bool IsTypeAccessibleFromGeneratedConstructor(
 569        ITypeSymbol type,
 570        Accessibility containingTypeAccessibility)
 571    {
 572        switch (type)
 573        {
 574            case IArrayTypeSymbol arrayType:
 0575                return IsTypeAccessibleFromGeneratedConstructor(
 0576                    arrayType.ElementType,
 0577                    containingTypeAccessibility);
 578            case IPointerTypeSymbol pointerType:
 0579                return IsTypeAccessibleFromGeneratedConstructor(
 0580                    pointerType.PointedAtType,
 0581                    containingTypeAccessibility);
 582            case ITypeParameterSymbol:
 583            case IDynamicTypeSymbol:
 2584                return true;
 585            case INamedTypeSymbol namedType:
 36586                if (!IsNamedTypeAccessibleFromGeneratedConstructor(
 36587                    namedType,
 36588                    containingTypeAccessibility))
 589                {
 2590                    return false;
 591                }
 592
 34593                return namedType.TypeArguments.All(typeArgument =>
 35594                    IsTypeAccessibleFromGeneratedConstructor(
 35595                        typeArgument,
 35596                        containingTypeAccessibility));
 597            default:
 0598                return true;
 599        }
 600    }
 601
 602    private static bool IsNamedTypeAccessibleFromGeneratedConstructor(
 603        INamedTypeSymbol type,
 604        Accessibility containingTypeAccessibility)
 605    {
 140606        for (var current = type; current is not null; current = current.ContainingType)
 607        {
 36608            if (current.SpecialType != SpecialType.None)
 609                continue;
 610
 8611            if (containingTypeAccessibility == Accessibility.Public)
 612            {
 7613                if (current.DeclaredAccessibility != Accessibility.Public)
 2614                    return false;
 615            }
 1616            else if (current.DeclaredAccessibility is not (
 1617                Accessibility.Public or
 1618                Accessibility.Internal or
 1619                Accessibility.ProtectedOrInternal))
 620            {
 0621                return false;
 622            }
 623        }
 624
 34625        return true;
 626    }
 627}

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)
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)
AreSignatureTypesEquivalent(Microsoft.CodeAnalysis.ITypeSymbol,Microsoft.CodeAnalysis.ITypeSymbol)
IsTypeAccessibleFromGeneratedConstructor(Microsoft.CodeAnalysis.ITypeSymbol,Microsoft.CodeAnalysis.Accessibility)
IsNamedTypeAccessibleFromGeneratedConstructor(Microsoft.CodeAnalysis.INamedTypeSymbol,Microsoft.CodeAnalysis.Accessibility)