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); }
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(); } } }
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); }