| File: Filtering\ImplicitSymbolFilter.cs | Web Access |
| Project: src\sdk\src\Compatibility\Microsoft.DotNet.ApiSymbolExtensions\Microsoft.DotNet.ApiSymbolExtensions.csproj (Microsoft.DotNet.ApiSymbolExtensions) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.CodeAnalysis; using Microsoft.DotNet.ApiSymbolExtensions; using Microsoft.DotNet.ApiSymbolExtensions.Filtering; namespace Microsoft.DotNet.ApiSymbolExtensions.Filtering { /// <summary> /// Filter out implicitly generated members for properties, events, etc. /// </summary> public class ImplicitSymbolFilter : ISymbolFilter { /// <summary> /// Determines whether implicitly generated symbols <see cref="ISymbol"/> should be included. /// </summary> /// <param name="symbol"><see cref="ISymbol"/> to evaluate.</param> /// <returns>True to include the <paramref name="symbol"/> or false to filter it out.</returns> public bool Include(ISymbol symbol) { if (symbol is IMethodSymbol method) { if (method.IsImplicitlyDeclared || method.Kind == SymbolKind.NamedType || method.MethodKind == MethodKind.PropertyGet || method.MethodKind == MethodKind.PropertySet || method.MethodKind == MethodKind.EventAdd || method.MethodKind == MethodKind.EventRemove || method.MethodKind == MethodKind.EventRaise || method.MethodKind == MethodKind.DelegateInvoke) { return false; } // If the method is an explicitly implemented getter or setter, exclude it. // https://github.com/dotnet/roslyn/issues/53911 if (method.MethodKind == MethodKind.ExplicitInterfaceImplementation && method.ExplicitInterfaceImplementations.Any(m => m is { MethodKind: MethodKind.PropertyGet or MethodKind.PropertySet or MethodKind.EventAdd or MethodKind.EventRemove })) { return false; } } if (symbol is ITypeSymbol type) { if (type.DeclaredAccessibility == Accessibility.Internal && ( // exclude the compiler generated `<Module>` type type.Name == "<Module>" || // exclude any types which the compiler embedded - marked with EmbeddedAttribute. // these will be generated by the compiler when compiling C# syntax that requires them. type.GetAttributes().Any(a => a.AttributeClass?.Name == "EmbeddedAttribute" && a.AttributeClass?.ContainingNamespace.ToDisplayString() == "Microsoft.CodeAnalysis"))) { return false; } } // exclude compiler-synthesized members on record if (symbol.ContainingType is { IsRecord: true }) { if (symbol.IsCompilerGenerated()) { return false; } // see if we can identify the record parameter syntax by locating the compiler generated constructor if (symbol.ContainingType.TryGetRecordConstructor(out IMethodSymbol? recordConstructor)) { // exclude the compiler generated constructor if (SymbolEqualityComparer.Default.Equals(symbol, recordConstructor)) { return false; } // exclude the compiler generated properties if (symbol is IPropertySymbol) { // Exclude members with the same name as the record constructor's parameters return !recordConstructor.Parameters.Any(p => p.Name == symbol.Name); } } } return true; } } }