public static IList <IList <string> > Start(InspectorContext context, MemberDeclarationSyntax memberDeclarationSyntax,
                                                    params string[] typeIdentifiers)
        {
            var semanticModel = context.GetSemanticModelFor(memberDeclarationSyntax);
            var namedTypes    = typeIdentifiers.Select(t => GetTypeByMetadataName(semanticModel, t)).ToArray();

            var visitor = new CallSequenceVisitor2(context, namedTypes);

            visitor.StartInternal(memberDeclarationSyntax, new List <ISymbol>());
            return(visitor.GetResults());
        }
        public static async Task <IList <MemberDeclarationSyntax> > GetMembers(
            InspectorContext context, Document document,
            bool collectMethods = true, bool collectProperties = false)
        {
            var visitor = new MemberExtractorVisitor(collectMethods, collectProperties);
            var root    = await document.GetSyntaxRootAsync();

            visitor._semanticModel = context.GetSemanticModelFor(root);

            visitor.Visit(root);
            return(visitor._members);
        }
        private void Visit(MemberDeclarationSyntax memberDeclarationSyntax)
        {
            var semanticModel = _context.GetSemanticModelFor(memberDeclarationSyntax);
            var memberSymbol  = semanticModel.GetDeclaredSymbol(memberDeclarationSyntax);
            var memberType    = memberSymbol.ContainingType;
            var fullName      = $"{memberSymbol.ContainingNamespace}.{memberType.Name}.{memberSymbol.Name}";

            // avoid circular references
            if (_alreadyVisited.Contains(fullName))
            {
                return;
            }
            _alreadyVisited.Add(fullName);

            // find all callers
            var references = SymbolFinder.FindCallersAsync(memberSymbol, _context.Solution).Result;

            if (!references.Any())
            {
                // a top declaration was found
                // Warning: this demo does not take in account overloads
                _topDeclarations[fullName] = memberDeclarationSyntax;
                return;
            }

            // cycle the callers
            foreach (var referenced in references)
            {
                var caller = referenced.CallingSymbol;

                foreach (var definition in caller.DeclaringSyntaxReferences)
                {
                    var callerMemberDeclarationSyntax = (MemberDeclarationSyntax)definition.GetSyntax();

                    // recurse on the available declarations
                    Visit(callerMemberDeclarationSyntax);
                }
            }
        }