Пример #1
0
 protected FSharpDaemonStageProcessBase(IFSharpFile fsFile, IDaemonProcess daemonProcess)
 {
     FSharpFile             = fsFile;
     DaemonProcess          = daemonProcess;
     ResolveContext         = fsFile.GetResolveContext();
     SeldomInterruptChecker = new SeldomInterruptCheckerWithCheckTime(InterruptCheckTime);
 }
        public IEnumerable <CppFileLocation> GetCppFileLocations(SeldomInterruptCheckerWithCheckTime checker)
        {
            foreach (var module in myPsiModules.GetSourceModules())
            {
                if (module.ContainingProjectModule is IProject project && project.IsVCXMiscProjectInVs2015())
                {
                    continue;
                }

                foreach (var f in module.SourceFiles)
                {
                    checker?.CheckForInterrupt();

                    if (f.IsValid() && f.LanguageType.Is <ShaderLabProjectFileType>())
                    {
                        foreach (var cppFileLocation in InjectedHlslLocationHelper.GetCppFileLocations(f))
                        {
                            yield return(cppFileLocation.Location);
                        }
                    }
                }
            }
        }
 protected FSharpDaemonStageProcessBase(IDaemonProcess daemonProcess)
 {
     DaemonProcess          = daemonProcess;
     SeldomInterruptChecker = new SeldomInterruptCheckerWithCheckTime(InterruptCheckTime);
 }
Пример #4
0
        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();
                }
            }
        }
Пример #5
0
        private ResolvedSymbols CreateFileResolvedSymbols()
        {
            var interruptChecker = new SeldomInterruptCheckerWithCheckTime(100);

            // todo: cancellation
            if (!(SourceFile.GetPrimaryPsiFile() is IFSharpFile fsFile))
            {
                return(ResolvedSymbols.Empty);
            }

            var checkResults = CheckerService.ParseAndCheckFile(SourceFile, OpName)?.Value.CheckResults;
            var symbolUses   = checkResults?.GetAllUsesOfAllSymbolsInFile().RunAsTask();

            if (symbolUses == null)
            {
                return(ResolvedSymbols.Empty);
            }

            var document        = SourceFile.Document;
            var lexer           = fsFile.CachingLexer;
            var buffer          = document.Buffer;
            var resolvedSymbols = new ResolvedSymbols(symbolUses.Length);

            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;
                var activePatternCase = symbol as FSharpActivePatternCase;

                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 == "v" &&
                            resolvedSymbols.Declarations.ContainsKey(startOffset))
                        {
                            continue;
                        }

                        if (mfvLogicalName == StandardMemberNames.ClassConstructor)
                        {
                            continue;
                        }

                        // visualfsharp#3943, visualfsharp#3933
                        if (mfvLogicalName != StandardMemberNames.Constructor &&
                            !(lexer.FindTokenAt(endOffset - 1) && (lexer.TokenType?.IsIdentifier ?? false) || mfv.IsActivePattern))
                        {
                            continue;
                        }

                        if (mfvLogicalName == "Invoke" && (mfv.DeclaringEntity?.Value?.IsDelegate ?? false))
                        {
                            continue;
                        }

                        var len = endOffset - startOffset;
                        if (mfvLogicalName == "op_Multiply" && len == 3)
                        {
                            // The `*` pattern includes parens and is parsed as special token
                            // let (*) (_, _) = ()
                            startOffset++;
                            endOffset--;
                        }
                    }
                    else if (activePatternCase != null)
                    {
                        // Skip active pattern cases bindings as these have incorrect ranges.
                        // Active pattern cases uses inside bindings are currently marked as bindings so check the range.
                        // https://github.com/Microsoft/visualfsharp/issues/4423
                        if (Range.equals(activePatternCase.DeclarationLocation, range))
                        {
                            var activePatternId = fsFile.GetContainingNodeAt <ActivePatternId>(new TreeOffset(endOffset - 1));
                            if (activePatternId == null)
                            {
                                continue;
                            }

                            var cases     = activePatternId.Cases;
                            var caseIndex = activePatternCase.Index;
                            if (caseIndex < 0 || caseIndex >= cases.Count)
                            {
                                continue;
                            }

                            if (!(cases[caseIndex] is IActivePatternNamedCaseDeclaration caseDeclaration))
                            {
                                continue;
                            }

                            var(caseStart, caseEnd) = caseDeclaration.GetTreeTextRange();
                            var caseStartOffset = caseStart.Offset;
                            var caseTextRange   = new TextRange(caseStartOffset, caseEnd.Offset);
                            resolvedSymbols.Declarations[caseStartOffset] = new FSharpResolvedSymbolUse(symbolUse, caseTextRange);
                            continue;
                        }

                        var caseUseInBindingRange = new TextRange(startOffset, endOffset);
                        resolvedSymbols.Uses[startOffset] = new FSharpResolvedSymbolUse(symbolUse, caseUseInBindingRange);
                        continue;
                    }
                    else
                    {
                        // workaround for compiler generated symbols (e.g. fields auto-properties)
                        if (!(lexer.FindTokenAt(endOffset - 1) && (lexer.TokenType?.IsIdentifier ?? false)))
                        {
                            continue;
                        }
                    }

                    var textRange = mfv != null
            ? new TextRange(startOffset, endOffset)
            : FixRange(startOffset, endOffset, null, buffer, lexer);
                    startOffset = textRange.StartOffset;

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

                    var entity =
                        symbol as FSharpEntity ??
                        (mfv != null && mfv.IsConstructor ? mfv.DeclaringEntity?.Value : null);

                    // we need `foo` in
                    // inherit mod.foo<bar.baz>()
                    if (entity != null && !entity.GenericParameters.IsEmpty())
                    {
                        if (lexer.FindTokenAt(endOffset - 1) && lexer.TokenType == FSharpTokenType.GREATER)
                        {
                            if (new ParenMatcher().FindMatchingBracket(lexer) && lexer.TokenStart >= startOffset)
                            {
                                lexer.Advance(-1);
                                if (lexer.TokenType != null)
                                {
                                    startOffset = lexer.TokenStart;
                                    endOffset   = lexer.TokenEnd;
                                }
                            }
                        }
                    }

                    var nameRange = FixRange(startOffset, endOffset, mfv?.LogicalName, buffer, lexer);
                    startOffset = nameRange.StartOffset;

                    // workaround for implicit type usages (e.g. in members with optional params), visualfsharp#3933
                    if (CanIgnoreSymbol(symbol) &&
                        !(lexer.FindTokenAt(nameRange.EndOffset - 1) && (lexer.TokenType?.IsIdentifier ?? false)))
                    {
                        continue;
                    }

                    if (!resolvedSymbols.Declarations.ContainsKey(startOffset))
                    {
                        resolvedSymbols.Uses[startOffset] = new FSharpResolvedSymbolUse(symbolUse, nameRange);
                    }
                }

                interruptChecker.CheckForInterrupt();
            }

            return(resolvedSymbols);
        }