| File: ContextReceiver.cs | Web Access |
| Project: src\src\Generators\Microsoft.Gen.ContextualOptions\Microsoft.Gen.ContextualOptions.csproj (Microsoft.Gen.ContextualOptions) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.Gen.ContextualOptions; /// <summary> /// Type declaration syntax receiver for generators. /// </summary> internal sealed class ContextReceiver : ISyntaxReceiver { private readonly CancellationToken _token; public ContextReceiver(CancellationToken token) { _token = token; } private readonly List<TypeDeclarationSyntax> _typeDeclarations = []; public void OnVisitSyntaxNode(SyntaxNode syntaxNode) { _token.ThrowIfCancellationRequested(); if (syntaxNode is TypeDeclarationSyntax type && type is not InterfaceDeclarationSyntax) { _typeDeclarations.Add(type); } } public bool TryGetTypeDeclarations(Compilation compilation, out Dictionary<INamedTypeSymbol, List<TypeDeclarationSyntax>>? typeDeclarations) { if (!SymbolLoader.TryLoad(compilation, out var holder)) { typeDeclarations = default; return false; } typeDeclarations = _typeDeclarations .ToLookup(declaration => declaration.SyntaxTree) .SelectMany(declarations => declarations.Select(declaration => (symbol: compilation.GetSemanticModel(declarations.Key).GetDeclaredSymbol(declaration), declaration))) .Where(_ => _.symbol is INamedTypeSymbol) .Where(_ => _.symbol!.GetAttributes().Any(attribute => SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, holder!.OptionsContextAttribute))) .ToLookup(_ => _.symbol, _ => _.declaration, comparer: SymbolEqualityComparer.Default) .ToDictionary<IGrouping<ISymbol?, TypeDeclarationSyntax>, INamedTypeSymbol, List<TypeDeclarationSyntax>>( group => (INamedTypeSymbol)group.Key!, group => group.ToList(), comparer: SymbolEqualityComparer.Default); return true; } }