File: Shared\Extensions\IPropertySymbolExtensions.cs
Web Access
Project: ..\..\..\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeGeneration;
 
namespace Microsoft.CodeAnalysis.Shared.Extensions
{
    internal static partial class IPropertySymbolExtensions
    {
        public static IPropertySymbol RenameParameters(this IPropertySymbol property, ImmutableArray<string> parameterNames)
        {
            var parameterList = property.Parameters;
            if (parameterList.Select(p => p.Name).SequenceEqual(parameterNames))
            {
                return property;
            }
 
            var parameters = parameterList.RenameParameters(parameterNames);
 
            return CodeGenerationSymbolFactory.CreatePropertySymbol(
                property.ContainingType,
                property.GetAttributes(),
                property.DeclaredAccessibility,
                property.GetSymbolModifiers(),
                property.Type,
                property.RefKind,
                property.ExplicitInterfaceImplementations,
                property.Name,
                parameters,
                property.GetMethod,
                property.SetMethod,
                property.IsIndexer);
        }
 
        public static IPropertySymbol RemoveInaccessibleAttributesAndAttributesOfTypes(
            this IPropertySymbol property, ISymbol accessibleWithin, params INamedTypeSymbol[] attributesToRemove)
        {
            // Many static predicates use the same state argument in this method
            var arg = (attributesToRemove, accessibleWithin);
 
            var someParameterHasAttribute = property.Parameters
                .Any(static (p, arg) => p.GetAttributes().Any(ShouldRemoveAttribute, arg), arg);
            if (!someParameterHasAttribute)
                return property;
 
            return CodeGenerationSymbolFactory.CreatePropertySymbol(
                property.ContainingType,
                property.GetAttributes(),
                property.DeclaredAccessibility,
                property.GetSymbolModifiers(),
                property.Type,
                property.RefKind,
                property.ExplicitInterfaceImplementations,
                property.Name,
                property.Parameters.SelectAsArray(static (p, arg) =>
                    CodeGenerationSymbolFactory.CreateParameterSymbol(
                        p.GetAttributes().WhereAsArray(static (a, arg) => !ShouldRemoveAttribute(a, arg), arg),
                        p.RefKind, p.IsParams, p.Type, p.Name, p.IsOptional,
                        p.HasExplicitDefaultValue, p.HasExplicitDefaultValue ? p.ExplicitDefaultValue : null), arg),
                property.GetMethod,
                property.SetMethod,
                property.IsIndexer);
 
            static bool ShouldRemoveAttribute(AttributeData a, (INamedTypeSymbol[] attributesToRemove, ISymbol accessibleWithin) arg)
                => arg.attributesToRemove.Any(attr => attr.Equals(a.AttributeClass)) ||
                a.AttributeClass?.IsAccessibleWithin(arg.accessibleWithin) == false;
        }
 
        public static bool IsWritableInConstructor(this IPropertySymbol property)
            => property.SetMethod != null || ContainsBackingField(property);
 
        private static bool ContainsBackingField(IPropertySymbol property)
            => property.GetBackingFieldIfAny() != null;
    }
}