internal AnalyzerSymbolStartAnalysisContext(DiagnosticAnalyzer analyzer, HostSymbolStartAnalysisScope scope, ISymbol owningSymbol, Compilation compilation, AnalyzerOptions options, CancellationToken cancellationToken) : base(owningSymbol, compilation, options, cancellationToken) { _analyzer = analyzer; _scope = scope; }
public Task <HostSymbolStartAnalysisScope> GetSymbolAnalysisScopeAsync( ISymbol symbol, ImmutableArray <SymbolStartAnalyzerAction> symbolStartActions, AnalyzerExecutor analyzerExecutor) { lock (_gate) { _lazySymbolScopeTasks = _lazySymbolScopeTasks ?? new Dictionary <ISymbol, Task <HostSymbolStartAnalysisScope> >(); if (!_lazySymbolScopeTasks.TryGetValue(symbol, out var symbolScopeTask)) { symbolScopeTask = Task.Run(() => getSymbolAnalysisScopeCore(), analyzerExecutor.CancellationToken); _lazySymbolScopeTasks.Add(symbol, symbolScopeTask); } return(symbolScopeTask); HostSymbolStartAnalysisScope getSymbolAnalysisScopeCore() { var symbolAnalysisScope = new HostSymbolStartAnalysisScope(); analyzerExecutor.ExecuteSymbolStartActions(symbol, _analyzer, symbolStartActions, symbolAnalysisScope); var symbolEndActions = symbolAnalysisScope.GetAnalyzerActions(_analyzer); if (symbolEndActions.SymbolEndActionsCount > 0) { var dependentSymbols = getDependentSymbols(); lock (_gate) { _lazyPendingMemberSymbolsMapOpt = _lazyPendingMemberSymbolsMapOpt ?? new Dictionary <ISymbol, HashSet <ISymbol> >(); // Guard against entry added from another thread. VerifyNewEntryForPendingMemberSymbolsMap(symbol, dependentSymbols); _lazyPendingMemberSymbolsMapOpt[symbol] = dependentSymbols; } } return(symbolAnalysisScope); } } HashSet <ISymbol> getDependentSymbols() { HashSet <ISymbol> memberSet = null; switch (symbol.Kind) { case SymbolKind.NamedType: processMembers(((INamedTypeSymbol)symbol).GetMembers()); break; case SymbolKind.Namespace: processMembers(((INamespaceSymbol)symbol).GetMembers()); break; } return(memberSet); void processMembers(IEnumerable <ISymbol> members) { foreach (var member in members) { if (!member.IsImplicitlyDeclared && member.IsInSource()) { memberSet = memberSet ?? new HashSet <ISymbol>(); memberSet.Add(member); // Ensure that we include symbols for both parts of partial methods. if (member is IMethodSymbol method && !(method.PartialImplementationPart is null)) { memberSet.Add(method.PartialImplementationPart); } } if (member.Kind != symbol.Kind && member is INamedTypeSymbol typeMember) { processMembers(typeMember.GetMembers()); } } } } }
public Task <HostSymbolStartAnalysisScope> GetSymbolAnalysisScopeAsync( ISymbol symbol, ImmutableArray <SymbolStartAnalyzerAction> symbolStartActions, AnalyzerExecutor analyzerExecutor) { lock (_gate) { _lazySymbolScopeTasks = _lazySymbolScopeTasks ?? new Dictionary <ISymbol, Task <HostSymbolStartAnalysisScope> >(); if (!_lazySymbolScopeTasks.TryGetValue(symbol, out var symbolScopeTask)) { symbolScopeTask = Task.Run(getSymbolAnalysisScopeCore, analyzerExecutor.CancellationToken); _lazySymbolScopeTasks.Add(symbol, symbolScopeTask); } return(symbolScopeTask); HostSymbolStartAnalysisScope getSymbolAnalysisScopeCore() { var symbolAnalysisScope = new HostSymbolStartAnalysisScope(); analyzerExecutor.ExecuteSymbolStartActions(symbol, _analyzer, symbolStartActions, symbolAnalysisScope); var symbolEndActions = symbolAnalysisScope.GetAnalyzerActions(_analyzer); if (symbolEndActions.SymbolEndActionsCount > 0) { var dependentSymbols = getDependentSymbols(); lock (_gate) { _lazyPendingMemberSymbolsMapOpt = _lazyPendingMemberSymbolsMapOpt ?? new Dictionary <ISymbol, HashSet <ISymbol> >(); _lazyPendingMemberSymbolsMapOpt.Add(symbol, dependentSymbols); } } return(symbolAnalysisScope); } } HashSet <ISymbol> getDependentSymbols() { HashSet <ISymbol> memberSet = null; switch (symbol.Kind) { case SymbolKind.NamedType: processMembers(((INamedTypeSymbol)symbol).GetMembers()); break; case SymbolKind.Namespace: processMembers(((INamespaceSymbol)symbol).GetMembers()); break; } return(memberSet); void processMembers(IEnumerable <ISymbol> members) { foreach (var member in members) { if (!member.IsImplicitlyDeclared) { memberSet = memberSet ?? new HashSet <ISymbol>(); memberSet.Add(member); } if (member.Kind != symbol.Kind && member is INamedTypeSymbol typeMember) { processMembers(typeMember.GetMembers()); } } } } }