예제 #1
0
 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());
                            }
                        }
                    }
                }
            }
예제 #3
0
            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());
                            }
                        }
                    }
                }
            }