private void GetSymbolsInContext()

in src/Kusto.Language/Binder/Binder.cs [710:843]


        private void GetSymbolsInContext(SyntaxNode contextNode, SymbolMatch match, IncludeFunctionKind include, List<Symbol> list)
        {
            if (_pathScope is GroupSymbol g
                && IsPassThrough(g))
            {
                var savePathScope = _pathScope;
                foreach (var s in g.Members)
                {
                    _pathScope = s;
                    GetSymbolsInContext(contextNode, match, include, list);
                }
                _pathScope = savePathScope;
            }
            else if (_pathScope != null)
            {
                // so far only columns, tables and functions can be dot accessed.
                var memberMatch = match & (SymbolMatch.Column | SymbolMatch.Table | SymbolMatch.Function);

                // table.column only works in commands
                if (_pathScope is TableSymbol && !IsInsideControlCommandProper(contextNode))
                {
                    memberMatch &= ~SymbolMatch.Column;
                }

                // any columns or tables from left-hand side?
                if ((memberMatch & SymbolMatch.Column) != 0)
                {
                    if (_pathScope is TableSymbol table && table.IsOpen)
                    {
                        list.AddRange(GetDeclaredAndInferredColumns(table));
                    }
                    else if (_pathScope is TupleSymbol tuple && tuple.RelatedTable != null && tuple.RelatedTable.IsOpen)
                    {
                        list.AddRange(GetDeclaredAndInferredColumns(tuple.RelatedTable));
                    }
                    else
                    {
                        GetPathMembers(_pathScope, memberMatch, list);
                    }
                }
                else if (memberMatch != 0)
                {
                    GetPathMembers(_pathScope, memberMatch, list);
                }

                // any special functions from left-hand side?
                if ((match & SymbolMatch.Function) != 0)
                {
                    GetSpecialFunctions(null, list);
                }
            }
            else
            {
                switch (_scopeKind)
                {
                    case ScopeKind.Normal:
                        // row scope columns
                        if (_rowScope != null && (match & SymbolMatch.Column) != 0)
                        {
                            if (_rightRowScope != null)
                            {
                                // add $left and $right variables
                                list.Add(new VariableSymbol("$left", GetTuple(_rowScope)));
                                list.Add(new VariableSymbol("$right", GetTuple(_rightRowScope)));

                                // common columns
                                GetCommonColumns(GetDeclaredAndInferredColumns(_rowScope), GetDeclaredAndInferredColumns(_rightRowScope), list);
                            }
                            else
                            {
                                _rowScope.GetMembers(match, list);
                            }
                        }

                        var localMatch = match;
                        if ((include & IncludeFunctionKind.LocalFunctions) == 0)
                            localMatch &= ~SymbolMatch.Function;

                        // local symbols
                        _localScope.GetSymbols(localMatch, list);

                        // get any built-in functions
                        if ((match & SymbolMatch.Function) != 0 && (include & IncludeFunctionKind.BuiltInFunctions) != 0)
                        {
                            GetFunctionsInScope(match, null, IncludeFunctionKind.BuiltInFunctions, list);
                        }

                        // metadata symbols (tables, etc)
                        if (_currentDatabase != null)
                        {
                            var dbMatch = match;

                            if ((include & IncludeFunctionKind.DatabaseFunctions) == 0)
                                dbMatch &= ~SymbolMatch.Function;

                            _currentDatabase.GetMembers(dbMatch, list);
                        }

                        if ((match & SymbolMatch.Database) != 0)
                        {
                            _currentCluster.GetMembers(match, list);
                        }

                        if ((match & SymbolMatch.Cluster) != 0)
                        {
                            list.AddRange(_globals.Clusters);
                        }
                        break;

                    // aggregate scopes only see aggregate functions
                    case ScopeKind.Aggregate:
                        if ((match & SymbolMatch.Function) != 0)
                        {
                            GetFunctionsInScope(match, null, include, list);
                        }
                        break;

                    // plug-in scopes only see plug-in functions
                    case ScopeKind.PlugIn:
                        if ((match & SymbolMatch.Function) != 0)
                        {
                            GetFunctionsInScope(match, null, include, list);
                        }
                        break;

                    case ScopeKind.Option:
                        if ((match & SymbolMatch.Option) != 0)
                        {
                            list.AddRange(_globals.Options);
                        }
                        break;
                }
            }
        }