public static IEnumerable <SymbolStat> Select(ControlFlowGraph cfg)
        {
            var visitor = new SymbolsSelector();

            visitor.VisitCFG(cfg);
            return((IEnumerable <SymbolStat>)visitor._result);
        }
        public void DiagnosticRunTest(string dir, string fname)
        {
            var path = Path.Combine(dir, fname);

            _output.WriteLine("Analysing {0} ...", path);

            var code        = File.ReadAllText(path);
            var syntaxTree  = PhpSyntaxTree.ParseCode(SourceText.From(code, Encoding.UTF8), PhpParseOptions.Default, PhpParseOptions.Default, path);
            var compilation = (PhpCompilation)EmptyCompilation.AddSyntaxTrees(syntaxTree);

            bool isCorrect = true;

            // Gather and check diagnostics
            var expectedDiags = DiagnosticAnnotationRegex.Matches(code);
            var actualDiags   = compilation.GetDiagnostics()
                                .OrderBy(diag => diag.Location.SourceSpan.Start)
                                .ToArray();

            isCorrect &= CheckDiagnostics(syntaxTree, actualDiags, expectedDiags);

            // Gather and check types if there are any annotations
            var expectedTypes = TypeAnnotationRegex.Matches(code);

            if (expectedTypes.Count > 0)
            {
                var symbolsInfo = compilation.UserDeclaredRoutines
                                  .Where(routine => routine.ControlFlowGraph != null)
                                  .Select(routine => SymbolsSelector.Select(routine.ControlFlowGraph))
                                  .Concat(compilation.UserDeclaredRoutines.Select(routine => SymbolsSelector.Select(routine))) // routine declarations
                                  .Concat(compilation.UserDeclaredTypes.Select(type => SymbolsSelector.Select(type)))          // type declarations
                                  .SelectMany(enumerators => enumerators);                                                     // IEnumerable<IEnumerable<T>> => IEnumerable<T>
                isCorrect &= CheckTypes(syntaxTree, symbolsInfo, expectedTypes);
            }

            // Gather and check routine properties if there are any annotations
            var expectedRoutineProps = RoutinePropertiesRegex.Matches(code);

            if (expectedRoutineProps.Count > 0)
            {
                isCorrect &= CheckRoutineProperties(syntaxTree, compilation.SourceSymbolCollection.AllRoutines, expectedRoutineProps);
            }

            Assert.True(isCorrect);
        }