Beispiel #1
0
        /// <summary>
        /// Searches the tree down. Returns the found symbol or null.
        /// Only takes definitions into account.
        /// If you would like all symbols, not only definitions, use <c>GetSymbolAtPosition</c>.
        /// </summary>
        public ISymbolInformation TopDown(ISymbolInformation rootEntry, Uri file, int line, int character)
        {
            if (rootEntry == null)
            {
                return(null);
            }

            ISymbolInformation bestMatch = null;

            if (SymbolUtil.PositionIsWithinSymbolTotalRange(rootEntry, file, line, character))
            {
                bestMatch = rootEntry;
            }

            foreach (var child in rootEntry.Children)
            {
                if (SymbolUtil.PositionIsWithinSymbolTotalRange(child, file, line, character))
                {
                    bestMatch = child;
                    if (child.HasChildren)
                    {
                        var match = TopDown(child, file, line, character);
                        bestMatch = match ?? bestMatch;
                    }
                }
                // in case no better match was found,
                // check default scope too
                if (
                    (bestMatch == null || bestMatch.Equals(rootEntry)) &&
                    (child.Name == Resources.SymbolTableStrings.default_class || child.Name == Resources.SymbolTableStrings.default_module) &&
                    (child.Children?.Any() ?? false)
                    )
                {
                    bestMatch = TopDown(child, file, line, character);
                }
            }
            return(bestMatch);
        }
Beispiel #2
0
        /// <summary>
        /// Searches the tree downwards to match a specific location.
        /// Only symbols that wrap the location are searched.
        /// <returns> Returns the match oder null.</returns>
        /// This will find all symbols, not only definitions.
        /// If you would like to search for definitions only, use <c>TopDown</c>
        /// </summary>
        public ISymbolInformation GetSymbolAtPosition(ISymbolInformation rootEntry, Uri file, int line, int character)
        {
            if (rootEntry == null || (!SymbolUtil.PositionIsWithinSymbolTotalRange(rootEntry, file, line, character) && (rootEntry.Name != Resources.SymbolTableStrings.default_module)))
            {
                return(null);
            }
            var wrappingSymbol = TopDown(rootEntry, file, line, character);

            if (wrappingSymbol?.Descendants != null)
            {
                foreach (var symbol in wrappingSymbol.Descendants)
                {
                    if (SymbolUtil.PositionIsWithinSymbolIdentifier(symbol, file, line, character))
                    {
                        return(symbol);
                    }
                }
            }
            if (line == wrappingSymbol?.Line && character <= wrappingSymbol.IdentifierEndColumn)
            {
                return(wrappingSymbol);
            }
            return(null);
        }