private static void AddUsagesRanges(FSharpSymbol symbol, HashSet <DocumentRange> ranges,
                                            FSharpCheckFileResults checkResults, IDocument document, IFSharpFile fsFile)
        {
            var isActivePatternCase = symbol is FSharpActivePatternCase;
            var isGreaterOp         =
                symbol is FSharpMemberOrFunctionOrValue mfv && mfv.LogicalName == StandardOperatorNames.GreaterThan;

            var symbolUsages = checkResults?.GetUsesOfSymbolInFile(symbol).RunAsTask();

            if (symbolUsages == null)
            {
                return;
            }

            foreach (var symbolUse in symbolUsages)
            {
                var treeOffset = document.GetTreeEndOffset(symbolUse.RangeAlternate);
                var usageToken = fsFile.FindTokenAt(treeOffset - 1);
                if (usageToken == null)
                {
                    continue;
                }

                if (isActivePatternCase && symbolUse.IsFromDefinition)
                {
                    if (!(symbolUse.Symbol is FSharpActivePatternCase useSymbol))
                    {
                        continue;
                    }

                    if (useSymbol.DeclarationLocation.Equals(symbolUse.RangeAlternate))
                    {
                        var caseDeclaration = usageToken.GetContainingNode <IActivePatternId>()?.Cases[useSymbol.Index];
                        if (caseDeclaration != null)
                        {
                            ranges.Add(caseDeclaration.GetDocumentRange());
                            continue;
                        }
                    }
                }

                if (!(usageToken is FSharpIdentifierToken identToken))
                {
                    continue;
                }

                var tokenType = identToken.GetTokenType();

                if ((tokenType == FSharpTokenType.GREATER || tokenType == FSharpTokenType.GREATER_RBRACK) && !isGreaterOp)
                {
                    continue; // found usage of generic symbol with specified type parameter
                }
                ranges.Add(identToken.GetDocumentRange());
            }
        }
 public FSharpResolvedSymbolUse[] GetAllDeclaredSymbols(FSharpCheckFileResults checkResults = null,
                                                        Action interruptChecker = null)
 {
     lock (myGetSymbolsLock)
     {
         if (myDeclarationSymbols == null)
         {
             UpdateSymbols(checkResults);
         }
         return(myDeclarationSymbols?.Values.AsArray() ?? EmptyArray <FSharpResolvedSymbolUse> .Instance);
     }
 }
        private void UpdateSymbols(FSharpCheckFileResults checkResults = null, Action daemonInterruptChecker = null)
        {
            if (myDeclarationSymbols == null)
            {
                var interruptChecker = new SeldomInterruptCheckerWithCheckTime(100);
                checkResults = checkResults ?? GetParseAndCheckResults(false)?.Value.CheckResults;
                if (checkResults == null)
                {
                    return;
                }

                var document = GetSourceFile()?.Document;
                var buffer   = document?.Buffer;

                var symbolUses = checkResults.GetAllUsesOfAllSymbolsInFile().RunAsTask(daemonInterruptChecker);
                if (symbolUses == null || document == null)
                {
                    return;
                }

                // add separate APIs to FCS to get resoved symbols and bindings?
                myResolvedSymbols    = new Dictionary <int, FSharpResolvedSymbolUse>(symbolUses.Length);
                myDeclarationSymbols = new Dictionary <int, FSharpResolvedSymbolUse>(symbolUses.Length / 4);

                foreach (var symbolUse in symbolUses)
                {
                    var symbol = symbolUse.Symbol;
                    var range  = symbolUse.RangeAlternate;

                    var startOffset = document.GetOffset(range.Start);
                    var endOffset   = document.GetOffset(range.End);
                    var mfv         = symbol as FSharpMemberOrFunctionOrValue;

                    if (symbolUse.IsFromDefinition)
                    {
                        if (mfv != null)
                        {
                            // workaround for auto-properties, see visualfsharp#3939
                            var mfvLogicalName = mfv.LogicalName;
                            if (mfvLogicalName.EndsWith("@", StringComparison.Ordinal))
                            {
                                continue;
                            }

                            // visualfsharp#3939
                            if (mfvLogicalName.Equals("v", StringComparison.Ordinal) &&
                                myDeclarationSymbols.ContainsKey(startOffset))
                            {
                                continue;
                            }

                            // visualfsharp#3943, visualfsharp#3933
                            if (!mfvLogicalName.Equals(".ctor", StringComparison.Ordinal) &&
                                !(FindTokenAt(new TreeOffset(endOffset - 1)) is FSharpIdentifierToken))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            // workaround for compiler generated symbols (e.g. fields auto-properties)
                            if (!(FindTokenAt(new TreeOffset(endOffset - 1)) is FSharpIdentifierToken))
                            {
                                continue;
                            }
                        }

                        var textRange = new TextRange(startOffset, endOffset);
                        myDeclarationSymbols[startOffset] = new FSharpResolvedSymbolUse(symbolUse, textRange);
                        myResolvedSymbols.Remove(startOffset);
                    }
                    else
                    {
                        // workaround for indexer properties, visualfsharp#3933
                        if (startOffset == endOffset ||
                            mfv != null && mfv.IsProperty && buffer[endOffset - 1] == ']')
                        {
                            continue;
                        }

                        var nameRange = FixRange(new TextRange(startOffset, endOffset), buffer);

                        // workaround for implicit type usages (e.g. in members with optional params), visualfsharp#3933
                        if (symbol is FSharpEntity &&
                            !(FindTokenAt(new TreeOffset(nameRange.EndOffset - 1)) is FSharpIdentifierToken))
                        {
                            continue;
                        }

                        if (!myDeclarationSymbols.ContainsKey(startOffset))
                        {
                            myResolvedSymbols[nameRange.StartOffset] = new FSharpResolvedSymbolUse(symbolUse, nameRange);
                        }
                    }

                    interruptChecker.CheckForInterrupt();
                }
            }
        }