From 958a0beb8717779bd273d809dfec6b374057ecb5 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 5 Nov 2021 10:36:36 -0500 Subject: [PATCH 1/7] update path to use local proj info --- src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj | 2 ++ src/FsAutoComplete.Core/paket.references | 4 ---- src/FsAutoComplete/FsAutoComplete.fsproj | 2 ++ src/FsAutoComplete/paket.references | 2 -- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj index 469f825e6..c7f03498a 100644 --- a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj +++ b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj @@ -6,6 +6,8 @@ + + diff --git a/src/FsAutoComplete.Core/paket.references b/src/FsAutoComplete.Core/paket.references index 09835dfa4..6c4ec253f 100644 --- a/src/FsAutoComplete.Core/paket.references +++ b/src/FsAutoComplete.Core/paket.references @@ -1,7 +1,4 @@ FSharp.Compiler.Service -Ionide.ProjInfo -Ionide.ProjInfo.FCS -Ionide.ProjInfo.ProjectSystem FSharp.Analyzers.SDK Newtonsoft.Json #Fake.Runtime @@ -13,6 +10,5 @@ System.Configuration.ConfigurationManager FSharp.UMX FsToolkit.ErrorHandling Fantomas.Client - System.Reflection.Metadata Microsoft.Build.Utilities.Core diff --git a/src/FsAutoComplete/FsAutoComplete.fsproj b/src/FsAutoComplete/FsAutoComplete.fsproj index a215b870b..bb7d3a769 100644 --- a/src/FsAutoComplete/FsAutoComplete.fsproj +++ b/src/FsAutoComplete/FsAutoComplete.fsproj @@ -33,6 +33,8 @@ + + diff --git a/src/FsAutoComplete/paket.references b/src/FsAutoComplete/paket.references index fc078834f..04299f7a2 100644 --- a/src/FsAutoComplete/paket.references +++ b/src/FsAutoComplete/paket.references @@ -10,8 +10,6 @@ FSharp.UMX #FSharpLint.Core FsToolkit.ErrorHandling ICSharpCode.Decompiler -Ionide.ProjInfo -Ionide.ProjInfo.ProjectSystem Microsoft.Data.Sqlite Microsoft.NETFramework.ReferenceAssemblies Microsoft.SourceLink.GitHub From 00aec830ba2c686625f4ef8f1549430bd80760f9 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 5 Nov 2021 10:38:36 -0500 Subject: [PATCH 2/7] update patch --- utils/local-proj-info.patch | 40 ++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/utils/local-proj-info.patch b/utils/local-proj-info.patch index 32c487a32..61bc257da 100644 --- a/utils/local-proj-info.patch +++ b/utils/local-proj-info.patch @@ -1,3 +1,15 @@ +From 958a0beb8717779bd273d809dfec6b374057ecb5 Mon Sep 17 00:00:00 2001 +From: Chet Husk +Date: Fri, 5 Nov 2021 10:36:36 -0500 +Subject: [PATCH] update path to use local proj info + +--- + src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj | 2 ++ + src/FsAutoComplete.Core/paket.references | 4 ---- + src/FsAutoComplete/FsAutoComplete.fsproj | 2 ++ + src/FsAutoComplete/paket.references | 2 -- + 4 files changed, 4 insertions(+), 6 deletions(-) + diff --git a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj index 469f825..c7f0349 100644 --- a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj @@ -12,7 +24,7 @@ index 469f825..c7f0349 100644 diff --git a/src/FsAutoComplete.Core/paket.references b/src/FsAutoComplete.Core/paket.references -index 09835df..4c7756f 100644 +index 09835df..6c4ec25 100644 --- a/src/FsAutoComplete.Core/paket.references +++ b/src/FsAutoComplete.Core/paket.references @@ -1,7 +1,4 @@ @@ -23,6 +35,13 @@ index 09835df..4c7756f 100644 FSharp.Analyzers.SDK Newtonsoft.Json #Fake.Runtime +@@ -13,6 +10,5 @@ System.Configuration.ConfigurationManager + FSharp.UMX + FsToolkit.ErrorHandling + Fantomas.Client +- + System.Reflection.Metadata + Microsoft.Build.Utilities.Core diff --git a/src/FsAutoComplete/FsAutoComplete.fsproj b/src/FsAutoComplete/FsAutoComplete.fsproj index a215b87..bb7d3a7 100644 --- a/src/FsAutoComplete/FsAutoComplete.fsproj @@ -34,18 +53,21 @@ index a215b87..bb7d3a7 100644 + + - + diff --git a/src/FsAutoComplete/paket.references b/src/FsAutoComplete/paket.references -index d2088b9..5823f0e 100644 +index fc07883..04299f7 100644 --- a/src/FsAutoComplete/paket.references +++ b/src/FsAutoComplete/paket.references -@@ -4,8 +4,6 @@ Newtonsoft.Json - FSharp.Core - Microsoft.SourceLink.GitHub - System.Configuration.ConfigurationManager +@@ -10,8 +10,6 @@ FSharp.UMX + #FSharpLint.Core + FsToolkit.ErrorHandling + ICSharpCode.Decompiler -Ionide.ProjInfo -Ionide.ProjInfo.ProjectSystem - #Fake.Runtime - Dapper Microsoft.Data.Sqlite + Microsoft.NETFramework.ReferenceAssemblies + Microsoft.SourceLink.GitHub +-- +2.33.1.windows.1 + From 5da466ace3ec12bb4cebbe3a5f56e85cfc8ffc71 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 5 Nov 2021 10:46:58 -0500 Subject: [PATCH 3/7] bump packages --- paket.dependencies | 12 ++++---- paket.lock | 73 ++++++++++++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/paket.dependencies b/paket.dependencies index ff21e4ae7..dd3468a8f 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -11,8 +11,8 @@ storage: none github TheAngryByrd/FsLibLog:f81cba440bf0476bb4e2262b57a067a0d6ab78a7 src/FsLibLog/FsLibLog.fs nuget Argu ~> 5.2.0 -nuget Fantomas.Client 0.3.1 -nuget FSharp.Compiler.Service ~> 39 +nuget Fantomas.Client +nuget FSharp.Compiler.Service ~> 41 nuget Ionide.ProjInfo 0.54.2 nuget Ionide.ProjInfo.FCS 0.54.2 nuget Ionide.ProjInfo.ProjectSystem 0.54.2 @@ -27,7 +27,7 @@ nuget Mono.Cecil >= 0.10.0-beta7 nuget Newtonsoft.Json # nuget Fake.Runtime prerelease nuget FSharpLint.Core -nuget FSharp.Core < 6.0.0 +nuget FSharp.Core nuget Dapper nuget Microsoft.Data.Sqlite 2.2.4 nuget Microsoft.Data.Sqlite.Core 2.2.4 @@ -38,15 +38,15 @@ nuget Serilog nuget Serilog.Sinks.File nuget Serilog.Sinks.Console nuget Serilog.Sinks.Async -nuget Destructurama.FSharp 1.1.1-dev-00035 # prerelease is stable, just has different FSharp.Core version constraints +nuget Destructurama.FSharp nuget FSharp.UMX nuget FSharp.Formatting nuget FsToolkit.ErrorHandling nuget FSharpx.Async nuget CliWrap -nuget Microsoft.NET.Test.Sdk ~> 16.8.0 -nuget Microsoft.SourceLink.GitHub copy_local:true +nuget Microsoft.NET.Test.Sdk +nuget Dotnet.ReproducibleBuilds copy_local:true nuget Microsoft.NETFramework.ReferenceAssemblies 1.0.0 nuget Expecto nuget YoloDev.Expecto.TestSdk diff --git a/paket.lock b/paket.lock index 9a584e168..556217df1 100644 --- a/paket.lock +++ b/paket.lock @@ -10,11 +10,16 @@ NUGET Microsoft.Bcl.AsyncInterfaces (>= 5.0) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netstandard2.1)) (== netstandard2.0) System.Buffers (>= 4.5.1) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netstandard2.1)) (== netstandard2.0) System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netstandard2.1)) (== netstandard2.0) - Dapper (2.0.90) + Dapper (2.0.123) System.Reflection.Emit.Lightweight (>= 4.7) - restriction: == netstandard2.0 - Destructurama.FSharp (1.1.1-dev-00035) + Destructurama.FSharp (1.2) FSharp.Core (>= 4.3.4) Serilog (>= 2.0 < 3.0) + DotNet.ReproducibleBuilds (0.1.66) - copy_local: true + Microsoft.SourceLink.AzureRepos.Git (>= 1.0) + Microsoft.SourceLink.Bitbucket.Git (>= 1.0) + Microsoft.SourceLink.GitHub (>= 1.0) + Microsoft.SourceLink.GitLab (>= 1.0) Expecto (9.0.4) FSharp.Core (>= 4.6) Mono.Cecil (>= 0.11.3) @@ -23,15 +28,15 @@ NUGET StreamJsonRpc (>= 2.8.28) FParsec (1.1.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) FSharp.Core (>= 4.3.4) - FSharp.Analyzers.SDK (0.9) - FSharp.Compiler.Service (>= 39.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - FSharp.Core (>= 5.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - McMaster.NETCore.Plugins (>= 1.3.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - FSharp.Compiler.Service (39.0) - FSharp.Core (5.0.1) - Microsoft.Build.Framework (>= 16.6) - Microsoft.Build.Tasks.Core (>= 16.6) - Microsoft.Build.Utilities.Core (>= 16.6) + FSharp.Analyzers.SDK (0.10.1) + FSharp.Compiler.Service (>= 40.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + FSharp.Core (>= 5.0.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + McMaster.NETCore.Plugins (>= 1.4) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + FSharp.Compiler.Service (41.0.1) + FSharp.Core (6.0.1) + Microsoft.Build.Framework (>= 16.11) + Microsoft.Build.Tasks.Core (>= 16.11) + Microsoft.Build.Utilities.Core (>= 16.11) System.Buffers (>= 4.5.1) System.Collections.Immutable (>= 5.0) System.Diagnostics.Process (>= 4.3) @@ -40,11 +45,12 @@ NUGET System.Linq.Queryable (>= 4.3) System.Memory (>= 4.5.4) System.Net.Requests (>= 4.3) - System.Net.Security (>= 4.3) + System.Net.Security (>= 4.3.1) System.Reflection.Emit (>= 4.3) System.Reflection.Metadata (>= 5.0) System.Reflection.TypeExtensions (>= 4.3) System.Runtime (>= 4.3) + System.Runtime.CompilerServices.Unsafe (>= 5.0) System.Runtime.InteropServices (>= 4.3) System.Runtime.Loader (>= 4.3) System.Security.Claims (>= 4.3) @@ -59,18 +65,18 @@ NUGET FSharp.Control.Reactive (5.0.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) FSharp.Core (>= 4.7.2) System.Reactive (>= 5.0) - FSharp.Core (5.0.1) - FSharp.Formatting (11.2) - FSharp.Compiler.Service (>= 39.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netstandard2.1)) + FSharp.Core (6.0.1) + FSharp.Formatting (11.5.1) + FSharp.Compiler.Service (>= 40.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netstandard2.1)) FSharp.UMX (1.1) FSharp.Core (>= 4.3.4) - FSharpLint.Core (0.19) + FSharpLint.Core (0.20.2) FParsec (>= 1.1.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - FSharp.Compiler.Service (>= 39.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - FSharp.Core (>= 5.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo (>= 0.52) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo.FCS (>= 0.48) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo.ProjectSystem (>= 0.48) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + FSharp.Compiler.Service (>= 40.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + FSharp.Core (>= 5.0.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo (>= 0.53.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo.FCS (>= 0.53.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo.ProjectSystem (>= 0.53.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) Microsoft.Build (>= 16.10) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) Microsoft.Build.Framework (>= 16.10) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) Microsoft.Build.Locator (>= 1.4.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) @@ -157,7 +163,7 @@ NUGET System.Configuration.ConfigurationManager (>= 4.7) System.Security.Permissions (>= 4.7) System.Text.Encoding.CodePages (>= 4.0.1) - Microsoft.CodeCoverage (17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net45)) (&& (== netstandard2.0) (>= netcoreapp2.1)) + Microsoft.CodeCoverage (17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net45)) (&& (== netstandard2.0) (>= netcoreapp1.0)) Microsoft.Data.Sqlite (2.2.4) Microsoft.Data.Sqlite.Core (>= 2.2.4) SQLitePCLRaw.bundle_green (>= 1.1.12) @@ -168,20 +174,29 @@ NUGET Microsoft.NET.StringTools (1.0) - copy_local: false System.Memory (>= 4.5.4) System.Runtime.CompilerServices.Unsafe (>= 5.0) - Microsoft.NET.Test.Sdk (16.8.3) - Microsoft.CodeCoverage (>= 16.8.3) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net45)) (&& (== netstandard2.0) (>= netcoreapp2.1)) - Microsoft.TestPlatform.TestHost (>= 16.8.3) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp2.1)) + Microsoft.NET.Test.Sdk (17.0) + Microsoft.CodeCoverage (>= 17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net45)) (&& (== netstandard2.0) (>= netcoreapp1.0)) + Microsoft.TestPlatform.TestHost (>= 17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp1.0)) Microsoft.NETCore.Platforms (5.0.4) - copy_local: false Microsoft.NETCore.Targets (5.0) Microsoft.NETFramework.ReferenceAssemblies (1.0) + Microsoft.SourceLink.AzureRepos.Git (1.0) - copy_local: true + Microsoft.Build.Tasks.Git (>= 1.0) + Microsoft.SourceLink.Common (>= 1.0) + Microsoft.SourceLink.Bitbucket.Git (1.0) - copy_local: true + Microsoft.Build.Tasks.Git (>= 1.0) + Microsoft.SourceLink.Common (>= 1.0) Microsoft.SourceLink.Common (1.0) - copy_local: true Microsoft.SourceLink.GitHub (1.0) - copy_local: true Microsoft.Build.Tasks.Git (>= 1.0) Microsoft.SourceLink.Common (>= 1.0) + Microsoft.SourceLink.GitLab (1.0) - copy_local: true + Microsoft.Build.Tasks.Git (>= 1.0) + Microsoft.SourceLink.Common (>= 1.0) Microsoft.TestPlatform.ObjectModel (17.0) NuGet.Frameworks (>= 5.0) System.Reflection.Metadata (>= 1.6) - Microsoft.TestPlatform.TestHost (17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp2.1)) + Microsoft.TestPlatform.TestHost (17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp1.0)) Microsoft.TestPlatform.ObjectModel (>= 17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp1.0)) (&& (== netstandard2.0) (>= uap10.0)) Newtonsoft.Json (>= 9.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp1.0)) (&& (== netstandard2.0) (>= uap10.0)) Microsoft.VisualStudio.Threading (17.0.63) @@ -202,7 +217,7 @@ NUGET Microsoft.Win32.SystemEvents (5.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp3.0)) Microsoft.NETCore.Platforms (>= 5.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp2.0)) Mono.Cecil (0.11.4) - Nerdbank.Streams (2.8.46) + Nerdbank.Streams (2.8.50) Microsoft.Bcl.AsyncInterfaces (>= 5.0) Microsoft.VisualStudio.Threading (>= 16.10.56) Microsoft.VisualStudio.Validation (>= 16.10.26) @@ -565,7 +580,7 @@ NUGET System.Runtime (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime.CompilerServices.Unsafe (5.0) - copy_local: false + System.Runtime.CompilerServices.Unsafe (5.0) System.Runtime.Extensions (4.3.1) Microsoft.NETCore.Platforms (>= 1.1.1) Microsoft.NETCore.Targets (>= 1.1.3) @@ -871,7 +886,7 @@ NUGET FSharp.Control.Reactive (5.0.2) FSharp.Core (>= 4.7.2) System.Reactive (>= 5.0) - FSharp.Core (6.0) + FSharp.Core (6.0.1) Microsoft.Build (16.11) Microsoft.Build.Framework (16.11) System.Security.Permissions (>= 4.7) From f58b8d3b7323d1ff18f147ee86aa33d6c836e278 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 5 Nov 2021 16:25:17 -0500 Subject: [PATCH 4/7] api breaking changes --- .../Program.fs | 19 +- .../AbstractClassStubGenerator.fs | 37 +- src/FsAutoComplete.Core/BackgroundServices.fs | 2 +- src/FsAutoComplete.Core/CodeGeneration.fs | 49 +-- src/FsAutoComplete.Core/Commands.fs | 292 +++++++------ .../CompilerServiceInterface.fs | 60 +-- src/FsAutoComplete.Core/Decompiler.fs | 63 +-- .../DocumentationFormatter.fs | 43 +- src/FsAutoComplete.Core/FCSPatches.fs | 333 +++++++-------- src/FsAutoComplete.Core/FileSystem.fs | 57 +-- .../InterfaceStubGenerator.fs | 34 +- src/FsAutoComplete.Core/KeywordList.fs | 10 +- src/FsAutoComplete.Core/Lexer.fs | 2 +- .../ParseAndCheckResults.fs | 360 ++++++++-------- .../RecordStubGenerator.fs | 54 ++- src/FsAutoComplete.Core/SignatureFormatter.fs | 35 +- src/FsAutoComplete.Core/SignatureHelp.fs | 45 +- src/FsAutoComplete.Core/State.fs | 17 +- src/FsAutoComplete.Core/SymbolCache.fs | 14 +- src/FsAutoComplete.Core/TipFormatter.fs | 104 +++-- src/FsAutoComplete.Core/TypedAstPatterns.fs | 3 +- src/FsAutoComplete.Core/TypedAstUtils.fs | 4 +- .../UnionPatternMatchCaseGenerator.fs | 85 ++-- src/FsAutoComplete.Core/UntypedAstUtils.fs | 398 +++++++++--------- .../UnusedDeclarationsAnalyzer.fs | 5 +- src/FsAutoComplete.Core/Utils.fs | 2 +- src/FsAutoComplete/CodeFixes.fs | 8 +- .../CodeFixes/AddExplicitTypeToParameter.fs | 14 +- .../CodeFixes/AddMissingFunKeyword.fs | 2 +- .../CodeFixes/AddMissingRecKeyword.fs | 4 +- .../CodeFixes/AddTypeToIndeterminateValue.fs | 5 +- .../ChangeComparisonToMutableAssignment.fs | 4 +- .../CodeFixes/ChangeTypeOfNameToNameOf.fs | 41 +- .../CodeFixes/RemoveUnusedBinding.fs | 89 ++-- .../CodeFixes/ResolveNamespace.fs | 12 +- src/FsAutoComplete/CommandResponse.fs | 37 +- src/FsAutoComplete/FsAutoComplete.Lsp.fs | 40 +- src/FsAutoComplete/JsonSerializer.fs | 2 +- src/FsAutoComplete/LspHelpers.fs | 33 +- src/FsAutoComplete/Program.fs | 3 +- test/FsAutoComplete.Tests.Lsp/Helpers.fs | 4 +- test/FsAutoComplete.Tests.Lsp/Program.fs | 2 +- test/OptionAnalyzer/Analyzer.fs | 88 ++-- 43 files changed, 1255 insertions(+), 1260 deletions(-) diff --git a/src/FsAutoComplete.BackgroundServices/Program.fs b/src/FsAutoComplete.BackgroundServices/Program.fs index 61a49e142..cd5f425f2 100644 --- a/src/FsAutoComplete.BackgroundServices/Program.fs +++ b/src/FsAutoComplete.BackgroundServices/Program.fs @@ -7,8 +7,9 @@ open LanguageServerProtocol.Server open LanguageServerProtocol.Types open LanguageServerProtocol open FSharp.Compiler +open FSharp.Compiler.Diagnostics open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open System.Collections.Concurrent open FsAutoComplete open Ionide.ProjInfo.ProjectSystem @@ -66,8 +67,8 @@ module Helpers = { Range = { - Start = { Line = error.StartLineAlternate - 1; Character = error.StartColumn } - End = { Line = error.EndLineAlternate - 1; Character = error.EndColumn } + Start = { Line = error.StartLine - 1; Character = error.StartColumn } + End = { Line = error.StartLine - 1; Character = error.EndColumn } } Severity = fcsSeverityToDiagnostic error.Severity Source = "F# Compiler" @@ -120,7 +121,6 @@ type BackgroundServiceServer(state: State, client: FsacClient) = let checker = FSharpChecker.Create(projectCacheSize = 1, keepAllBackgroundResolutions = false, suggestNamesForErrors = false) - do checker.ImplicitlyStartBackgroundWork <- false let mutable latestSdkVersion = lazy None let mutable latestRuntimeVersion = lazy None //TODO: does the backgroundservice ever get config updates? @@ -224,7 +224,7 @@ type BackgroundServiceServer(state: State, client: FsacClient) = match ignoredFile with | Some fn when fn = file -> return () | _ -> - let errors = Array.append pr.Errors res.Errors |> Array.map (Helpers.fcsErrorToDiagnostic) + let errors = Array.append pr.Diagnostics res.Diagnostics |> Array.map (Helpers.fcsErrorToDiagnostic) let msg = {Diagnostics = errors; Uri = Helpers.filePathToUri file} do! client.SendDiagnostics msg return () @@ -242,7 +242,7 @@ type BackgroundServiceServer(state: State, client: FsacClient) = match ignoredFile with | Some fn when fn = file -> return () | _ -> - let errors = Array.append pr.Errors res.Errors |> Array.map (Helpers.fcsErrorToDiagnostic) + let errors = Array.append pr.Diagnostics res.Diagnostics |> Array.map (Helpers.fcsErrorToDiagnostic) let msg = {Diagnostics = errors; Uri = Helpers.filePathToUri file} do! client.SendDiagnostics msg return () @@ -261,8 +261,8 @@ type BackgroundServiceServer(state: State, client: FsacClient) = |> Seq.distinctBy (fun o -> o.ProjectFileName) |> Seq.filter (fun o -> o.ReferencedProjects - |> Array.map (fun (_,v) -> Path.GetFullPath v.ProjectFileName) - |> Array.contains s.ProjectFileName ) + |> Array.map (fun p -> Path.GetFullPath p.FileName) + |> Array.contains s.ProjectFileName) |> Seq.toList let reactor = MailboxProcessor.Start(fun agent -> @@ -412,6 +412,7 @@ module Program = LanguageServerProtocol.Server.start requestsHandlings input output FsacClient (fun lspClient -> new BackgroundServiceServer(state, lspClient)) + open FSharp.Compiler.IO [] @@ -419,7 +420,7 @@ module Program = let pid = Int32.Parse argv.[0] let originalFs = FileSystemAutoOpens.FileSystem - let fs = FileSystem(originalFs, state.Files.TryFind) :> IFileSystem + let fs = FsAutoComplete.FileSystem(originalFs, state.Files.TryFind) :> IFileSystem FileSystemAutoOpens.FileSystem <- fs ProcessWatcher.zombieCheckWithHostPID (fun () -> exit 0) pid SymbolCache.initCache (Environment.CurrentDirectory) diff --git a/src/FsAutoComplete.Core/AbstractClassStubGenerator.fs b/src/FsAutoComplete.Core/AbstractClassStubGenerator.fs index b2e6a7c40..499b939b9 100644 --- a/src/FsAutoComplete.Core/AbstractClassStubGenerator.fs +++ b/src/FsAutoComplete.Core/AbstractClassStubGenerator.fs @@ -2,12 +2,13 @@ module FsAutoComplete.AbstractClassStubGenerator open FsAutoComplete.CodeGenerationUtils open FSharp.Compiler.Text -open FSharp.Compiler.SyntaxTree -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.Symbols +open FSharp.Compiler.Tokenization type AbstractClassData = | ObjExpr of baseTy: SynType * bindings: SynBinding list * overallRange: Range - | ExplicitImpl of baseTy: SynType * members: SynMemberDefn list * safeInsertPosition: Pos + | ExplicitImpl of baseTy: SynType * members: SynMemberDefn list * safeInsertPosition: Position member x.AbstractTypeIdentRange = match x with | ObjExpr (baseTy, _, _) @@ -18,12 +19,12 @@ type AbstractClassData = | ExplicitImpl(t, _, _) -> expandTypeParameters t /// checks to see if a type definition inherits an abstract class, and if so collects the members defined at that -let private walkTypeDefn (SynTypeDefn.TypeDefn(info, repr, members, range)) = +let private walkTypeDefn (SynTypeDefn(info, repr, members, implicitCtor, range)) = let reprMembers = match repr with | SynTypeDefnRepr.ObjectModel (_, members, _) -> members | _ -> [] - let allMembers = reprMembers @ members + let allMembers = reprMembers @ (Option.toList implicitCtor) @ members let inheritMember = allMembers |> List.tryPick (function SynMemberDefn.ImplicitInherit(inheritType, inheritArgs, alias, range) -> Some (inheritType) | _ -> None) @@ -34,28 +35,28 @@ let private walkTypeDefn (SynTypeDefn.TypeDefn(info, repr, members, range)) = // filter out implicit/explicit constructors and inherit statements, as all members _must_ come after these function | SynMemberDefn.ImplicitCtor _ | SynMemberDefn.ImplicitInherit _ -> false - | SynMemberDefn.Member (SynBinding.Binding(valData = SynValData(Some({ MemberKind = MemberKind.Constructor } ), _, _)) , _) -> false + | SynMemberDefn.Member (SynBinding(valData = SynValData(Some({ MemberKind = SynMemberKind.Constructor } ), _, _)) , _) -> false | _ -> true) match inheritMember with | Some inheritMember -> let safeInsertPosition = match otherMembers with - | [] -> Pos.mkPos (inheritMember.Range.End.Line + 1) (inheritMember.Range.Start.Column + 2) - | x :: _ -> Pos.mkPos (x.Range.End.Line - 1) (x.Range.Start.Column + 2) + | [] -> Position.mkPos (inheritMember.Range.End.Line + 1) (inheritMember.Range.Start.Column + 2) + | x :: _ -> Position.mkPos (x.Range.End.Line - 1) (x.Range.Start.Column + 2) Some(AbstractClassData.ExplicitImpl(inheritMember, otherMembers, safeInsertPosition)) | _ -> None /// find the declaration of the abstract class being filled in at the given position -let private tryFindAbstractClassExprInParsedInput (pos: Pos) (parsedInput: ParsedInput) : AbstractClassData option = - AstTraversal.Traverse(pos, parsedInput, - { new AstTraversal.AstVisitorBase<_>() with +let private tryFindAbstractClassExprInParsedInput (pos: Position) (parsedInput: ParsedInput) : AbstractClassData option = + SyntaxTraversal.Traverse(pos, parsedInput, + { new SyntaxVisitorBase<_>() with member _.VisitExpr (path, traverseExpr, defaultTraverse, expr) = match expr with | SynExpr.ObjExpr (baseTy, constructorArgs, bindings, extraImpls, newExprRange, range) -> Some (AbstractClassData.ObjExpr(baseTy, bindings, range)) | _ -> defaultTraverse expr - override _.VisitModuleDecl (defaultTraverse, decl) = + override _.VisitModuleDecl (_, defaultTraverse, decl) = match decl with | SynModuleDecl.Types(types, m) -> List.tryPick walkTypeDefn types @@ -64,12 +65,10 @@ let private tryFindAbstractClassExprInParsedInput (pos: Pos) (parsedInput: Parse /// Walk the parse tree for the given document and look for the definition of any abstract classes in use at the given pos. /// This looks for implementations of abstract types in object expressions, as well as inheriting of abstract types inside class type declarations. -let tryFindAbstractClassExprInBufferAtPos (codeGenService: CodeGenerationService) (pos: Pos) (document : Document) = +let tryFindAbstractClassExprInBufferAtPos (codeGenService: CodeGenerationService) (pos: Position) (document : Document) = asyncMaybe { let! parseResults = codeGenService.ParseFileInProject(document.FullName) - return! - parseResults.ParseTree - |> Option.bind (tryFindAbstractClassExprInParsedInput pos) + return! tryFindAbstractClassExprInParsedInput pos parseResults.ParseTree } let getAbstractClassIdentifier (abstractClassData: AbstractClassData) tokens = @@ -96,7 +95,7 @@ let getMemberNameAndRanges (abstractClassData) = | AbstractClassData.ObjExpr (_, bindings, _) -> List.choose (|MemberNameAndRange|_|) bindings /// Try to find the start column, so we know what the base indentation should be -let inferStartColumn (codeGenServer : CodeGenerationService) (pos : Pos) (doc : Document) (lines: ISourceText) (lineStr : string) (abstractClassData : AbstractClassData) (indentSize : int) = +let inferStartColumn (codeGenServer : CodeGenerationService) (pos : Position) (doc : Document) (lines: ISourceText) (lineStr : string) (abstractClassData : AbstractClassData) (indentSize : int) = match getMemberNameAndRanges abstractClassData with | (_, range) :: _ -> getLineIdent (lines.GetLineString(range.StartLine - 1)) @@ -124,7 +123,7 @@ let inferStartColumn (codeGenServer : CodeGenerationService) (pos : Pos) (doc : /// nothing is written. Otherwise, a list of missing members is generated and written let writeAbstractClassStub (codeGenServer : CodeGenerationService) (checkResultForFile: ParseAndCheckResults) (doc : Document) (lines: ISourceText) (lineStr : string) (abstractClassData : AbstractClassData) = asyncMaybe { - let pos = Pos.mkPos abstractClassData.AbstractTypeIdentRange.Start.Line (abstractClassData.AbstractTypeIdentRange.End.Column) + let pos = Position.mkPos abstractClassData.AbstractTypeIdentRange.Start.Line (abstractClassData.AbstractTypeIdentRange.End.Column) let! (_lexerSym, usages) = codeGenServer.GetSymbolAndUseAtPositionOfKind(doc.FullName, pos, SymbolKind.Ident) let! usage = usages let! (displayContext, entity) = @@ -143,7 +142,7 @@ let writeAbstractClassStub (codeGenServer : CodeGenerationService) (checkResultF let getMemberByLocation (name, range: Range) = asyncMaybe { - let pos = Pos.fromZ (range.StartLine - 1) (range.StartColumn + 1) + let pos = Position.fromZ (range.StartLine - 1) (range.StartColumn + 1) return! checkResultForFile.GetCheckResults.GetSymbolUseAtLocation (pos.Line, pos.Column, lineStr, []) } diff --git a/src/FsAutoComplete.Core/BackgroundServices.fs b/src/FsAutoComplete.Core/BackgroundServices.fs index 717cd12de..21930b739 100644 --- a/src/FsAutoComplete.Core/BackgroundServices.fs +++ b/src/FsAutoComplete.Core/BackgroundServices.fs @@ -3,7 +3,7 @@ module BackgroundServices open FsAutoComplete open LanguageServerProtocol open System.IO -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open Ionide.ProjInfo.ProjectSystem open FsAutoComplete.Logging diff --git a/src/FsAutoComplete.Core/CodeGeneration.fs b/src/FsAutoComplete.Core/CodeGeneration.fs index 061e447a7..e6eec9215 100644 --- a/src/FsAutoComplete.Core/CodeGeneration.fs +++ b/src/FsAutoComplete.Core/CodeGeneration.fs @@ -4,9 +4,11 @@ namespace FsAutoComplete open System open System.IO open System.CodeDom.Compiler -open FSharp.Compiler.SyntaxTree +open FSharp.Compiler.Syntax open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Tokenization +open FSharp.Compiler.CodeAnalysis [] type Line0 [] type Line1 @@ -22,7 +24,7 @@ type CodeGenerationService(checker : FSharpCompilerServiceChecker, state : State with | _ -> None - member x.GetSymbolAtPosition(fileName, pos: Pos) = + member x.GetSymbolAtPosition(fileName, pos: Position) = match state.TryGetFileCheckerOptionsWithLinesAndLineStr(fileName, pos) with | ResultOrString.Error _ -> None | ResultOrString.Ok (opts, lines, line) -> @@ -31,7 +33,7 @@ type CodeGenerationService(checker : FSharpCompilerServiceChecker, state : State with | _ -> None - member x.GetSymbolAndUseAtPositionOfKind(fileName, pos: Pos, kind) = + member x.GetSymbolAndUseAtPositionOfKind(fileName, pos: Position, kind) = asyncMaybe { let! symbol = x.GetSymbolAtPosition(fileName,pos) if symbol.Kind = kind then @@ -55,7 +57,7 @@ type CodeGenerationService(checker : FSharpCompilerServiceChecker, state : State | _ -> None module CodeGenerationUtils = - open FSharp.Compiler.SourceCodeServices.PrettyNaming + open FSharp.Compiler.Syntax.PrettyNaming type ColumnIndentedTextWriter() = let stringWriter = new StringWriter() @@ -91,13 +93,6 @@ module CodeGenerationUtils = stringWriter.Dispose() indentWriter.Dispose() - let (|IndexerArg|) = function - | SynIndexerArg.Two(e1,e1FromEnd, e2, e2FromEnd, _e1Range, _e2Range) -> [e1, e1FromEnd; e2, e2FromEnd] - | SynIndexerArg.One(e, fromEnd, _range) -> [e, fromEnd] - - let (|IndexerArgList|) xs = - List.collect (|IndexerArg|) xs - let hasAttribute<'T> (attrs: seq) = attrs |> Seq.exists (fun a -> a.AttributeType.CompiledName = typeof<'T>.Name) @@ -114,7 +109,7 @@ module CodeGenerationUtils = if range.EndLine > document.LineCount then let newEndLine = document.LineCount let newEndColumn = document.GetLineText1(document.LineCount).Length - let newEndPos = Pos.mkPos newEndLine newEndColumn + let newEndPos = Position.mkPos newEndLine newEndColumn Range.mkRange range.FileName range.Start newEndPos else @@ -144,7 +139,7 @@ module CodeGenerationUtils = predicate tokenInfo ) |> Option.map (fun (line1, tokenInfo) -> - tokenInfo, (Pos.fromZ (int line1 - 1) tokenInfo.LeftColumn) + tokenInfo, (Position.fromZ (int line1 - 1) tokenInfo.LeftColumn) ) /// Represent environment where a captured identifier should be renamed @@ -550,14 +545,14 @@ module CodeGenerationUtils = // On merged properties (consisting both getters and setters), they have the same range values, // so we use 'get_' and 'set_' prefix to ensure corresponding symbols are retrieved correctly. let (|MemberNameAndRange|_|) = function - | Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, SynValData(Some mf, _, _), LongIdentPattern(name, range), - _retTy, _expr, _bindingRange, _seqPoint) when mf.MemberKind = MemberKind.PropertyGet -> + | SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, SynValData(Some mf, _, _), LongIdentPattern(name, range), + _retTy, _expr, _bindingRange, _seqPoint) when mf.MemberKind = SynMemberKind.PropertyGet -> if name.StartsWith("get_") then Some(name, range) else Some("get_" + name, range) - | Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, SynValData(Some mf, _, _), LongIdentPattern(name, range), - _retTy, _expr, _bindingRange, _seqPoint) when mf.MemberKind = MemberKind.PropertySet -> + | SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, SynValData(Some mf, _, _), LongIdentPattern(name, range), + _retTy, _expr, _bindingRange, _seqPoint) when mf.MemberKind = SynMemberKind.PropertySet -> if name.StartsWith("set_") then Some(name, range) else Some("set_" + name, range) - | Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, LongIdentPattern(name, range), - _retTy, _expr, _bindingRange, _seqPoint) -> + | SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, LongIdentPattern(name, range), + _retTy, _expr, _bindingRange, _seqPoint) -> Some(name, range) | _ -> None @@ -618,12 +613,12 @@ module CodeGenerationUtils = res <- res + powerNumber res - let findLastPositionOfWithKeyword (tokens: FSharpTokenInfo list) (entity: FSharpEntity) (pos: Pos) (entityAdvancer) = + let findLastPositionOfWithKeyword (tokens: FSharpTokenInfo list) (entity: FSharpEntity) (pos: Position) (entityAdvancer) = let endPosOfWidth = tokens |> List.tryPick (fun (t: FSharpTokenInfo) -> if t.CharClass = FSharpTokenCharKind.Keyword && t.LeftColumn >= pos.Column && t.TokenName = "WITH" then - Some (Pos.fromZ (pos.Line - 1) (t.RightColumn + 1)) + Some (Position.fromZ (pos.Line - 1) (t.RightColumn + 1)) else None) match endPosOfWidth with @@ -634,11 +629,11 @@ module CodeGenerationUtils = let position = if entity.GenericParameters.Count = 0 then let token = entityAdvancer tokens - Pos.fromZ (pos.Line - 1) (token.RightColumn + 1) + Position.fromZ (pos.Line - 1) (token.RightColumn + 1) // Otherwise, returns the position after the last greater angle (>) else let token = findLastGreaterOperator tokens - Pos.fromZ (pos.Line - 1) (token.RightColumn + 1) + Position.fromZ (pos.Line - 1) (token.RightColumn + 1) Some (true, position) @@ -776,11 +771,11 @@ module CodeGenerationUtils = sprintf "- %s" s let rec (|TypeIdent|_|) = function - | SynType.Var(SynTypar.Typar(s, req , _), _) -> + | SynType.Var(SynTypar(s, req , _), _) -> match req with - | NoStaticReq -> + | TyparStaticReq.None -> Some ("'" + s.idText) - | HeadTypeStaticReq -> + | TyparStaticReq.HeadType -> Some ("^" + s.idText) | SynType.LongIdent(LongIdentWithDots(xs, _)) -> xs |> Seq.map (fun x -> x.idText) |> String.concat "." |> Some diff --git a/src/FsAutoComplete.Core/Commands.fs b/src/FsAutoComplete.Core/Commands.fs index 4feda82f4..2f98a86d5 100644 --- a/src/FsAutoComplete.Core/Commands.fs +++ b/src/FsAutoComplete.Core/Commands.fs @@ -2,7 +2,6 @@ namespace FsAutoComplete open System open System.IO -open FSharp.Compiler.SourceCodeServices open Fantomas.Client.Contracts open Fantomas.Client.LSPFantomasService open FsAutoComplete.Logging @@ -11,12 +10,16 @@ open FsAutoComplete.RecordStubGenerator open FsAutoComplete.InterfaceStubGenerator open System.Threading open Utils +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices open FSharp.Compiler.Text open Ionide.ProjInfo open Ionide.ProjInfo.ProjectSystem open FsToolkit.ErrorHandling open FSharp.Analyzers open FSharp.UMX +open FSharp.Compiler.Tokenization [] type LocationResponse<'a, 'b> = @@ -26,7 +29,7 @@ type LocationResponse<'a, 'b> = [] type HelpText = | Simple of symbol: string * text: string - | Full of symbol: string * tip: FSharpToolTipText * textEdits: CompletionNamespaceInsert option + | Full of symbol: string * tip: ToolTipText * textEdits: CompletionNamespaceInsert option [] @@ -118,12 +121,12 @@ type Commands // note that the first and last segments can be zero-length. // in that case we should not emit them because it confuses the // encoding algorithm - if Pos.posEq firstSegment.Start firstSegment.End then + if Position.posEq firstSegment.Start firstSegment.End then () else firstSegment yield! innerSegments - if Pos.posEq lastSegment.Start lastSegment.End then + if Position.posEq lastSegment.Start lastSegment.End then () else lastSegment |] @@ -131,22 +134,22 @@ type Commands // TODO: LSP technically does now know how to handle overlapping, nested and multiline ranges, but // as of 3 February 2021 there are no good examples of this that I've found, so we still do this /// because LSP doesn't know how to handle overlapping/nested ranges, we have to dedupe them here - let scrubRanges (highlights: struct (range * _) array) : struct (range * _) array = - let startToken = fun (struct (m: Range, _)) -> m.Start.Line, m.Start.Column + let scrubRanges (highlights: SemanticClassificationItem array) : SemanticClassificationItem array = + let startToken = fun (m: SemanticClassificationItem) -> m.Range.StartLine, m.Range.StartColumn highlights |> Array.sortBy startToken - |> Array.groupBy (fun (struct (r, _)) -> r.StartLine) + |> Array.groupBy (fun m -> m.Range.StartLine) |> Array.collect (fun (_, highlights) -> // split out any ranges that contain other ranges on this line into the non-overlapping portions of that range - let expandParents (struct (parentRange, tokenType) as p) = + let expandParents (p: SemanticClassificationItem) = let children = highlights |> Array.except [ p ] - |> Array.choose (fun (struct (childRange, _)) -> - if Range.rangeContainsRange parentRange childRange then - Some childRange + |> Array.choose (fun child -> + if Range.rangeContainsRange p.Range child.Range then + Some child.Range else None) @@ -157,8 +160,8 @@ type Commands children |> Array.sortBy (fun r -> r.Start.Line, r.Start.Column) - segmentRanges parentRange sortedChildren - |> Array.map (fun subRange -> struct (subRange, tokenType)) + segmentRanges p.Range sortedChildren + |> Array.map (fun subRange -> SemanticClassificationItem((subRange, p.Type))) highlights |> Array.collect expandParents) |> Array.sortBy startToken @@ -269,13 +272,13 @@ type Commands NotificationEvent.FileParsed file |> notify.Trigger - let checkErrors = parseAndCheck.GetParseResults.Errors - let parseErrors = parseAndCheck.GetCheckResults.Errors + let checkErrors = parseAndCheck.GetParseResults.Diagnostics + let parseErrors = parseAndCheck.GetCheckResults.Diagnostics let errors = Array.append checkErrors parseErrors |> Array.distinctBy (fun e -> - e.Severity, e.ErrorNumber, e.StartLineAlternate, e.StartColumn, e.EndLineAlternate, e.EndColumn, e.Message) + e.Severity, e.ErrorNumber, e.StartLine, e.StartColumn, e.EndLine, e.EndColumn, e.Message) (errors, file) |> NotificationEvent.ParseError @@ -296,8 +299,8 @@ type Commands >> Log.addContextDestructured "file" file ) - match parseAndCheck.GetParseResults.ParseTree, parseAndCheck.GetCheckResults.ImplementationFile with - | Some pt, Some tast -> + match parseAndCheck.GetCheckResults.ImplementationFile with + | Some tast -> match state.Files.TryGetValue file with | true, fileData -> @@ -305,7 +308,7 @@ type Commands analyzerHandler ( file, fileData.Lines.ToString().Split("\n"), - pt, + parseAndCheck.GetParseResults.ParseTree, tast, parseAndCheck.GetCheckResults.PartialAssemblySignature.Entities |> Seq.toList, @@ -405,7 +408,7 @@ type Commands GetLineText0 = fun i -> lines.GetLineString i GetLineText1 = fun i -> lines.GetLineString(i - 1) } - let calculateNamespaceInsert (decl: FSharpDeclarationListItem) (pos: Pos) getLine : CompletionNamespaceInsert option = + let calculateNamespaceInsert (decl: DeclarationListItem) (pos: Position) getLine : CompletionNamespaceInsert option = let getLine i = try getLine i @@ -417,7 +420,7 @@ type Commands decl.NamespaceToOpen |> Option.bind (fun n -> state.CurrentAST - |> Option.map (fun ast -> ParsedInput.findNearestPointToInsertOpenDeclaration (pos.Line) ast idents Nearest) + |> Option.map (fun ast -> ParsedInput.FindNearestPointToInsertOpenDeclaration (pos.Line) ast idents OpenStatementInsertionPoint.Nearest) |> Option.map (fun ic -> //TODO: unite with `CodeFix/ResolveNamespace` //TODO: Handle Nearest AND TopLevel. Currently it's just Nearest (vs. ResolveNamespace -> TopLevel) (#789) @@ -461,14 +464,14 @@ type Commands 0 | _, c -> c - let pos = Pos.mkPos l c + let pos = Position.mkPos l c { Namespace = n Position = pos Scope = ic.ScopeKind })) - let fillHelpTextInTheBackground decls (pos: Pos) fn getLine = - let declName (d: FSharpDeclarationListItem) = d.Name + let fillHelpTextInTheBackground decls (pos: Position) fn getLine = + let declName (d: DeclarationListItem) = d.Name //Fill list of declarations synchronously to know which declarations should be in cache. for d in decls do @@ -756,7 +759,7 @@ type Commands do state.SetLastCheckedVersion fileName version do fileChecked.Trigger(parseAndCheck, fileName, version) - let errors = Array.append results.Errors parseResult.Errors + let errors = Array.append results.Diagnostics parseResult.Diagnostics CoreResponse.Res(errors, fileName) } @@ -894,7 +897,7 @@ type Commands match state.HelpText.TryFind sym with | Some tip -> tip | None -> - let tip = decl.DescriptionText + let tip = decl.Description state.HelpText.[sym] <- tip tip @@ -914,7 +917,7 @@ type Commands member x.Completion (tyRes: ParseAndCheckResults) - (pos: Pos) + (pos: Position) lineStr (lines: ISourceText) (fileName: string) @@ -933,14 +936,14 @@ type Commands match res with | Some (decls, residue, shouldKeywords) -> - let declName (d: FSharpDeclarationListItem) = d.Name + let declName (d: DeclarationListItem) = d.Name let getLine = fun i -> lines.GetLineString(i - 1) //Init cache for current list state.Declarations.Clear() state.HelpText.Clear() state.CompletionNamespaceInsert.Clear() - state.CurrentAST <- tyRes.GetAST + state.CurrentAST <- Some tyRes.GetAST //Fill cache for current list do fillHelpTextInTheBackground decls pos fileName getLine @@ -959,11 +962,11 @@ type Commands | None -> return CoreResponse.ErrorRes "Timed out while fetching completions" } - member x.ToolTip (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.ToolTip (tyRes: ParseAndCheckResults) (pos: Position) lineStr = tyRes.TryGetToolTipEnhanced pos lineStr |> Result.bimap CoreResponse.Res CoreResponse.ErrorRes - member x.FormattedDocumentation (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.FormattedDocumentation (tyRes: ParseAndCheckResults) (pos: Position) lineStr = tyRes.TryGetFormattedDocumentation pos lineStr |> Result.bimap CoreResponse.Res CoreResponse.ErrorRes @@ -971,23 +974,23 @@ type Commands tyRes.TryGetFormattedDocumentationForSymbol xmlSig assembly |> Result.map CoreResponse.Res - member x.Typesig (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.Typesig (tyRes: ParseAndCheckResults) (pos: Position) lineStr = tyRes.TryGetToolTip pos lineStr |> Result.bimap CoreResponse.Res CoreResponse.ErrorRes - member x.SymbolUse (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.SymbolUse (tyRes: ParseAndCheckResults) (pos: Position) lineStr = tyRes.TryGetSymbolUseAndUsages pos lineStr |> Result.bimap CoreResponse.Res CoreResponse.ErrorRes - member x.SignatureData (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.SignatureData (tyRes: ParseAndCheckResults) (pos: Position) lineStr = tyRes.TryGetSignatureData pos lineStr |> Result.bimap CoreResponse.Res CoreResponse.ErrorRes - member x.Help (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.Help (tyRes: ParseAndCheckResults) (pos: Position) lineStr = tyRes.TryGetF1Help pos lineStr |> Result.bimap CoreResponse.Res CoreResponse.ErrorRes - member x.SymbolUseProject (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.SymbolUseProject (tyRes: ParseAndCheckResults) (pos: Position) lineStr = async { match tyRes.TryGetSymbolUseAndUsages pos lineStr with | Ok (sym, usages) -> @@ -1011,13 +1014,13 @@ type Commands |> x.AsCancellable tyRes.FileName |> AsyncResult.recoverCancellation - member x.SymbolImplementationProject (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.SymbolImplementationProject (tyRes: ParseAndCheckResults) (pos: Position) lineStr = let filterSymbols symbols = symbols |> Array.where (fun (su: FSharpSymbolUse) -> su.IsFromDispatchSlotImplementation || (su.IsFromType - && not (UntypedAstUtils.isTypedBindingAtPosition tyRes.GetAST su.RangeAlternate))) + && not (UntypedAstUtils.isTypedBindingAtPosition tyRes.GetAST su.Range))) async { match tyRes.TryGetSymbolUseAndUsages pos lineStr with @@ -1043,13 +1046,13 @@ type Commands |> x.AsCancellable tyRes.FileName |> AsyncResult.recoverCancellation - member x.FindDeclaration (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.FindDeclaration (tyRes: ParseAndCheckResults) (pos: Position) lineStr = tyRes.TryFindDeclaration pos lineStr |> x.MapResult(CoreResponse.Res, CoreResponse.ErrorRes) |> x.AsCancellable tyRes.FileName |> AsyncResult.recoverCancellation - member x.FindTypeDeclaration (tyRes: ParseAndCheckResults) (pos: Pos) lineStr = + member x.FindTypeDeclaration (tyRes: ParseAndCheckResults) (pos: Position) lineStr = tyRes.TryFindTypeDeclaration pos lineStr |> x.MapResult(CoreResponse.Res, CoreResponse.ErrorRes) |> x.AsCancellable tyRes.FileName @@ -1059,7 +1062,7 @@ type Commands member x.MethodsForSignatureHelp ( tyRes: ParseAndCheckResults, - pos: Pos, + pos: Position, lines: ISourceText, triggerChar, possibleSessionKind @@ -1093,104 +1096,101 @@ type Commands // |> AsyncResult.recoverCancellationIgnore - member x.GetNamespaceSuggestions (tyRes: ParseAndCheckResults) (pos: Pos) (line: LineStr) = + member x.GetNamespaceSuggestions (tyRes: ParseAndCheckResults) (pos: Position) (line: LineStr) = async { - match tyRes.GetAST with - | None -> return CoreResponse.InfoRes "Parsed Tree not avaliable" - | Some parsedTree -> - match Lexer.findLongIdents (pos.Column, line) with - | None -> return CoreResponse.InfoRes "Ident not found" - | Some (_, idents) -> - match UntypedParseImpl.GetEntityKind(pos, parsedTree) with - | None -> return CoreResponse.InfoRes "EntityKind not found" - | Some entityKind -> - - let symbol = Lexer.getSymbol pos.Line pos.Column line SymbolLookupKind.Fuzzy [||] - - match symbol with - | None -> return CoreResponse.InfoRes "Symbol at position not found" - | Some sym -> - - - let entities = tyRes.GetAllEntities true - - let isAttribute = entityKind = EntityKind.Attribute - - let entities = - entities - |> List.filter (fun e -> - match entityKind, (e.Kind LookupType.Fuzzy) with - | EntityKind.Attribute, EntityKind.Attribute - | EntityKind.Type, - (EntityKind.Type - | EntityKind.Attribute) - | EntityKind.FunctionOrValue _, _ -> true - | EntityKind.Attribute, _ - | _, EntityKind.Module _ - | EntityKind.Module _, _ - | EntityKind.Type, _ -> false) - - let maybeUnresolvedIdents = - idents - |> Array.map (fun ident -> { Ident = ident; Resolved = false }) - - let entities = - entities - |> List.collect (fun e -> - [ yield e.TopRequireQualifiedAccessParent, e.AutoOpenParent, e.Namespace, e.CleanedIdents - if isAttribute then - let lastIdent = e.CleanedIdents.[e.CleanedIdents.Length - 1] - - if (e.Kind LookupType.Fuzzy) = EntityKind.Attribute - && lastIdent.EndsWith "Attribute" then - yield - e.TopRequireQualifiedAccessParent, - e.AutoOpenParent, - e.Namespace, - e.CleanedIdents - |> Array.replace (e.CleanedIdents.Length - 1) (lastIdent.Substring(0, lastIdent.Length - 9)) ]) - - let createEntity = - ParsedInput.tryFindInsertionContext pos.Line parsedTree maybeUnresolvedIdents TopLevel - - let word = sym.Text - - let candidates = entities |> Seq.collect createEntity |> Seq.toList - - let openNamespace = - candidates - |> List.choose (fun (entity, ctx) -> - entity.Namespace - |> Option.map (fun ns -> ns, entity.Name, ctx)) - |> List.groupBy (fun (ns, _, _) -> ns) - |> List.map (fun (ns, xs) -> - ns, - xs - |> List.map (fun (_, name, ctx) -> name, ctx) - |> List.distinctBy (fun (name, _) -> name) - |> List.sortBy fst) - |> List.collect (fun (ns, names) -> - let multipleNames = - match names with - | [] -> false - | [ _ ] -> false - | _ -> true - - names - |> List.map (fun (name, ctx) -> ns, name, ctx, multipleNames)) - - let qualifySymbolActions = - candidates - |> List.map (fun (entity, _) -> entity.FullRelativeName, entity.Qualifier) - |> List.distinct - |> List.sort - - return CoreResponse.Res(word, openNamespace, qualifySymbolActions) + match Lexer.findLongIdents (pos.Column, line) with + | None -> return CoreResponse.InfoRes "Ident not found" + | Some (_, idents) -> + match ParsedInput.GetEntityKind(pos, tyRes.GetParseResults.ParseTree) with + | None -> return CoreResponse.InfoRes "EntityKind not found" + | Some entityKind -> + + let symbol = Lexer.getSymbol pos.Line pos.Column line SymbolLookupKind.Fuzzy [||] + + match symbol with + | None -> return CoreResponse.InfoRes "Symbol at position not found" + | Some sym -> + + + let entities = tyRes.GetAllEntities true + + let isAttribute = entityKind = EntityKind.Attribute + + let entities = + entities + |> List.filter (fun e -> + match entityKind, (e.Kind LookupType.Fuzzy) with + | EntityKind.Attribute, EntityKind.Attribute + | EntityKind.Type, + (EntityKind.Type + | EntityKind.Attribute) + | EntityKind.FunctionOrValue _, _ -> true + | EntityKind.Attribute, _ + | _, EntityKind.Module _ + | EntityKind.Module _, _ + | EntityKind.Type, _ -> false) + + let maybeUnresolvedIdents = + idents + |> Array.map (fun ident -> { Ident = ident; Resolved = false }) + + let entities = + entities + |> List.collect (fun e -> + [ yield e.TopRequireQualifiedAccessParent, e.AutoOpenParent, e.Namespace, e.CleanedIdents + if isAttribute then + let lastIdent = e.CleanedIdents.[e.CleanedIdents.Length - 1] + + if (e.Kind LookupType.Fuzzy) = EntityKind.Attribute + && lastIdent.EndsWith "Attribute" then + yield + e.TopRequireQualifiedAccessParent, + e.AutoOpenParent, + e.Namespace, + e.CleanedIdents + |> Array.replace (e.CleanedIdents.Length - 1) (lastIdent.Substring(0, lastIdent.Length - 9)) ]) + + let createEntity = + ParsedInput.TryFindInsertionContext pos.Line tyRes.GetParseResults.ParseTree maybeUnresolvedIdents OpenStatementInsertionPoint.TopLevel + + let word = sym.Text + + let candidates = entities |> Seq.collect createEntity |> Seq.toList + + let openNamespace = + candidates + |> List.choose (fun (entity, ctx) -> + entity.Namespace + |> Option.map (fun ns -> ns, entity.FullDisplayName , ctx)) + |> List.groupBy (fun (ns, _, _) -> ns) + |> List.map (fun (ns, xs) -> + ns, + xs + |> List.map (fun (_, name, ctx) -> name, ctx) + |> List.distinctBy (fun (name, _) -> name) + |> List.sortBy fst) + |> List.collect (fun (ns, names) -> + let multipleNames = + match names with + | [] -> false + | [ _ ] -> false + | _ -> true + + names + |> List.map (fun (name, ctx) -> ns, name, ctx, multipleNames)) + + let qualifySymbolActions = + candidates + |> List.map (fun (entity, _) -> entity.FullRelativeName, entity.Qualifier) + |> List.distinct + |> List.sort + + return CoreResponse.Res(word, openNamespace, qualifySymbolActions) } |> x.AsCancellable tyRes.FileName |> AsyncResult.recoverCancellation - member x.GetUnionPatternMatchCases (tyRes: ParseAndCheckResults) (pos: Pos) (lines: ISourceText) (line: LineStr) = + member x.GetUnionPatternMatchCases (tyRes: ParseAndCheckResults) (pos: Position) (lines: ISourceText) (line: LineStr) = async { let codeGenService = CodeGenerationService(checker, state) @@ -1217,7 +1217,7 @@ type Commands |> x.AsCancellable tyRes.FileName |> AsyncResult.recoverCancellation - member x.GetRecordStub (tyRes: ParseAndCheckResults) (pos: Pos) (lines: ISourceText) (line: LineStr) = + member x.GetRecordStub (tyRes: ParseAndCheckResults) (pos: Position) (lines: ISourceText) (line: LineStr) = async { let doc = docForText lines tyRes let! res = tryFindRecordDefinitionFromPos codeGenServer pos doc @@ -1228,7 +1228,7 @@ type Commands if shouldGenerateRecordStub recordEpr recordDefinition then let result = formatRecord insertionPos "$1" recordDefinition recordEpr.FieldExprList - let pos = Pos.mkPos insertionPos.InsertionPos.Line insertionPos.InsertionPos.Column + let pos = Position.mkPos insertionPos.InsertionPos.Line insertionPos.InsertionPos.Column return CoreResponse.Res(result, pos) else @@ -1238,7 +1238,7 @@ type Commands |> x.AsCancellable tyRes.FileName |> AsyncResult.recoverCancellation - member x.GetInterfaceStub (tyRes: ParseAndCheckResults) (pos: Pos) (lines: ISourceText) (lineStr: LineStr) = + member x.GetInterfaceStub (tyRes: ParseAndCheckResults) (pos: Position) (lines: ISourceText) (lineStr: LineStr) = async { let doc = docForText lines tyRes let! res = tryFindInterfaceExprInBufferAtPos codeGenServer pos doc @@ -1373,7 +1373,7 @@ type Commands return positions - |> List.map (fun x -> UntypedAstUtils.getRangesAtPosition ast.ParseTree x) + |> List.map (UntypedAstUtils.getRangesAtPosition ast.ParseTree) |> CoreResponse.Res | _ -> return CoreResponse.InfoRes "Couldn't find file state" } @@ -1400,18 +1400,8 @@ type Commands let parseOpts = Utils.projectOptionsToParseOptions opts let! ast = checker.ParseFile(file, text, parseOpts) - match ast.ParseTree with - | None -> - return! - Error( - ast.Errors - |> Array.map string - |> String.concat Environment.NewLine - ) - | Some ast' -> - let ranges = Structure.getOutliningRanges (text.ToString().Split("\n")) ast' - - return ranges + let ranges = Structure.getOutliningRanges (text.ToString().Split("\n")) ast.ParseTree + return ranges } member __.SetDotnetSDKRoot(dotnetBinary: System.IO.FileInfo) = @@ -1521,7 +1511,7 @@ type Commands let getGenerics line (token: FSharpTokenInfo) = let lineStr = contents.GetLineString line - let res = tyRes.TryGetToolTip(Pos.fromZ line token.RightColumn) lineStr + let res = tyRes.TryGetToolTip(Position.fromZ line token.RightColumn) lineStr match res with | Ok tip -> TipFormatter.extractGenerics tip diff --git a/src/FsAutoComplete.Core/CompilerServiceInterface.fs b/src/FsAutoComplete.Core/CompilerServiceInterface.fs index 30c882b25..df46ac4f7 100644 --- a/src/FsAutoComplete.Core/CompilerServiceInterface.fs +++ b/src/FsAutoComplete.Core/CompilerServiceInterface.fs @@ -1,12 +1,14 @@ namespace FsAutoComplete open System.IO -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open Utils open FSharp.Compiler.Text open FsAutoComplete.Logging open Ionide.ProjInfo.ProjectSystem open FSharp.UMX +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols type Version = int @@ -21,7 +23,6 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = enableBackgroundItemKeyStoreAndSemanticClassification = true ) - do checker.ImplicitlyStartBackgroundWork <- not backgroundServiceEnabled do checker.BeforeBackgroundFileCheck.Add ignore // we only want to let people hook onto the underlying checker event if there's not a background service actually compiling things for us @@ -29,7 +30,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = if not backgroundServiceEnabled then checker.FileChecked else - (new Event()).Publish + (new Event<_>()).Publish // /// FCS only accepts absolute file paths, so this ensures that by // /// rooting relative paths onto HOME on *nix and %HOMRDRIVE%%HOMEPATH% on windows @@ -102,14 +103,6 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = else opts - let logQueueLength (logger: ILog) msg = - checkerLogger.trace ( - Log.setMessage "Current Queue Length is {queueLength}" - >> Log.addContextDestructured "queueLength" checker.CurrentQueueLength - ) - - logger.info msg - let filterBadRuntimeRefs = let badRefs = [ "System.Private" @@ -130,8 +123,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = let addLoadedFiles (projectOptions: FSharpProjectOptions) = let files = Array.append fsiAdditionalFiles projectOptions.SourceFiles - logQueueLength - optsLogger + optsLogger.info (Log.setMessage "Source file list is {files}" >> Log.addContextDestructured "files" files) @@ -174,13 +166,12 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = |> Seq.distinctBy (fun o -> o.ProjectFileName) |> Seq.filter (fun o -> o.ReferencedProjects - |> Array.map (fun (_, v) -> Path.GetFullPath v.ProjectFileName) + |> Array.map (fun p -> Path.GetFullPath p.FileName) |> Array.contains option.ProjectFileName) ]) member private __.GetNetFxScriptOptions(file: string, source) = async { - logQueueLength - optsLogger + optsLogger.info (Log.setMessage "Getting NetFX options for script file {file}" >> Log.addContextDestructured "file" file) @@ -203,8 +194,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = member private __.GetNetCoreScriptOptions(file: string, source) = async { - logQueueLength - optsLogger + optsLogger.info (Log.setMessage "Getting NetCore options for script file {file}" >> Log.addContextDestructured "file" file) @@ -254,8 +244,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = match errors with | [] -> () | errs -> - logQueueLength - optsLogger + optsLogger.info (Log.setLogLevel LogLevel.Error >> Log.setMessage "Resolved {opts} with {errors}" >> Log.addContextDestructured "opts" projOptions @@ -284,8 +273,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = } member __.GetBackgroundCheckResultsForFileInProject(fn: string, opt) = - logQueueLength - checkerLogger + checkerLogger.info (Log.setMessage "GetBackgroundCheckResultsForFileInProject - {file}" >> Log.addContextDestructured "file" fn) @@ -294,15 +282,14 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = checker.GetBackgroundCheckResultsForFileInProject(UMX.untag fn, opt) |> Async.map (fun (pr, cr) -> ParseAndCheckResults(pr, cr, entityCache)) - member __.FileChecked: IEvent * obj option> = + member __.FileChecked: IEvent * FSharpProjectOptions> = safeFileCheckedEvent |> Event.map (fun (fileName, blob) -> UMX.tag fileName, blob) //path comes from the compiler, so it's safe to assume the tag in this case member __.ScriptTypecheckRequirementsChanged = scriptTypecheckRequirementsChanged.Publish member __.ParseFile(fn: string, source, fpo) = - logQueueLength - checkerLogger + checkerLogger.info (Log.setMessage "ParseFile - {file}" >> Log.addContextDestructured "file" fn) @@ -312,9 +299,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = member __.ParseAndCheckFileInProject(filePath: string, version, source, options) = async { let opName = sprintf "ParseAndCheckFileInProject - %A" filePath - - logQueueLength - checkerLogger + checkerLogger.info (Log.setMessage "{opName}" >> Log.addContextDestructured "opName" opName) @@ -324,20 +309,18 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = try let! (p, c) = checker.ParseAndCheckFileInProject(path, version, source, options, userOpName = opName) - let parseErrors = p.Errors |> Array.map (fun p -> p.Message) + let parseErrors = p.Diagnostics |> Array.map (fun p -> p.Message) match c with | FSharpCheckFileAnswer.Aborted -> - logQueueLength - checkerLogger + checkerLogger.info (Log.setMessage "{opName} completed with errors: {errors}" >> Log.addContextDestructured "opName" opName - >> Log.addContextDestructured "errors" (List.ofArray p.Errors)) + >> Log.addContextDestructured "errors" (List.ofArray p.Diagnostics)) return ResultOrString.Error(sprintf "Check aborted (%A). Errors: %A" c parseErrors) | FSharpCheckFileAnswer.Succeeded (c) -> - logQueueLength - checkerLogger + checkerLogger.info (Log.setMessage "{opName} completed successfully" >> Log.addContextDestructured "opName" opName) @@ -349,8 +332,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = member __.TryGetRecentCheckResultsForFile(file: string, options, ?source) = let opName = sprintf "TryGetRecentCheckResultsForFile - %A" file - logQueueLength - checkerLogger + checkerLogger.info (Log.setMessage "{opName}" >> Log.addContextDestructured "opName" opName) @@ -366,8 +348,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = symbol: FSharpSymbol ) = async { - logQueueLength - checkerLogger + checkerLogger.info (Log.setMessage "GetUsesOfSymbol - {file}" >> Log.addContextDestructured "file" file) @@ -394,8 +375,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = member __.GetDeclarations(fileName: string, source, options, version) = async { - logQueueLength - checkerLogger + checkerLogger.info (Log.setMessage "GetDeclarations - {file}" >> Log.addContextDestructured "file" fileName) diff --git a/src/FsAutoComplete.Core/Decompiler.fs b/src/FsAutoComplete.Core/Decompiler.fs index 1b21718d3..a39dd4ffe 100644 --- a/src/FsAutoComplete.Core/Decompiler.fs +++ b/src/FsAutoComplete.Core/Decompiler.fs @@ -2,7 +2,7 @@ open System open System.IO -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Text open Utils open System.Text.RegularExpressions open ICSharpCode.Decompiler.CSharp @@ -12,6 +12,9 @@ open ICSharpCode.Decompiler.TypeSystem open ICSharpCode.Decompiler.CSharp.Syntax open ICSharpCode.Decompiler.CSharp.Transforms open System.Collections.Generic +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols +open FSharp.Compiler.EditorServices type TextWriterWithLocationFinder(tokenWriter:TextWriterTokenWriter, formattingPolicy, symbol:ISymbol option) = inherit CSharpOutputVisitor(tokenWriter, formattingPolicy) @@ -78,7 +81,7 @@ let resolveType (typeSystem: IDecompilerTypeSystem) (typeName:string) = let rec formatExtTypeFullName externalType = match externalType with - | ExternalType.Type (name, genericArgs) -> + | FindDeclExternalType.Type (name, genericArgs) -> match genericArgs with | [] -> "" | args -> @@ -87,12 +90,12 @@ let rec formatExtTypeFullName externalType = |> String.concat "," |> sprintf "[%s]" |> sprintf "%s%s" name - | ExternalType.Array inner -> sprintf "%s[]" (formatExtTypeFullName inner) - | ExternalType.Pointer inner -> sprintf "&%s" (formatExtTypeFullName inner) - | ExternalType.TypeVar name -> sprintf "%s" name + | FindDeclExternalType.Array inner -> sprintf "%s[]" (formatExtTypeFullName inner) + | FindDeclExternalType.Pointer inner -> sprintf "&%s" (formatExtTypeFullName inner) + | FindDeclExternalType.TypeVar name -> sprintf "%s" name -let areSameTypes (typeArguments:IReadOnlyList) ((mParam,paramSym):IParameter*ParamTypeSymbol) = - let compareToExternalType (extType:ExternalType) = +let areSameTypes (typeArguments:IReadOnlyList) ((mParam,paramSym):IParameter * FindDeclExternalParam) = + let compareToExternalType (extType: FindDeclExternalType) = let parameterTypeFullName = typeArguments |> Seq.fold @@ -102,21 +105,19 @@ let areSameTypes (typeArguments:IReadOnlyList) ((mParam,paramSym):IParame let extTypeFullName = formatExtTypeFullName extType parameterTypeFullName = extTypeFullName - match paramSym with - | ParamTypeSymbol.Param extType -> compareToExternalType extType - | ParamTypeSymbol.Byref extType -> - mParam.IsRef && compareToExternalType extType + if paramSym.IsByRef then mParam.IsRef && compareToExternalType paramSym.ParameterType + else compareToExternalType paramSym.ParameterType let getDeclaringTypeName = function - | FSharpExternalSymbol.Type (fullName) -> fullName - | FSharpExternalSymbol.Constructor (typeName, _args) -> typeName - | FSharpExternalSymbol.Method (typeName, _name, _paramSyms, _genericArity) -> typeName - | FSharpExternalSymbol.Field (typeName, _name) -> typeName - | FSharpExternalSymbol.Event (typeName, _name) -> typeName - | FSharpExternalSymbol.Property (typeName, _name) -> typeName - -let findMethodFromArgs (args:ParamTypeSymbol list) (methods:IMethod seq) = + | FindDeclExternalSymbol.Type (fullName) -> fullName + | FindDeclExternalSymbol.Constructor (typeName, _args) -> typeName + | FindDeclExternalSymbol.Method (typeName, _name, _paramSyms, _genericArity) -> typeName + | FindDeclExternalSymbol.Field (typeName, _name) -> typeName + | FindDeclExternalSymbol.Event (typeName, _name) -> typeName + | FindDeclExternalSymbol.Property (typeName, _name) -> typeName + +let findMethodFromArgs (args: FindDeclExternalParam list) (methods:IMethod seq) = methods |> Seq.tryFind (fun m -> let mParams = m.Parameters @@ -126,7 +127,7 @@ let findMethodFromArgs (args:ParamTypeSymbol list) (methods:IMethod seq) = type ExternalContentPosition = { File: string - Position: FSharp.Compiler.Text.Pos } + Position: FSharp.Compiler.Text.Position } let toSafeFileNameRegex = System.Text.RegularExpressions.Regex("[^\w\.`\s]+", RegexOptions.Compiled) @@ -136,9 +137,9 @@ let toSafeFileName (typeDef:ITypeDefinition) = toSafeFileNameRegex.Replace(str, "_") type DecompileError = -| Exception of symbol: FSharpExternalSymbol * filePath: string * error: exn +| Exception of symbol: FindDeclExternalSymbol * filePath: string * error: exn -let decompile (externalSym: FSharpExternalSymbol) assemblyPath: Result = +let decompile (externalSym: FindDeclExternalSymbol) assemblyPath: Result = try let decompiler = decompilerForFile assemblyPath @@ -150,29 +151,29 @@ let decompile (externalSym: FSharpExternalSymbol) assemblyPath: Result Some (typeDef :> ISymbol) - | FSharpExternalSymbol.Constructor (_typeName, args) -> + | FindDeclExternalSymbol.Type _ -> Some (typeDef :> ISymbol) + | FindDeclExternalSymbol.Constructor (_typeName, args) -> typeDef.GetConstructors() |> findMethodFromArgs args |> Option.map (fun x -> x :> ISymbol) - | FSharpExternalSymbol.Method (_typeName, name, args, genericArity) -> + | FindDeclExternalSymbol.Method (_typeName, name, args, genericArity) -> typeDef.GetMethods(filter = Predicate (fun m -> m.Name = name)) |> Seq.where (fun m -> m.TypeParameters.Count = genericArity) |> findMethodFromArgs args |> Option.map (fun x -> x :> ISymbol) - | FSharpExternalSymbol.Field (_typeName, name) -> + | FindDeclExternalSymbol.Field (_typeName, name) -> typeDef.GetFields(filter = Predicate (fun m -> m.Name = name)) |> Seq.tryHead |> Option.map (fun x -> x :> ISymbol) - | FSharpExternalSymbol.Event (_typeName, name) -> + | FindDeclExternalSymbol.Event (_typeName, name) -> typeDef.GetEvents(filter = Predicate (fun m -> m.Name = name)) |> Seq.tryHead |> Option.map (fun x -> x :> ISymbol) - | FSharpExternalSymbol.Property (_typeName, name) -> + | FindDeclExternalSymbol.Property (_typeName, name) -> typeDef.GetProperties(filter = Predicate (fun m -> m.Name = name)) |> Seq.tryHead |> Option.map (fun x -> x :> ISymbol) @@ -190,10 +191,10 @@ let decompile (externalSym: FSharpExternalSymbol) assemblyPath: Result Ok { File = tempFile // external library columns are 1-based, not 0-based like FCS Pos columns - Position = FSharp.Compiler.Text.Pos.mkPos l.Line (l.Column - 1) } + Position = FSharp.Compiler.Text.Position.mkPos l.Line (l.Column - 1) } | None -> Ok { File = tempFile - Position = FSharp.Compiler.Text.Pos.pos0 } + Position = FSharp.Compiler.Text.Position.pos0 } with | e -> Result.Error (Exception (externalSym, assemblyPath, e)) @@ -202,7 +203,7 @@ type FindExternalDeclarationError = | ReferenceHasNoFileName of assembly: FSharpAssembly | DecompileError of error: DecompileError -let tryFindExternalDeclaration (checkResults:FSharpCheckFileResults) (assembly, externalSym): Result = +let tryFindExternalDeclaration (checkResults: FSharpCheckFileResults) (assembly, externalSym: FindDeclExternalSymbol): Result = match checkResults.ProjectContext.GetReferencedAssemblies() |> List.tryFind(fun x -> x.SimpleName = assembly) with diff --git a/src/FsAutoComplete.Core/DocumentationFormatter.fs b/src/FsAutoComplete.Core/DocumentationFormatter.fs index 62157363e..21d782898 100644 --- a/src/FsAutoComplete.Core/DocumentationFormatter.fs +++ b/src/FsAutoComplete.Core/DocumentationFormatter.fs @@ -1,14 +1,15 @@ namespace FsAutoComplete - -open System.Text.RegularExpressions - module DocumentationFormatter = - - open FSharp.Compiler - open FSharp.Compiler.SourceCodeServices + + open FSharp.Compiler.CodeAnalysis + open FSharp.Compiler.EditorServices + open FSharp.Compiler.Symbols + open FSharp.Compiler.Syntax + open FSharp.Compiler.Tokenization open System open System.Text + open System.Text.RegularExpressions let nl = Environment.NewLine let maxPadding = 200 @@ -74,7 +75,7 @@ module DocumentationFormatter = [formatLink name xmlDocSig assemblyName] else if typ.HasTypeDefinition then - let name = typ.TypeDefinition.DisplayName |> FSharpKeywords.QuoteIdentifierIfNeeded + let name = typ.TypeDefinition.DisplayName |> FSharpKeywords.AddBackticksToIdentifierIfNeeded [formatLink name xmlDocSig assemblyName] else let name = typ.Format displayContext @@ -100,7 +101,7 @@ module DocumentationFormatter = chopped, true | _, _ -> if PrettyNaming.IsMangledOpName c.MemberName then - PrettyNaming.DemangleOperatorName c.MemberName, false + PrettyNaming.DecompileOpName c.MemberName, false else c.MemberName, false @@ -161,9 +162,9 @@ module DocumentationFormatter = with :? InvalidOperationException -> p.DisplayName, p.DisplayName.Length let getUnioncaseSignature displayContext (unionCase:FSharpUnionCase) = - if unionCase.UnionCaseFields.Count > 0 then + if unionCase.Fields.Count > 0 then let typeList = - unionCase.UnionCaseFields + unionCase.Fields |> Seq.map (fun unionField -> if unionField.Name.StartsWith "Item" then //TODO: Some better way of detecting default names for the union cases' fields unionField.FieldType |> format displayContext |> fst @@ -183,10 +184,10 @@ module DocumentationFormatter = match func.EnclosingEntitySafe with | Some ent -> ent.DisplayName | _ -> func.DisplayName - |> FSharpKeywords.QuoteIdentifierIfNeeded + |> FSharpKeywords.AddBackticksToIdentifierIfNeeded elif func.IsOperatorOrActivePattern then func.DisplayName - elif func.DisplayName.StartsWith "( " then FSharpKeywords.QuoteIdentifierIfNeeded func.LogicalName - else FSharpKeywords.QuoteIdentifierIfNeeded func.DisplayName + elif func.DisplayName.StartsWith "( " then FSharpKeywords.AddBackticksToIdentifierIfNeeded func.LogicalName + else FSharpKeywords.AddBackticksToIdentifierIfNeeded func.DisplayName name let modifiers = @@ -241,7 +242,7 @@ module DocumentationFormatter = argInfos |> List.concat |> List.map (fun p -> let name = Option.defaultValue p.DisplayName p.Name - let normalisedName = FSharpKeywords.QuoteIdentifierIfNeeded name + let normalisedName = FSharpKeywords.AddBackticksToIdentifierIfNeeded name normalisedName.Length) match allLengths with | [] -> 0 @@ -249,7 +250,7 @@ module DocumentationFormatter = let formatName indent padding (parameter:FSharpParameter) = let name = Option.defaultValue parameter.DisplayName parameter.Name - let normalisedName = FSharpKeywords.QuoteIdentifierIfNeeded name + let normalisedName = FSharpKeywords.AddBackticksToIdentifierIfNeeded name indent + normalisedName.PadRight padding + ":" let isDelegate = @@ -310,7 +311,7 @@ module DocumentationFormatter = let name = if func.IsConstructor then "new" elif func.IsOperatorOrActivePattern then func.DisplayName - elif func.DisplayName.StartsWith "( " then FSharpKeywords.QuoteIdentifierIfNeeded func.LogicalName + elif func.DisplayName.StartsWith "( " then FSharpKeywords.AddBackticksToIdentifierIfNeeded func.LogicalName elif func.LogicalName.StartsWith "get_" || func.LogicalName.StartsWith "set_" then PrettyNaming.TryChopPropertyName func.DisplayName |> Option.defaultValue func.DisplayName else func.DisplayName fst (formatLink name func.XmlDocSig func.Assembly.SimpleName) @@ -415,7 +416,7 @@ module DocumentationFormatter = let name = if v.DisplayName.StartsWith "( " then v.LogicalName else v.DisplayName - |> FSharpKeywords.QuoteIdentifierIfNeeded + |> FSharpKeywords.AddBackticksToIdentifierIfNeeded let constraints = match v.FullTypeSafe with | Some fulltype when fulltype.IsGenericParameter -> @@ -506,7 +507,7 @@ module DocumentationFormatter = |> Seq.collect (fun f -> seq { yield getFuncSignatureForTypeSignature displayContext f false false - yield! f.Overloads false |> Option.map (Seq.map (fun f -> getFuncSignatureForTypeSignature displayContext f false false)) |> Option.defaultValue Seq.empty + yield! f.GetOverloads false |> Option.map (Seq.map (fun f -> getFuncSignatureForTypeSignature displayContext f false false)) |> Option.defaultValue Seq.empty }) |> Seq.toArray @@ -550,7 +551,7 @@ module DocumentationFormatter = [ for f in v do yield getFuncSignatureForTypeSignature displayContext f false false - yield! f.Overloads false |> Option.map (Seq.map (fun f -> getFuncSignatureForTypeSignature displayContext f false false)) |> Option.defaultValue Seq.empty + yield! f.GetOverloads false |> Option.map (Seq.map (fun f -> getFuncSignatureForTypeSignature displayContext f false false)) |> Option.defaultValue Seq.empty ]) |> Seq.toArray @@ -575,7 +576,7 @@ module DocumentationFormatter = let typeDisplay = let name = - let normalisedName = FSharpKeywords.QuoteIdentifierIfNeeded fse.DisplayName + let normalisedName = FSharpKeywords.AddBackticksToIdentifierIfNeeded fse.DisplayName if fse.GenericParameters.Count > 0 then let paramsAndConstraints = fse.GenericParameters @@ -607,7 +608,7 @@ module DocumentationFormatter = - let footerForType (entity:FSharpSymbolUse) = + let footerForType (entity: FSharpSymbolUse) = try match entity with | SymbolUse.MemberFunctionOrValue m -> diff --git a/src/FsAutoComplete.Core/FCSPatches.fs b/src/FsAutoComplete.Core/FCSPatches.fs index 04f47ef00..f52569377 100644 --- a/src/FsAutoComplete.Core/FCSPatches.fs +++ b/src/FsAutoComplete.Core/FCSPatches.fs @@ -3,10 +3,10 @@ module FsAutoComplete.FCSPatches -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.SyntaxTree +open FSharp.Compiler.Syntax open FSharp.Compiler.Text open FsAutoComplete.UntypedAstUtils +open FSharp.Compiler.CodeAnalysis module internal SynExprAppLocationsImpl = let rec private searchSynArgExpr traverseSynExpr expr ranges = @@ -39,10 +39,10 @@ module internal SynExprAppLocationsImpl = | _ -> None, Some inner let getAllCurriedArgsAtPosition pos parseTree = - AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with + SyntaxTraversal.Traverse(pos, parseTree, { new SyntaxVisitorBase<_>() with member _.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = match expr with - | SynExpr.App (_exprAtomicFlag, _isInfix, funcExpr, argExpr, range) when Pos.posEq pos range.Start -> + | SynExpr.App (_exprAtomicFlag, _isInfix, funcExpr, argExpr, range) when Position.posEq pos range.Start -> let isInfixFuncExpr = match funcExpr with | SynExpr.App (_, isInfix, _, _, _) -> isInfix @@ -67,30 +67,27 @@ module internal SynExprAppLocationsImpl = type FSharpParseFileResults with member scope.IsPositionContainedInACurriedParameter pos = - match scope.ParseTree with - | Some input -> - let result = - AstTraversal.Traverse(pos, input, { new AstTraversal.AstVisitorBase<_>() with - member __.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = - defaultTraverse(expr) - - override __.VisitBinding (_, binding) = - match binding with - | SynBinding.Binding(_, _, _, _, _, _, valData, _, _, _, ((ContainsPos pos) as range), _) -> - let info = valData.SynValInfo.CurriedArgInfos - let mutable found = false - for group in info do - for arg in group do - match arg.Ident with - | Some (IdentContainsPos pos) -> - found <- true - | _ -> () - if found then Some range else None - | _ -> - None - }) - result.IsSome - | _ -> false + let result = + SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member __.VisitExpr(_path, traverseSynExpr, defaultTraverse, expr) = + defaultTraverse(expr) + + override __.VisitBinding (_, _, binding) = + match binding with + | SynBinding(_, _, _, _, _, _, valData, _, _, _, ((ContainsPos pos) as range), _) -> + let info = valData.SynValInfo.CurriedArgInfos + let mutable found = false + for group in info do + for arg in group do + match arg.Ident with + | Some (IdentContainsPos pos) -> + found <- true + | _ -> () + if found then Some range else None + | _ -> + None + }) + result.IsSome member scope.TryRangeOfParenEnclosingOpEqualsGreaterUsage opGreaterEqualPos = /// reused pattern to find applications of => (a symptom of improper C# style lambdas) @@ -98,101 +95,83 @@ type FSharpParseFileResults with function | SynExpr.App(ExprAtomicFlag.NonAtomic, false, SynExpr.App(ExprAtomicFlag.NonAtomic, true, Ident "op_EqualsGreater", actualParamListExpr, _), actualLambdaBodyExpr, _) -> Some (actualParamListExpr, actualLambdaBodyExpr) | _ -> None - match scope.ParseTree with - | None -> None - | Some input -> - let visitor = { - new AstTraversal.AstVisitorBase<_>() with + + let visitor = { + new SyntaxVisitorBase<_>() with member _.VisitExpr(_, _, defaultTraverse, expr) = match expr with | SynExpr.Paren((InfixAppOfOpEqualsGreater(lambdaArgs, lambdaBody) as app), _, _, _) -> Some (app.Range, lambdaArgs.Range, lambdaBody.Range) | _ -> defaultTraverse expr - member _.VisitBinding(defaultTraverse, binding) = + member _.VisitBinding(_, defaultTraverse, binding) = match binding with - | SynBinding.Binding (_, SynBindingKind.NormalBinding, _, _, _, _, _, _, _, (InfixAppOfOpEqualsGreater(lambdaArgs, lambdaBody) as app), _, _) -> + | SynBinding (_, SynBindingKind.Normal, _, _, _, _, _, _, _, (InfixAppOfOpEqualsGreater(lambdaArgs, lambdaBody) as app), _, _) -> Some(app.Range, lambdaArgs.Range, lambdaBody.Range) | _ -> defaultTraverse binding } - AstTraversal.Traverse(opGreaterEqualPos, input, visitor) + SyntaxTraversal.Traverse(opGreaterEqualPos, scope.ParseTree, visitor) member scope.TryRangeOfRefCellDereferenceContainingPos expressionPos = - match scope.ParseTree with - | Some input -> - AstTraversal.Traverse(expressionPos, input, { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_, _, defaultTraverse, expr) = - match expr with - | SynExpr.App(_, false, SynExpr.Ident funcIdent, expr, _) -> - if funcIdent.idText = "op_Dereference" && Range.rangeContainsPos expr.Range expressionPos then - Some funcIdent.idRange - else - None - | _ -> defaultTraverse expr }) - | None -> None + SyntaxTraversal.Traverse(expressionPos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.App(_, false, SynExpr.Ident funcIdent, expr, _) -> + if funcIdent.idText = "op_Dereference" && Range.rangeContainsPos expr.Range expressionPos then + Some funcIdent.idRange + else + None + | _ -> defaultTraverse expr }) member scope.TryRangeOfRecordExpressionContainingPos pos = - match scope.ParseTree with - | Some input -> - AstTraversal.Traverse(pos, input, { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_, _, defaultTraverse, expr) = - match expr with - | SynExpr.Record(_, _, _, range) when Range.rangeContainsPos range pos -> - Some range - | _ -> defaultTraverse expr }) - | None -> - None + SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.Record(_, _, _, range) when Range.rangeContainsPos range pos -> + Some range + | _ -> defaultTraverse expr }) member scope.TryRangeOfExprInYieldOrReturn pos = - match scope.ParseTree with - | Some parseTree -> - AstTraversal.Traverse(pos, parseTree, { new AstTraversal.AstVisitorBase<_>() with - member __.VisitExpr(_path, _, defaultTraverse, expr) = - match expr with - | SynExpr.YieldOrReturn(_, expr, range) - | SynExpr.YieldOrReturnFrom(_, expr, range) when Range.rangeContainsPos range pos -> - Some expr.Range - | _ -> defaultTraverse expr }) - | None -> None + SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member __.VisitExpr(_path, _, defaultTraverse, expr) = + match expr with + | SynExpr.YieldOrReturn(_, expr, range) + | SynExpr.YieldOrReturnFrom(_, expr, range) when Range.rangeContainsPos range pos -> + Some expr.Range + | _ -> defaultTraverse expr }) /// Attempts to find an Ident of a pipeline containing the given position, and the number of args already applied in that pipeline. /// For example, '[1..10] |> List.map ' would give back the ident of '|>' and 1, because it applied 1 arg (the list) to 'List.map'. member scope.TryIdentOfPipelineContainingPosAndNumArgsApplied pos = - match scope.ParseTree with - | Some input -> - AstTraversal.Traverse(pos, input, { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_, _, defaultTraverse, expr) = - match expr with - | SynExpr.App (_, _, SynExpr.App(_, true, SynExpr.Ident ident, _, _), argExpr, _) when Range.rangeContainsPos argExpr.Range pos -> - if ident.idText = "op_PipeRight" then - Some (ident, 1) - elif ident.idText = "op_PipeRight2" then - Some (ident, 2) - elif ident.idText = "op_PipeRight3" then - Some (ident, 3) - else - None - | _ -> defaultTraverse expr - }) - | None -> None + SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.App (_, _, SynExpr.App(_, true, SynExpr.Ident ident, _, _), argExpr, _) when Range.rangeContainsPos argExpr.Range pos -> + if ident.idText = "op_PipeRight" then + Some (ident, 1) + elif ident.idText = "op_PipeRight2" then + Some (ident, 2) + elif ident.idText = "op_PipeRight3" then + Some (ident, 3) + else + None + | _ -> defaultTraverse expr + }) /// Determines if the given position is inside a function or method application. member scope.IsPosContainedInApplicationPatched pos = - match scope.ParseTree with - | Some input -> - let result = - AstTraversal.Traverse(pos, input, { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_, traverseSynExpr, defaultTraverse, expr) = - match expr with - | SynExpr.TypeApp (_, _, _, _, _, _, range) when Range.rangeContainsPos range pos -> - Some range - | SynExpr.App(_, _, _, SynExpr.CompExpr (_, _, expr, _), range) when Range.rangeContainsPos range pos -> - traverseSynExpr expr - | SynExpr.App (_, _, _, _, range) when Range.rangeContainsPos range pos -> - Some range - | _ -> defaultTraverse expr - }) - result.IsSome - | None -> false + let result = + SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, traverseSynExpr, defaultTraverse, expr) = + match expr with + | SynExpr.TypeApp (_, _, _, _, _, _, range) when Range.rangeContainsPos range pos -> + Some range + | SynExpr.App(_, _, _, SynExpr.ComputationExpr (_, expr, _), range) when Range.rangeContainsPos range pos -> + traverseSynExpr expr + | SynExpr.App (_, _, _, _, range) when Range.rangeContainsPos range pos -> + Some range + | _ -> defaultTraverse expr + }) + result.IsSome /// Attempts to find the range of a function or method that is being applied. Also accounts for functions in pipelines. member scope.TryRangeOfFunctionOrMethodBeingAppliedPatched pos = @@ -214,7 +193,7 @@ type FSharpParseFileResults with getIdentRangeForFuncExprInApp traverseSynExpr argExpr pos // Special case: `async { ... }` is actually a CompExpr inside of the argExpr of a SynExpr.App - | SynExpr.CompExpr (_, _, expr, range) when Range.rangeContainsPos range pos -> + | SynExpr.ComputationExpr (_, expr, range) when Range.rangeContainsPos range pos -> getIdentRangeForFuncExprInApp traverseSynExpr expr pos | SynExpr.Paren (expr, _, _, range) when Range.rangeContainsPos range pos -> @@ -235,14 +214,14 @@ type FSharpParseFileResults with | SynExpr.LetOrUse (_, _, bindings, body, range) when Range.rangeContainsPos range pos -> let binding = bindings - |> List.tryFind (fun x -> Range.rangeContainsPos x.RangeOfBindingAndRhs pos) + |> List.tryFind (fun x -> Range.rangeContainsPos x.RangeOfBindingWithRhs pos) match binding with - | Some(SynBinding.Binding(_, _, _, _, _, _, _, _, _, expr, _, _)) -> + | Some(SynBinding(_, _, _, _, _, _, _, _, _, expr, _, _)) -> getIdentRangeForFuncExprInApp traverseSynExpr expr pos | None -> getIdentRangeForFuncExprInApp traverseSynExpr body pos - | SynExpr.IfThenElse (ifExpr, thenExpr, elseExpr, _, _, _, range) when Range.rangeContainsPos range pos -> + | SynExpr.IfThenElse (_, _, ifExpr, _, thenExpr, _, elseExpr, _, _, _, range) when Range.rangeContainsPos range pos -> if Range.rangeContainsPos ifExpr.Range pos then getIdentRangeForFuncExprInApp traverseSynExpr ifExpr pos elif Range.rangeContainsPos thenExpr.Range pos then @@ -262,7 +241,7 @@ type FSharpParseFileResults with | None -> None | Some clause -> match clause with - | SynMatchClause.Clause (_, whenExpr, resultExpr, _, _) -> + | SynMatchClause (_, whenExpr, _, resultExpr, _, _) -> match whenExpr with | None -> getIdentRangeForFuncExprInApp traverseSynExpr resultExpr pos @@ -282,7 +261,7 @@ type FSharpParseFileResults with getIdentRangeForFuncExprInApp traverseSynExpr expr pos // Capture the body of a lambda, often nested in a call to a collection function - | SynExpr.Lambda(_, _, _args, body, _, _) when Range.rangeContainsPos body.Range pos -> + | SynExpr.Lambda(_, _, _args, _, body, _, _) when Range.rangeContainsPos body.Range pos -> getIdentRangeForFuncExprInApp traverseSynExpr body pos | SynExpr.Do(expr, range) when Range.rangeContainsPos range pos -> @@ -298,101 +277,88 @@ type FSharpParseFileResults with traverseSynExpr expr |> Option.map (fun expr -> expr) - match scope.ParseTree with - | Some input -> - AstTraversal.Traverse(pos, input, { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_, traverseSynExpr, defaultTraverse, expr) = - match expr with - | SynExpr.TypeApp (expr, _, _, _, _, _, range) when Range.rangeContainsPos range pos -> - getIdentRangeForFuncExprInApp traverseSynExpr expr pos - | SynExpr.App (_, _, _funcExpr, _, range) as app when Range.rangeContainsPos range pos -> - getIdentRangeForFuncExprInApp traverseSynExpr app pos - | _ -> defaultTraverse expr - }) - | None -> None + + SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, traverseSynExpr, defaultTraverse, expr) = + match expr with + | SynExpr.TypeApp (expr, _, _, _, _, _, range) when Range.rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr expr pos + | SynExpr.App (_, _, _funcExpr, _, range) as app when Range.rangeContainsPos range pos -> + getIdentRangeForFuncExprInApp traverseSynExpr app pos + | _ -> defaultTraverse expr + }) /// Gets the ranges of all arguments, if they can be found, for a function application at the given position. member scope.GetAllArgumentsForFunctionApplicationAtPostion pos = - match scope.ParseTree with - | Some input -> SynExprAppLocationsImpl.getAllCurriedArgsAtPosition pos input - | None -> None + SynExprAppLocationsImpl.getAllCurriedArgsAtPosition pos scope.ParseTree member scope.TryRangeOfExpressionBeingDereferencedContainingPos expressionPos = - scope.ParseTree - |> Option.bind (fun input -> - AstTraversal.Traverse(expressionPos, input, { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_, _, defaultTraverse, expr) = - match expr with - | SynExpr.App(_, false, SynExpr.Ident funcIdent, expr, _) -> - if funcIdent.idText = "op_Dereference" && Range.rangeContainsPos expr.Range expressionPos then - Some expr.Range - else - None - | _ -> defaultTraverse expr }) - ) + SyntaxTraversal.Traverse(expressionPos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + match expr with + | SynExpr.App(_, false, SynExpr.Ident funcIdent, expr, _) -> + if funcIdent.idText = "op_Dereference" && Range.rangeContainsPos expr.Range expressionPos then + Some expr.Range + else + None + | _ -> defaultTraverse expr }) member scope.IsTypeAnnotationGivenAtPositionPatched pos = - match scope.ParseTree with - | Some input -> - let result = - AstTraversal.Traverse(pos, input, { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = - match expr with - | SynExpr.Typed (_expr, _typeExpr, range) when Pos.posEq range.Start pos -> - Some range - | _ -> defaultTraverse expr - - override _.VisitSimplePats(pats) = - match pats with - | [] -> None - | _ -> - let exprFunc pat = - match pat with - | SynSimplePat.Typed (_pat, _targetExpr, range) when Pos.posEq range.Start pos -> - Some range - | _ -> - None - - pats |> List.tryPick exprFunc - - override _.VisitPat(defaultTraverse, pat) = - match pat with - | SynPat.Typed (_pat, _targetType, range) when Pos.posEq range.Start pos -> - Some range - | _ -> defaultTraverse pat }) - result.IsSome - | None -> false + let result = + SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = + match expr with + | SynExpr.Typed (_expr, _typeExpr, range) when Position.posEq range.Start pos -> + Some range + | _ -> defaultTraverse expr + + override _.VisitSimplePats(_, pats) = + match pats with + | [] -> None + | _ -> + let exprFunc pat = + match pat with + | SynSimplePat.Typed (_pat, _targetExpr, range) when Position.posEq range.Start pos -> + Some range + | _ -> + None + + pats |> List.tryPick exprFunc + + override _.VisitPat(_, defaultTraverse, pat) = + match pat with + | SynPat.Typed (_pat, _targetType, range) when Position.posEq range.Start pos -> + Some range + | _ -> defaultTraverse pat }) + result.IsSome member scope.IsBindingALambdaAtPositionPatched pos = - match scope.ParseTree with - | Some input -> let result = - AstTraversal.Traverse(pos, input, { new AstTraversal.AstVisitorBase<_>() with + SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with member _.VisitExpr(_path, _traverseSynExpr, defaultTraverse, expr) = defaultTraverse expr - override _.VisitBinding(defaultTraverse, binding) = + override _.VisitBinding(_, defaultTraverse, binding) = match binding with - | SynBinding.Binding(_, _, _, _, _, _, _, _, _, expr, range, _) when Pos.posEq range.Start pos -> + | SynBinding(_, _, _, _, _, _, _, _, _, expr, range, _) when Position.posEq range.Start pos -> match expr with | SynExpr.Lambda _ -> Some range | _ -> None | _ -> defaultTraverse binding }) result.IsSome - | None -> false module SyntaxTreeOps = - open FSharp.Compiler.SyntaxTree + open FSharp.Compiler.Syntax let rec synExprContainsError inpExpr = - let rec walkBind (SynBinding.Binding(_, _, _, _, _, _, _, _, _, synExpr, _, _)) = walkExpr synExpr + let rec walkBind (SynBinding(_, _, _, _, _, _, _, _, _, synExpr, _, _)) = walkExpr synExpr and walkExprs es = es |> List.exists walkExpr and walkBinds es = es |> List.exists walkBind and walkMatchClauses cl = - cl |> List.exists (fun (SynMatchClause.Clause(_, whenExpr, e, _, _)) -> walkExprOpt whenExpr || walkExpr e) + cl |> List.exists (fun (SynMatchClause(_, whenExpr, _, e, _, _)) -> walkExprOpt whenExpr || walkExpr e) and walkExprOpt eOpt = eOpt |> Option.exists walkExpr @@ -414,8 +380,8 @@ module SyntaxTreeOps = | SynExpr.TypeTest (e, _, _) | SynExpr.Upcast (e, _, _) | SynExpr.AddressOf (_, e, _, _) - | SynExpr.CompExpr (_, _, e, _) - | SynExpr.ArrayOrListOfSeqExpr (_, e, _) + | SynExpr.ComputationExpr (_, e, _) + | SynExpr.ArrayOrListComputed (_, e, _) | SynExpr.Typed (e, _, _) | SynExpr.FromParseError (e, _) | SynExpr.Do (e, _) @@ -459,7 +425,7 @@ module SyntaxTreeOps = walkExprs flds | SynExpr.ObjExpr (_, _, bs, is, _, _) -> - walkBinds bs || walkBinds [ for (SynInterfaceImpl.InterfaceImpl(_, bs, _)) in is do yield! bs ] + walkBinds bs || walkBinds [ for (SynInterfaceImpl(_, bs, _)) in is do yield! bs ] | SynExpr.ForEach (_, _, _, _, e1, e2, _) | SynExpr.While (_, e1, e2, _) -> @@ -471,7 +437,7 @@ module SyntaxTreeOps = | SynExpr.MatchLambda (_, _, cl, _, _) -> walkMatchClauses cl - | SynExpr.Lambda (_, _, _, e, _, _) -> + | SynExpr.Lambda (_, _, _, _, e, _, _) -> walkExpr e | SynExpr.Match (_, e, cl, _) -> @@ -492,14 +458,14 @@ module SyntaxTreeOps = | SynExpr.SequentialOrImplicitYield (_, e1, e2, _, _) -> walkExpr e1 || walkExpr e2 - | SynExpr.IfThenElse (e1, e2, e3opt, _, _, _, _) -> + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3opt, _, _, _, _) -> walkExpr e1 || walkExpr e2 || walkExprOpt e3opt | SynExpr.DotIndexedGet (e1, es, _, _) -> - walkExpr e1 || walkExprs [ for e in es do yield! e.Exprs ] + walkExpr e1 || walkExpr es | SynExpr.DotIndexedSet (e1, es, e2, _, _, _) -> - walkExpr e1 || walkExprs [ for e in es do yield! e.Exprs ] || walkExpr e2 + walkExpr e1 || walkExpr es || walkExpr e2 | SynExpr.DotNamedIndexedPropertySet (e1, _, e2, e3, _) -> walkExpr e1 || walkExpr e2 || walkExpr e3 @@ -510,10 +476,15 @@ module SyntaxTreeOps = | SynExpr.LetOrUseBang (rhs = e1; body = e2; andBangs = es) -> walkExpr e1 || walkExprs [ for (_,_,_,_,e,_) in es do yield e ] || walkExpr e2 - | SynExpr.InterpolatedString (parts, _m) -> + | SynExpr.InterpolatedString (parts, _, _m) -> walkExprs (parts |> List.choose (function | SynInterpolatedStringPart.String _ -> None | SynInterpolatedStringPart.FillExpr (x, _) -> Some x)) + | SynExpr.IndexRange(expr1, opm, expr2, range1, range2, range3) -> + Option.map walkExpr expr1 + |> Option.orElseWith (fun _-> Option.map walkExpr expr2) + |> Option.defaultValue false + | SynExpr.IndexFromEnd(expr, range) -> walkExpr expr walkExpr inpExpr diff --git a/src/FsAutoComplete.Core/FileSystem.fs b/src/FsAutoComplete.Core/FileSystem.fs index 5347e7156..9ba987cdd 100644 --- a/src/FsAutoComplete.Core/FileSystem.fs +++ b/src/FsAutoComplete.Core/FileSystem.fs @@ -1,6 +1,6 @@ namespace FsAutoComplete -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open System open FsAutoComplete.Logging open FSharp.UMX @@ -13,13 +13,14 @@ type VolatileFile = Version: int option } open System.IO +open FSharp.Compiler.IO [] type SourceTextExtensions = [] static member GetText(t: ISourceText, m: FSharp.Compiler.Text.Range): Result = - let allFileRange = Range.mkRange m.FileName Pos.pos0 (t.GetLastFilePosition()) + let allFileRange = Range.mkRange m.FileName Position.pos0 (t.GetLastFilePosition()) if not (Range.rangeContainsRange allFileRange m) then Error $"%A{m} is outside of the bounds of the file" else @@ -47,9 +48,9 @@ type SourceTextExtensions = [] /// a safe alternative to GetLastCharacterPosition, which returns untagged indexes. this version /// returns a FCS Pos to prevent confusion about line index offsets - static member GetLastFilePosition(t: ISourceText): FSharp.Compiler.Text.Pos = + static member GetLastFilePosition(t: ISourceText): Position = let endLine, endChar = t.GetLastCharacterPosition() - Pos.mkPos endLine endChar + Position.mkPos endLine endChar type FileSystem (actualFs: IFileSystem, tryFindFile: string -> VolatileFile option) = let getContent (filename: string) = @@ -92,38 +93,26 @@ type FileSystem (actualFs: IFileSystem, tryFindFile: string -> Volati |> Path.FileUriToLocalPath fsLogger.debug (Log.setMessage "{path} expanded to {expanded}" >> Log.addContext "path" f >> Log.addContext "expanded" expanded) expanded + + member _.GetLastWriteTimeShim (f: string) = + f |> Utils.normalizePath |> tryFindFile |> Option.map (fun f -> f.Touched) |> Option.defaultValue DateTime.MinValue - (* These next members all make use of the VolatileFile concept, and so need to check that before delegating to the original FS implementation *) + member _.NormalizePathShim (f: string) = f |> Utils.normalizePath |> UMX.untag - (* Note that in addition to this behavior, we _also_ do not normalize the file paths anymore for any other members of this interfact, - because these members are always used by the compiler with paths returned from `GetFullPathShim`, which has done the normalization *) - - member _.ReadAllBytesShim (f) = - f - |> Utils.normalizePath - |> getContent - |> Option.defaultWith (fun _ -> actualFs.ReadAllBytesShim f) - - member _.FileStreamReadShim (f) = - f - |> Utils.normalizePath - |> getContent - |> Option.map (fun bytes -> new MemoryStream(bytes) :> Stream) - |> Option.defaultWith (fun _ -> actualFs.FileStreamReadShim f) - - member _.GetLastWriteTimeShim (f) = - f - |> Utils.normalizePath - |> tryFindFile - |> Option.map (fun f -> f.Touched) - |> Option.defaultWith (fun _ -> actualFs.GetLastWriteTimeShim f) - - member _.FileStreamCreateShim (f) = actualFs.FileStreamCreateShim f - member _.FileStreamWriteExistingShim (f) = actualFs.FileStreamWriteExistingShim f member _.IsInvalidPathShim (f) = actualFs.IsInvalidPathShim f member _.GetTempPathShim () = actualFs.GetTempPathShim() - member _.SafeExists (f) = actualFs.SafeExists f - member _.FileDelete (f) = actualFs.FileDelete f - member _.AssemblyLoadFrom (f) = actualFs.AssemblyLoadFrom f - member _.AssemblyLoad (f) = actualFs.AssemblyLoad f member _.IsStableFileHeuristic (f) = actualFs.IsStableFileHeuristic f + member _.CopyShim(src, dest, o) = actualFs.CopyShim(src, dest, o) + member _.DirectoryCreateShim p = actualFs.DirectoryCreateShim p + member _.DirectoryDeleteShim p = actualFs.DirectoryDeleteShim p + member _.DirectoryExistsShim p = actualFs.DirectoryExistsShim p + member _.EnumerateDirectoriesShim p = actualFs.EnumerateDirectoriesShim p + member _.EnumerateFilesShim (p, pat) = actualFs.EnumerateFilesShim(p, pat) + member _.FileDeleteShim f = actualFs.FileDeleteShim f + member _.FileExistsShim f = actualFs.FileExistsShim f + member _.GetCreationTimeShim p = actualFs.GetCreationTimeShim p + member _.GetDirectoryNameShim p = actualFs.GetDirectoryNameShim p + member _.GetFullFilePathInDirectoryShim dir f = actualFs.GetFullFilePathInDirectoryShim dir f + member _.OpenFileForReadShim (filePath:string, useMemoryMappedFile, shouldShadowCopy) = actualFs.OpenFileForReadShim(filePath, ?useMemoryMappedFile=useMemoryMappedFile, ?shouldShadowCopy=shouldShadowCopy) + member _.OpenFileForWriteShim (filePath:string, fileMode, fileAccess, fileShare) = actualFs.OpenFileForWriteShim(filePath, ?fileMode=fileMode, ?fileAccess=fileAccess, ?fileShare=fileShare) + member _.AssemblyLoader = actualFs.AssemblyLoader diff --git a/src/FsAutoComplete.Core/InterfaceStubGenerator.fs b/src/FsAutoComplete.Core/InterfaceStubGenerator.fs index 332aee0e9..ec371312a 100644 --- a/src/FsAutoComplete.Core/InterfaceStubGenerator.fs +++ b/src/FsAutoComplete.Core/InterfaceStubGenerator.fs @@ -2,10 +2,11 @@ module FsAutoComplete.InterfaceStubGenerator open System -open FSharp.Compiler.SyntaxTree +open FSharp.Compiler.Syntax open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Symbols open FsAutoComplete.CodeGenerationUtils +open FSharp.Compiler.Tokenization /// Capture information about an interface in ASTs [] @@ -37,9 +38,9 @@ let getMemberNameAndRanges = function | InterfaceData.ObjExpr(_, bindings) -> List.choose (|MemberNameAndRange|_|) bindings -let private walkTypeDefn pos (SynTypeDefn.TypeDefn(info, repr, members, range)) = - members - |>List.tryPick (fun m -> +let private walkTypeDefn pos (SynTypeDefn(info, repr, members, implicitCtor, range)) = + Option.toList implicitCtor @ members + |> List.tryPick (fun m -> if Range.rangeContainsPos m.Range pos then match m with @@ -50,9 +51,9 @@ let private walkTypeDefn pos (SynTypeDefn.TypeDefn(info, repr, members, range)) None ) -let tryFindInterfaceDeclAt (pos: Pos) (tree: ParsedInput) = - AstTraversal.Traverse(pos, tree, { - new AstTraversal.AstVisitorBase<_>() with +let tryFindInterfaceDeclAt (pos: Position) (tree: ParsedInput) = + SyntaxTraversal.Traverse(pos, tree, { + new SyntaxVisitorBase<_>() with member _.VisitExpr (_, _, defaultTraverse, expr) = match expr with SynExpr.ObjExpr(ty, baseCallOpt, binds, ifaces, _, _) -> @@ -62,27 +63,24 @@ let tryFindInterfaceDeclAt (pos: Pos) (tree: ParsedInput) = Some (InterfaceData.ObjExpr(ty, binds)) else ifaces - |> List.tryPick (fun (InterfaceImpl(ty, binds, range)) -> + |> List.tryPick (fun (SynInterfaceImpl(ty, binds, range)) -> if Range.rangeContainsPos range pos then Some (InterfaceData.ObjExpr(ty, binds)) else None ) | Some _ -> None | _ -> defaultTraverse expr - override _.VisitModuleDecl (defaultTraverse, decl) = + override _.VisitModuleDecl (_, defaultTraverse, decl) = match decl with | SynModuleDecl.Types(types, _) -> List.tryPick (walkTypeDefn pos) types | _ -> defaultTraverse decl }) -let tryFindInterfaceExprInBufferAtPos (codeGenService: CodeGenerationService) (pos: Pos) (document : Document) = +let tryFindInterfaceExprInBufferAtPos (codeGenService: CodeGenerationService) (pos: Position) (document : Document) = asyncMaybe { let! parseResults = codeGenService.ParseFileInProject(document.FullName) - - return! - parseResults.ParseTree - |> Option.bind (tryFindInterfaceDeclAt pos) + return! tryFindInterfaceDeclAt pos parseResults.ParseTree } /// Return the interface identifier @@ -108,7 +106,7 @@ let getInterfaceIdentifier (interfaceData : InterfaceData) (tokens : FSharpToken CodeGenerationUtils.findLastIdentifier tokens.[newKeywordIndex + 2..] tokens.[newKeywordIndex + 2] /// Try to find the start column, so we know what the base indentation should be -let inferStartColumn (codeGenServer : CodeGenerationService) (pos : Pos) (doc : Document) (lines: ISourceText) (lineStr : string) (interfaceData : InterfaceData) (indentSize : int) = +let inferStartColumn (codeGenServer : CodeGenerationService) (pos : Position) (doc : Document) (lines: ISourceText) (lineStr : string) (interfaceData : InterfaceData) (indentSize : int) = match getMemberNameAndRanges interfaceData with | (_, range) :: _ -> getLineIdent (lines.GetLineString(range.StartLine - 1)) @@ -134,7 +132,7 @@ let inferStartColumn (codeGenServer : CodeGenerationService) (pos : Pos) (doc : /// Return None, if we failed to handle the interface implementation /// Return Some (insertPosition, generatedString): /// `insertPosition`: representation the position where the editor should insert the `generatedString` -let handleImplementInterface (codeGenServer : CodeGenerationService) (checkResultForFile: ParseAndCheckResults) (pos : Pos) (doc : Document) (lines: ISourceText) (lineStr : string) (interfaceData : InterfaceData) = +let handleImplementInterface (codeGenServer : CodeGenerationService) (checkResultForFile: ParseAndCheckResults) (pos : Position) (doc : Document) (lines: ISourceText) (lineStr : string) (interfaceData : InterfaceData) = async { let! result = asyncMaybe { let! _symbol, symbolUse = codeGenServer.GetSymbolAndUseAtPositionOfKind(doc.FullName, pos, SymbolKind.Ident) @@ -159,7 +157,7 @@ let handleImplementInterface (codeGenServer : CodeGenerationService) (checkResul | Some (interfaceData, displayContext, entity) -> let getMemberByLocation (name, range: Range) = asyncMaybe { - let pos = Pos.fromZ (range.StartLine - 1) (range.StartColumn + 1) + let pos = Position.fromZ (range.StartLine - 1) (range.StartColumn + 1) return! checkResultForFile.GetCheckResults.GetSymbolUseAtLocation (pos.Line, pos.Column, lineStr, []) } diff --git a/src/FsAutoComplete.Core/KeywordList.fs b/src/FsAutoComplete.Core/KeywordList.fs index ebde1c4a5..817ecd3d8 100644 --- a/src/FsAutoComplete.Core/KeywordList.fs +++ b/src/FsAutoComplete.Core/KeywordList.fs @@ -1,7 +1,10 @@ namespace FsAutoComplete open LanguageServerProtocol.Types -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Text +open FSharp.Compiler.Tokenization +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols module KeywordList = @@ -14,8 +17,9 @@ module KeywordList = |> Seq.map (fun kv -> let lines = kv.Value.Replace("\r\n", "\n").Split('\n') let allLines = Array.concat [| [|""|]; lines; [| "" |] |] - let tip = FSharpToolTipText [FSharpToolTipElement.Single(kv.Key, FSharpXmlDoc.Text (allLines, allLines))] - kv.Key, tip) + let tip = ToolTipText [ToolTipElement.Single([| TaggedText.tagText kv.Key |], FSharpXmlDoc.FromXmlText (FSharp.Compiler.Xml.XmlDoc(allLines, Range.Zero))) ] + kv.Key, tip + ) |> dict let hashDirectives = diff --git a/src/FsAutoComplete.Core/Lexer.fs b/src/FsAutoComplete.Core/Lexer.fs index 97ab1987e..8f8ec9e82 100644 --- a/src/FsAutoComplete.Core/Lexer.fs +++ b/src/FsAutoComplete.Core/Lexer.fs @@ -1,6 +1,6 @@ namespace FsAutoComplete -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Tokenization type SymbolKind = | Ident diff --git a/src/FsAutoComplete.Core/ParseAndCheckResults.fs b/src/FsAutoComplete.Core/ParseAndCheckResults.fs index dec0008c8..702f22ce2 100644 --- a/src/FsAutoComplete.Core/ParseAndCheckResults.fs +++ b/src/FsAutoComplete.Core/ParseAndCheckResults.fs @@ -1,19 +1,24 @@ namespace FsAutoComplete -open System -open System.IO -open FSharp.Compiler.SourceCodeServices -open Utils -open FSharp.Compiler.Text -open FSharp.Compiler open FsAutoComplete.Logging open FsAutoComplete.UntypedAstUtils +open FSharp.Compiler +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Text +open FSharp.Compiler.Symbols +open FSharp.Compiler.CodeAnalysis open FSharp.UMX +open System +open System.IO +open Utils +open FSharp.Compiler.Tokenization +open FSharp.Compiler.Syntax [] type FindDeclarationResult = | ExternalDeclaration of Decompiler.ExternalContentPosition - | Range of Range + | Range of FSharp.Compiler.Text.Range /// The declaration refers to a file. | File of string @@ -26,7 +31,7 @@ type ParseAndCheckResults let logger = LogProvider.getLoggerByName "ParseAndCheckResults" - member __.TryFindDeclaration (pos: Pos) (lineStr: LineStr) = + member __.TryFindDeclaration (pos: Position) (lineStr: LineStr) = async { // try find identifier first let! identResult = __.TryFindIdentifierDeclaration pos lineStr @@ -42,7 +47,7 @@ type ParseAndCheckResults | Error _ -> return Error identErr } - member __.TryFindLoadDirectiveSource (pos: Pos) (lineStr: LineStr) = + member __.TryFindLoadDirectiveSource (pos: Position) (lineStr: LineStr) = async { let tryGetFullPath fileName = try @@ -63,7 +68,7 @@ type ParseAndCheckResults | None -> return Error "load directive not recognized" } - member __.TryFindIdentifierDeclaration (pos: Pos) (lineStr: LineStr) = + member __.TryFindIdentifierDeclaration (pos: Position) (lineStr: LineStr) = match Lexer.findLongIdents (pos.Column, lineStr) with | None -> async.Return(ResultOrString.Error "Could not find ident at this location") | Some (col, identIsland) -> @@ -85,19 +90,19 @@ type ParseAndCheckResults ) /// these are all None because you can't easily get the source file from the external symbol information here. - let tryGetSourceRangeForSymbol (sym: FSharpExternalSymbol) : (string * Pos) option = + let tryGetSourceRangeForSymbol (sym: FindDeclExternalSymbol) : (string * Position) option = match sym with - | FSharpExternalSymbol.Type name -> None - | FSharpExternalSymbol.Constructor (typeName, args) -> None - | FSharpExternalSymbol.Method (typeName, name, paramSyms, genericArity) -> None - | FSharpExternalSymbol.Field (typeName, name) -> None - | FSharpExternalSymbol.Event (typeName, name) -> None - | FSharpExternalSymbol.Property (typeName, name) -> None + | FindDeclExternalSymbol.Type name -> None + | FindDeclExternalSymbol.Constructor (typeName, args) -> None + | FindDeclExternalSymbol.Method (typeName, name, paramSyms, genericArity) -> None + | FindDeclExternalSymbol.Field (typeName, name) -> None + | FindDeclExternalSymbol.Event (typeName, name) -> None + | FindDeclExternalSymbol.Property (typeName, name) -> None // attempts to manually discover symbol use and externalsymbol information for a range that doesn't exist in a local file // bugfix/workaround for FCS returning invalid declfound for f# members. let tryRecoverExternalSymbolForNonexistentDecl - (rangeInNonexistentFile: Range) + (rangeInNonexistentFile: FSharp.Compiler.Text.Range) : ResultOrString * string> = match Lexer.findLongIdents (pos.Column - 1, lineStr) with | None -> @@ -127,20 +132,20 @@ type ParseAndCheckResults async { match declarations with - | FSharpFindDeclResult.DeclNotFound reason -> + | FindDeclResult.DeclNotFound reason -> let elaboration = match reason with - | FSharpFindDeclFailureReason.NoSourceCode -> "No source code was found for the declaration" - | FSharpFindDeclFailureReason.ProvidedMember m -> + | FindDeclFailureReason.NoSourceCode -> "No source code was found for the declaration" + | FindDeclFailureReason.ProvidedMember m -> sprintf "Go-to-declaration is not available for Type Provider-provided member %s" m - | FSharpFindDeclFailureReason.ProvidedType t -> + | FindDeclFailureReason.ProvidedType t -> sprintf "Go-to-declaration is not available from Type Provider-provided type %s" t - | FSharpFindDeclFailureReason.Unknown r -> r + | FindDeclFailureReason.Unknown r -> r return ResultOrString.Error(sprintf "Could not find declaration. %s" elaboration) - | FSharpFindDeclResult.DeclFound range when range.FileName.EndsWith(Range.rangeStartup.FileName) -> + | FindDeclResult.DeclFound range when range.FileName.EndsWith(Range.rangeStartup.FileName) -> return ResultOrString.Error "Could not find declaration" - | FSharpFindDeclResult.DeclFound range when System.IO.File.Exists range.FileName -> + | FindDeclResult.DeclFound range when System.IO.File.Exists range.FileName -> let rangeStr = range.ToString() logger.info ( @@ -149,7 +154,7 @@ type ParseAndCheckResults ) return Ok(FindDeclarationResult.Range range) - | FSharpFindDeclResult.DeclFound rangeInNonexistentFile -> + | FindDeclResult.DeclFound rangeInNonexistentFile -> let range = rangeInNonexistentFile.ToString() logger.warn ( @@ -169,7 +174,7 @@ type ParseAndCheckResults ) | Error reason -> return ResultOrString.Error(sprintf "%A" reason) | Error e -> return Error e - | FSharpFindDeclResult.ExternalDecl (assembly, externalSym) -> + | FindDeclResult.ExternalDecl (assembly, externalSym) -> // not enough info on external symbols to get a range-like thing :( match tryGetSourceRangeForSymbol externalSym with | Some (sourceFile, pos) -> @@ -191,7 +196,7 @@ type ParseAndCheckResults | None -> return decompile assembly externalSym } - member __.TryFindTypeDeclaration (pos: Pos) (lineStr: LineStr) = + member __.TryFindTypeDeclaration (pos: Position) (lineStr: LineStr) = async { match Lexer.findLongIdents (pos.Column, lineStr) with | None -> return Error "Cannot find ident at this location" @@ -241,7 +246,7 @@ type ParseAndCheckResults async { match ty.TryFullName with | Some fullName -> - let externalSym = FSharpExternalSymbol.Type fullName + let externalSym = FindDeclExternalSymbol.Type fullName // from TryFindIdentifierDeclaration let decompile assembly externalSym = match Decompiler.tryFindExternalDeclaration checkResults (assembly, externalSym) with @@ -288,19 +293,19 @@ type ParseAndCheckResults return! tryGetSource ty } - member __.TryGetToolTip (pos: Pos) (lineStr: LineStr) = + member __.TryGetToolTip (pos: Position) (lineStr: LineStr) = match Lexer.findLongIdents (pos.Column, lineStr) with | None -> ResultOrString.Error "Cannot find ident for tooltip" | Some (col, identIsland) -> let identIsland = Array.toList identIsland // TODO: Display other tooltip types, for example for strings or comments where appropriate let tip = - checkResults.GetToolTipText(pos.Line, col, lineStr, identIsland, FSharpTokenTag.Identifier) + checkResults.GetToolTip(pos.Line, col, lineStr, identIsland, FSharpTokenTag.Identifier) match tip with - | FSharpToolTipText (elems) when + | ToolTipText (elems) when elems - |> List.forall ((=) FSharpToolTipElement.None) + |> List.forall ((=) ToolTipElement.None) -> match identIsland with | [ ident ] -> @@ -310,64 +315,60 @@ type ParseAndCheckResults | _ -> ResultOrString.Error "No tooltip information" | _ -> Ok(tip) - member x.TryGetToolTipEnhanced (pos: Pos) (lineStr: LineStr) = - match x.GetParseResults.ParseTree with - | None -> Error "No parse tree" - | Some parsedInput -> - match Completion.atPos (pos, parsedInput) with - | Completion.Context.StringLiteral -> Ok None - | Completion.Context.Unknown -> - match Lexer.findLongIdents (pos.Column, lineStr) with - | None -> Error "Cannot find ident for tooltip" - | Some (col, identIsland) -> - let identIsland = Array.toList identIsland - // TODO: Display other tooltip types, for example for strings or comments where appropriate - let tip = - checkResults.GetToolTipText(pos.Line, col, lineStr, identIsland, FSharpTokenTag.Identifier) - - let symbol = checkResults.GetSymbolUseAtLocation(pos.Line, col, lineStr, identIsland) - - match tip with - | FSharpToolTipText (elems) when - elems - |> List.forall ((=) FSharpToolTipElement.None) - && symbol.IsNone - -> - match identIsland with - | [ ident ] -> - match KeywordList.keywordTooltips.TryGetValue ident with - | true, tip -> Ok(Some(tip, ident, "", None)) - | _ -> Error "No tooltip information" + member x.TryGetToolTipEnhanced (pos: Position) (lineStr: LineStr) = + match Completion.atPos (pos, x.GetParseResults.ParseTree) with + | Completion.Context.StringLiteral -> Ok None + | Completion.Context.Unknown -> + match Lexer.findLongIdents (pos.Column, lineStr) with + | None -> Error "Cannot find ident for tooltip" + | Some (col, identIsland) -> + let identIsland = Array.toList identIsland + // TODO: Display other tooltip types, for example for strings or comments where appropriate + let tip = + checkResults.GetToolTip(pos.Line, col, lineStr, identIsland, FSharpTokenTag.Identifier) + + let symbol = checkResults.GetSymbolUseAtLocation(pos.Line, col, lineStr, identIsland) + + match tip with + | ToolTipText (elems) when + elems + |> List.forall ((=) ToolTipElement.None) + && symbol.IsNone + -> + match identIsland with + | [ ident ] -> + match KeywordList.keywordTooltips.TryGetValue ident with + | true, tip -> Ok(Some(tip, ident, "", None)) | _ -> Error "No tooltip information" - | _ -> - match symbol with - | None -> Error "No tooltip information" - | Some symbol -> + | _ -> Error "No tooltip information" + | _ -> + match symbol with + | None -> Error "No tooltip information" + | Some symbol -> - match SignatureFormatter.getTooltipDetailsFromSymbolUse symbol with - | None -> Error "No tooltip information" - | Some (signature, footer) -> - let typeDoc = - getTypeIfConstructor symbol.Symbol - |> Option.map (fun n -> n.XmlDocSig) + match SignatureFormatter.getTooltipDetailsFromSymbolUse symbol with + | None -> Error "No tooltip information" + | Some (signature, footer) -> + let typeDoc = + getTypeIfConstructor symbol.Symbol + |> Option.map (fun n -> n.XmlDocSig) - Ok(Some(tip, signature, footer, typeDoc)) + Ok(Some(tip, signature, footer, typeDoc)) - member __.TryGetFormattedDocumentation (pos: Pos) (lineStr: LineStr) = + member __.TryGetFormattedDocumentation (pos: Position) (lineStr: LineStr) = match Lexer.findLongIdents (pos.Column - 1, lineStr) with | None -> Error "Cannot find ident" | Some (col, identIsland) -> let identIsland = Array.toList identIsland // TODO: Display other tooltip types, for example for strings or comments where appropriate - let tip = - checkResults.GetToolTipText(pos.Line, col, lineStr, identIsland, FSharpTokenTag.Identifier) + let tip = checkResults.GetToolTip(pos.Line, col, lineStr, identIsland, FSharpTokenTag.Identifier) let symbol = checkResults.GetSymbolUseAtLocation(pos.Line, col, lineStr, identIsland) match tip with - | FSharpToolTipText (elems) when + | ToolTipText (elems) when elems - |> List.forall ((=) FSharpToolTipElement.None) + |> List.forall ((=) ToolTipElement.None) && symbol.IsNone -> match identIsland with @@ -461,20 +462,20 @@ type ParseAndCheckResults Ok( symbol.XmlDocSig, symbol.Assembly.FileName |> Option.defaultValue "", - symbol.XmlDoc |> Seq.toList, + symbol.XmlDoc, signature, footer, cn ) - member __.TryGetSymbolUse (pos: Pos) (lineStr: LineStr) : FSharpSymbolUse option = + member __.TryGetSymbolUse (pos: Position) (lineStr: LineStr) : FSharpSymbolUse option = match Lexer.findLongIdents (pos.Column, lineStr) with | None -> None | Some (colu, identIsland) -> let identIsland = Array.toList identIsland checkResults.GetSymbolUseAtLocation(pos.Line, colu, lineStr, identIsland) - member x.TryGetSymbolUseAndUsages (pos: Pos) (lineStr: LineStr) = + member x.TryGetSymbolUseAndUsages (pos: Position) (lineStr: LineStr) = let symboluse = x.TryGetSymbolUse pos lineStr match symboluse with @@ -483,7 +484,7 @@ type ParseAndCheckResults let symboluses = checkResults.GetUsesOfSymbolInFile symboluse.Symbol Ok(symboluse, symboluses) - member __.TryGetSignatureData (pos: Pos) (lineStr: LineStr) = + member __.TryGetSignatureData (pos: Position) (lineStr: LineStr) = match Lexer.findLongIdents (pos.Column - 1, lineStr) with | None -> ResultOrString.Error "No ident at this location" | Some (colu, identIsland) -> @@ -530,7 +531,7 @@ type ParseAndCheckResults Ok(typ, [], []) | _ -> ResultOrString.Error "Not a member, function or value" - member __.TryGetF1Help (pos: Pos) (lineStr: LineStr) = + member __.TryGetF1Help (pos: Position) (lineStr: LineStr) = match Lexer.findLongIdents (pos.Column - 1, lineStr) with | None -> ResultOrString.Error "No ident at this location" | Some (colu, identIsland) -> @@ -542,119 +543,116 @@ type ParseAndCheckResults | None -> ResultOrString.Error "No symbol information found" | Some hlp -> Ok hlp - member x.TryGetCompletions (pos: Pos) (lineStr: LineStr) filter (getAllSymbols: unit -> AssemblySymbol list) = + member x.TryGetCompletions (pos: Position) (lineStr: LineStr) filter (getAllSymbols: unit -> AssemblySymbol list) = async { - match x.GetParseResults.ParseTree with - | None -> return None - | Some parsedInput -> - match Completion.atPos (pos, parsedInput) with - | Completion.Context.StringLiteral -> return None - | Completion.Context.Unknown -> - try - let longName = - FSharp.Compiler.SourceCodeServices.QuickParse.GetPartialLongNameEx(lineStr, pos.Column - 1) - - let residue = longName.PartialIdent - - logger.info ( - Log.setMessage "TryGetCompletions - long name: {longName}" - >> Log.addContextDestructured "longName" longName - ) + match Completion.atPos (pos, x.GetParseResults.ParseTree) with + | Completion.Context.StringLiteral -> return None + | Completion.Context.Unknown -> + try + let longName = + QuickParse.GetPartialLongNameEx(lineStr, pos.Column - 1) - let getAllSymbols () = - getAllSymbols () - |> List.filter (fun entity -> - entity.FullName.Contains "." - && not (PrettyNaming.IsOperatorName entity.Symbol.DisplayName)) + let residue = longName.PartialIdent - let token = Lexer.getSymbol pos.Line (pos.Column - 1) lineStr SymbolLookupKind.Simple [||] + logger.info ( + Log.setMessage "TryGetCompletions - long name: {longName}" + >> Log.addContextDestructured "longName" longName + ) - logger.info ( - Log.setMessage "TryGetCompletions - token: {token}" - >> Log.addContextDestructured "token" token - ) + let getAllSymbols () = + getAllSymbols () + |> List.filter (fun entity -> + entity.FullName.Contains "." + && not (PrettyNaming.IsOperatorDisplayName entity.Symbol.DisplayName)) - let isEmpty = - longName.QualifyingIdents.IsEmpty - && String.IsNullOrWhiteSpace longName.PartialIdent - && longName.LastDotPos.IsNone - - match token with - | Some k when k.Kind = Other && not isEmpty -> return None - | Some k when k.Kind = Operator -> return None - | Some k when k.Kind = Keyword -> return None - | _ -> - - let results = - checkResults.GetDeclarationListInfo(Some parseResults, pos.Line, lineStr, longName, getAllSymbols) - - let getKindPriority = - function - | FSharpCompletionItemKind.CustomOperation -> -1 - | FSharpCompletionItemKind.Property -> 0 - | FSharpCompletionItemKind.Field -> 1 - | FSharpCompletionItemKind.Method(isExtension = false) -> 2 - | FSharpCompletionItemKind.Event -> 3 - | FSharpCompletionItemKind.Argument -> 4 - | FSharpCompletionItemKind.Other -> 5 - | FSharpCompletionItemKind.Method(isExtension = true) -> 6 - - let decls = - match filter with - | Some "StartsWith" -> - results.Items - |> Array.filter (fun d -> d.Name.StartsWith(residue, StringComparison.InvariantCultureIgnoreCase)) - | Some "Contains" -> - results.Items - |> Array.filter (fun d -> - d.Name.IndexOf(residue, StringComparison.InvariantCultureIgnoreCase) - >= 0) - | _ -> results.Items - - let sortedDecls = - decls - |> Array.sortWith (fun x y -> - let transformKind (item: FSharpDeclarationListItem) = - if item.Kind = FSharpCompletionItemKind.Field - && item.Glyph = FSharpGlyph.Method then - FSharpCompletionItemKind.Method false - elif item.Kind = FSharpCompletionItemKind.Argument - && item.Glyph = FSharpGlyph.Property then - FSharpCompletionItemKind.Property - else - item.Kind + let token = Lexer.getSymbol pos.Line (pos.Column - 1) lineStr SymbolLookupKind.Simple [||] - let mutable n = (not x.IsResolved).CompareTo(not y.IsResolved) + logger.info ( + Log.setMessage "TryGetCompletions - token: {token}" + >> Log.addContextDestructured "token" token + ) + + let isEmpty = + longName.QualifyingIdents.IsEmpty + && String.IsNullOrWhiteSpace longName.PartialIdent + && longName.LastDotPos.IsNone + + match token with + | Some k when k.Kind = Other && not isEmpty -> return None + | Some k when k.Kind = Operator -> return None + | Some k when k.Kind = Keyword -> return None + | _ -> + + let results = + checkResults.GetDeclarationListInfo(Some parseResults, pos.Line, lineStr, longName, getAllSymbols) + + let getKindPriority = + function + | CompletionItemKind.CustomOperation -> -1 + | CompletionItemKind.Property -> 0 + | CompletionItemKind.Field -> 1 + | CompletionItemKind.Method(isExtension = false) -> 2 + | CompletionItemKind.Event -> 3 + | CompletionItemKind.Argument -> 4 + | CompletionItemKind.Other -> 5 + | CompletionItemKind.Method(isExtension = true) -> 6 + + let decls = + match filter with + | Some "StartsWith" -> + results.Items + |> Array.filter (fun d -> d.Name.StartsWith(residue, StringComparison.InvariantCultureIgnoreCase)) + | Some "Contains" -> + results.Items + |> Array.filter (fun d -> + d.Name.IndexOf(residue, StringComparison.InvariantCultureIgnoreCase) + >= 0) + | _ -> results.Items + + let sortedDecls = + decls + |> Array.sortWith (fun x y -> + let transformKind (item: DeclarationListItem) = + if item.Kind = CompletionItemKind.Field + && item.Glyph = FSharpGlyph.Method then + CompletionItemKind.Method false + elif item.Kind = CompletionItemKind.Argument + && item.Glyph = FSharpGlyph.Property then + CompletionItemKind.Property + else + item.Kind + + let mutable n = (not x.IsResolved).CompareTo(not y.IsResolved) + + if n <> 0 then + n + else + n <- + (getKindPriority <| transformKind x) + .CompareTo(getKindPriority <| transformKind y) if n <> 0 then n else - n <- - (getKindPriority <| transformKind x) - .CompareTo(getKindPriority <| transformKind y) + n <- (not x.IsOwnMember).CompareTo(not y.IsOwnMember) if n <> 0 then n else - n <- (not x.IsOwnMember).CompareTo(not y.IsOwnMember) + n <- StringComparer.OrdinalIgnoreCase.Compare(x.Name, y.Name) if n <> 0 then n else - n <- StringComparer.OrdinalIgnoreCase.Compare(x.Name, y.Name) - - if n <> 0 then - n - else - x.MinorPriority.CompareTo(y.MinorPriority)) + x.MinorPriority.CompareTo(y.MinorPriority)) - let shouldKeywords = - sortedDecls.Length > 0 - && not results.IsForType - && not results.IsError - && List.isEmpty longName.QualifyingIdents + let shouldKeywords = + sortedDecls.Length > 0 + && not results.IsForType + && not results.IsError + && List.isEmpty longName.QualifyingIdents - return Some(sortedDecls, residue, shouldKeywords) + return Some(sortedDecls, residue, shouldKeywords) with | :? TimeoutException -> return None } @@ -663,7 +661,7 @@ type ParseAndCheckResults try let res = [ yield! - AssemblyContentProvider.getAssemblySignatureContent + AssemblyContent.GetAssemblySignatureContent AssemblyContentType.Full checkResults.PartialAssemblySignature let ctx = checkResults.ProjectContext @@ -675,10 +673,10 @@ type ParseAndCheckResults // get Content.Entities from it. for fileName, signatures in assembliesByFileName do - let contentType = if publicOnly then Public else Full + let contentType = if publicOnly then AssemblyContentType.Public else AssemblyContentType.Full let content = - AssemblyContentProvider.getAssemblyContent entityCache.Locking contentType fileName signatures + AssemblyContent.GetAssemblyContent entityCache.Locking contentType fileName signatures yield! content ] @@ -690,11 +688,11 @@ type ParseAndCheckResults member __.GetSemanticClassification = checkResults.GetSemanticClassification None - // member this.GetExpandedType (pos: Pos) = + // member this.GetExpandedType (pos: Position) = // match parseResults.ParseTree with // | Some input -> - // AstTraversal.Traverse(pos, input, { - // new AstTraversal.AstVisitorBase<_>() with + // SyntaxTraversal.Traverse(pos, input, { + // new SyntaxVisitorBase<_>() with // }) // | None -> None diff --git a/src/FsAutoComplete.Core/RecordStubGenerator.fs b/src/FsAutoComplete.Core/RecordStubGenerator.fs index 4bf401840..afdfdafe1 100644 --- a/src/FsAutoComplete.Core/RecordStubGenerator.fs +++ b/src/FsAutoComplete.Core/RecordStubGenerator.fs @@ -2,11 +2,11 @@ module FsAutoComplete.RecordStubGenerator open FsAutoComplete.UntypedAstUtils -open FSharp.Compiler.SyntaxTree +open FSharp.Compiler.Syntax open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices open System.Diagnostics open FsAutoComplete.CodeGenerationUtils +open FSharp.Compiler.Symbols // Algorithm // [x] Make sure '}' is the last token of the expression @@ -35,7 +35,7 @@ type PositionKind = type RecordStubsInsertionParams = { Kind: PositionKind - InsertionPos: Pos + InsertionPos: Position IndentColumn: int } static member TryCreateFromRecordExpression (expr: RecordExpr) = @@ -44,7 +44,7 @@ type RecordStubsInsertionParams = match expr.CopyExprOption with | None -> let exprRange = expr.Expr.Range - let pos = Pos.fromZ (exprRange.StartLine - 1) (exprRange.StartColumn + 1) + let pos = Position.fromZ (exprRange.StartLine - 1) (exprRange.StartColumn + 1) { Kind = PositionKind.AfterLeftBrace IndentColumn = pos.Column + 1 InsertionPos = pos } @@ -187,7 +187,7 @@ let formatRecord (insertionPos: RecordStubsInsertionParams) (fieldDefaultValue: writer.Dump() -let private tryFindRecordBindingInParsedInput (pos: Pos) (parsedInput: ParsedInput) = +let private tryFindRecordBindingInParsedInput (pos: Position) (parsedInput: ParsedInput) = let inline getIfPosInRange range f = if Range.rangeContainsPos range pos then f() else None @@ -223,9 +223,10 @@ let private tryFindRecordBindingInParsedInput (pos: Pos) (parsedInput: ParsedInp None ) - and walkSynTypeDefn(TypeDefn(_componentInfo, representation, members, range)) = + and walkSynTypeDefn(SynTypeDefn(_componentInfo, representation, members, implicitCtor, range)) = getIfPosInRange range (fun () -> walkSynTypeDefnRepr representation + |> Option.orElseWith (fun _ -> Option.bind walkSynMemberDefn implicitCtor) |> Option.orElseWith (fun _ -> List.tryPick walkSynMemberDefn members) ) @@ -262,8 +263,8 @@ let private tryFindRecordBindingInParsedInput (pos: Pos) (parsedInput: ParsedInp None ) - and walkBinding (Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, _headPat, retTy, expr, _bindingRange, _seqPoint) as binding) = - getIfPosInRange binding.RangeOfBindingAndRhs (fun () -> + and walkBinding (SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, _headPat, retTy, expr, _bindingRange, _seqPoint) as binding) = + getIfPosInRange binding.RangeOfBindingWithRhs (fun () -> match retTy with | Some(SynBindingReturnInfo(_ty, _range, _attributes)) -> match expr with @@ -332,9 +333,9 @@ let private tryFindRecordBindingInParsedInput (pos: Pos) (parsedInput: ParsedInp | SynExpr.Paren(synExpr, _, _, _) | SynExpr.New(_, _, synExpr, _) - | SynExpr.ArrayOrListOfSeqExpr(_, synExpr, _) - | SynExpr.CompExpr(_, _, synExpr, _) - | SynExpr.Lambda(_, _, _, synExpr, _, _) + | SynExpr.ArrayOrListComputed(_, synExpr, _) + | SynExpr.ComputationExpr(_, synExpr, _) + | SynExpr.Lambda(_, _, _, _, synExpr, _, _) | SynExpr.Lazy(synExpr, _) | SynExpr.Do(synExpr, _) | SynExpr.Assert(synExpr, _) -> @@ -368,10 +369,10 @@ let private tryFindRecordBindingInParsedInput (pos: Pos) (parsedInput: ParsedInp List.tryPick walkExpr [synExpr1; synExpr2; synExpr3] | SynExpr.MatchLambda(_isExnMatch, _argm, synMatchClauseList, _spBind, _wholem) -> - synMatchClauseList |> List.tryPick (fun (Clause(_, _, e, _, _)) -> walkExpr e) + synMatchClauseList |> List.tryPick (fun (SynMatchClause(_, _, _, e, _, _)) -> walkExpr e) | SynExpr.Match(_sequencePointInfoForBinding, synExpr, synMatchClauseList, _range) -> walkExpr synExpr - |> Option.orElseWith (fun _ -> synMatchClauseList |> List.tryPick (fun (Clause(_, _, e, _, _)) -> walkExpr e)) + |> Option.orElseWith (fun _ -> synMatchClauseList |> List.tryPick (fun (SynMatchClause(_, _, _, e, _, _)) -> walkExpr e)) | SynExpr.App(_exprAtomicFlag, _isInfix, synExpr1, synExpr2, _range) -> List.tryPick walkExpr [synExpr1; synExpr2] @@ -392,7 +393,7 @@ let private tryFindRecordBindingInParsedInput (pos: Pos) (parsedInput: ParsedInp | Sequentials exprs -> List.tryPick walkExpr exprs - | SynExpr.IfThenElse(synExpr1, synExpr2, synExprOpt, _sequencePointInfoForBinding, _isRecovery, _range, _range2) -> + | SynExpr.IfThenElse(_, _, synExpr1, _, synExpr2, _, synExprOpt, _sequencePointInfoForBinding, _isRecovery, _range, _range2) -> match synExprOpt with | Some synExpr3 -> List.tryPick walkExpr [synExpr1; synExpr2; synExpr3] @@ -412,16 +413,14 @@ let private tryFindRecordBindingInParsedInput (pos: Pos) (parsedInput: ParsedInp | SynExpr.DotSet(synExpr1, _longIdent, synExpr2, _range) -> List.tryPick walkExpr [synExpr1; synExpr2] - | SynExpr.DotIndexedGet(synExpr, IndexerArgList synExprList, _range, _range2) -> - synExprList - |> List.map fst - |> List.tryPick walkExpr + | SynExpr.DotIndexedGet(synExpr, argList, _range, _range2) -> + walkExpr argList |> Option.orElseWith (fun _ -> walkExpr synExpr) - | SynExpr.DotIndexedSet(synExpr1, IndexerArgList synExprList, synExpr2, _, _range, _range2) -> - [ yield synExpr1 - yield! synExprList |> List.map fst - yield synExpr2 ] + | SynExpr.DotIndexedSet(synExpr1, argList, synExpr2, _, _range, _range2) -> + [ synExpr1 + argList + synExpr2 ] |> List.tryPick walkExpr | SynExpr.JoinIn(synExpr1, _range, synExpr2, _range2) -> @@ -478,20 +477,19 @@ let private tryFindRecordBindingInParsedInput (pos: Pos) (parsedInput: ParsedInp | Some synExpr when Range.rangeContainsPos synExpr.Range pos -> walkExpr synExpr | _ -> None - and walkSynInterfaceImpl (InterfaceImpl(_synType, synBindings, _range)) = + and walkSynInterfaceImpl (SynInterfaceImpl(_synType, synBindings, _range)) = List.tryPick walkBinding synBindings match parsedInput with | ParsedInput.SigFile _input -> None | ParsedInput.ImplFile input -> walkImplFileInput input -let tryFindRecordExprInBufferAtPos (codeGenService: CodeGenerationService) (pos: Pos) (document : Document) = +let tryFindRecordExprInBufferAtPos (codeGenService: CodeGenerationService) (pos: Position) (document : Document) = asyncMaybe { let! parseResults = codeGenService.ParseFileInProject(document.FullName) return! - parseResults.ParseTree - |> Option.bind (tryFindRecordBindingInParsedInput pos) + tryFindRecordBindingInParsedInput pos parseResults.ParseTree } let checkThatRecordExprEndsWithRBrace (codeGenService: CodeGenerationService) (document : Document) (expr: RecordExpr) = @@ -523,7 +521,7 @@ let checkThatRecordExprEndsWithRBrace (codeGenService: CodeGenerationService) (d } |> Option.isSome -let tryFindStubInsertionParamsAtPos (codeGenService: CodeGenerationService) (pos: Pos) (document : Document) = +let tryFindStubInsertionParamsAtPos (codeGenService: CodeGenerationService) (pos: Position) (document : Document) = asyncMaybe { let! recordExpression = tryFindRecordExprInBufferAtPos codeGenService pos document if checkThatRecordExprEndsWithRBrace codeGenService document recordExpression then @@ -539,7 +537,7 @@ let shouldGenerateRecordStub (recordExpr: RecordExpr) (entity: FSharpEntity) = let writtenFieldCount = recordExpr.FieldExprList.Length fieldCount > 0 && writtenFieldCount < fieldCount -let tryFindRecordDefinitionFromPos (codeGenService: CodeGenerationService) (pos: Pos) (document : Document) = +let tryFindRecordDefinitionFromPos (codeGenService: CodeGenerationService) (pos: Position) (document : Document) = asyncMaybe { let! recordExpression, insertionPos = tryFindStubInsertionParamsAtPos codeGenService pos document diff --git a/src/FsAutoComplete.Core/SignatureFormatter.fs b/src/FsAutoComplete.Core/SignatureFormatter.fs index a88475560..b6b9b1857 100644 --- a/src/FsAutoComplete.Core/SignatureFormatter.fs +++ b/src/FsAutoComplete.Core/SignatureFormatter.fs @@ -1,14 +1,15 @@ namespace FsAutoComplete -open UntypedAstUtils [] module PrintParameter = let print sb = Printf.bprintf sb "%s" module SignatureFormatter = - open FSharp.Compiler - open FSharp.Compiler.SourceCodeServices + open FSharp.Compiler.CodeAnalysis + open FSharp.Compiler.Symbols + open FSharp.Compiler.Syntax + open FSharp.Compiler.Tokenization open System open System.Text @@ -70,10 +71,10 @@ module SignatureFormatter = sprintf "%s array" genericArgs elif isMeasureType typeDef then typ.Format context - else sprintf "%s<%s>" (FSharpKeywords.QuoteIdentifierIfNeeded typeDef.DisplayName) genericArgs + else sprintf "%s<%s>" (FSharpKeywords.AddBackticksToIdentifierIfNeeded typeDef.DisplayName) genericArgs else if typ.HasTypeDefinition then - FSharpKeywords.QuoteIdentifierIfNeeded typ.TypeDefinition.DisplayName + FSharpKeywords.AddBackticksToIdentifierIfNeeded typ.TypeDefinition.DisplayName else typ.Format context with | _ -> typ.Format context @@ -93,7 +94,7 @@ module SignatureFormatter = chopped, true | _, _ -> if PrettyNaming.IsMangledOpName c.MemberName then - PrettyNaming.DemangleOperatorName c.MemberName, false + PrettyNaming.DecompileOpName c.MemberName, false else c.MemberName, false @@ -150,9 +151,9 @@ module SignatureFormatter = sb.ToString() let getUnioncaseSignature (displayContext: FSharpDisplayContext) (unionCase:FSharpUnionCase) = - if unionCase.UnionCaseFields.Count > 0 then + if unionCase.Fields.Count > 0 then let typeList = - unionCase.UnionCaseFields + unionCase.Fields |> Seq.map (fun unionField -> if unionField.Name.StartsWith "Item" then //TODO: Some better way of dettecting default names for the union cases' fields formatFSharpType displayContext unionField.FieldType @@ -171,10 +172,10 @@ module SignatureFormatter = match func.EnclosingEntitySafe with | Some ent -> ent.DisplayName | _ -> func.DisplayName - |> FSharpKeywords.QuoteIdentifierIfNeeded + |> FSharpKeywords.AddBackticksToIdentifierIfNeeded elif func.IsOperatorOrActivePattern then func.DisplayName - elif func.DisplayName.StartsWith "( " then FSharpKeywords.QuoteIdentifierIfNeeded func.LogicalName - else FSharpKeywords.QuoteIdentifierIfNeeded func.DisplayName + elif func.DisplayName.StartsWith "( " then FSharpKeywords.AddBackticksToIdentifierIfNeeded func.LogicalName + else FSharpKeywords.AddBackticksToIdentifierIfNeeded func.DisplayName name let modifiers = @@ -229,7 +230,7 @@ module SignatureFormatter = argInfos |> List.concat |> List.map (fun p -> let name = Option.defaultValue p.DisplayName p.Name - let normalisedName = FSharpKeywords.QuoteIdentifierIfNeeded name + let normalisedName = FSharpKeywords.AddBackticksToIdentifierIfNeeded name normalisedName.Length ) match allLengths with | [] -> 0 @@ -237,7 +238,7 @@ module SignatureFormatter = let formatName indent padding (parameter:FSharpParameter) = let name = Option.defaultValue parameter.DisplayName parameter.Name - let normalisedName = FSharpKeywords.QuoteIdentifierIfNeeded name + let normalisedName = FSharpKeywords.AddBackticksToIdentifierIfNeeded name indent + normalisedName.PadRight padding + ":" let isDelegate = @@ -310,7 +311,7 @@ module SignatureFormatter = let name = if func.IsConstructor then "new" elif func.IsOperatorOrActivePattern then func.DisplayName - elif func.DisplayName.StartsWith "( " then FSharpKeywords.QuoteIdentifierIfNeeded func.LogicalName + elif func.DisplayName.StartsWith "( " then FSharpKeywords.AddBackticksToIdentifierIfNeeded func.LogicalName elif func.LogicalName.StartsWith "get_" || func.LogicalName.StartsWith "set_" then PrettyNaming.TryChopPropertyName func.DisplayName |> Option.defaultValue func.DisplayName else func.DisplayName name @@ -353,7 +354,7 @@ module SignatureFormatter = match func.EnclosingEntitySafe with | Some ent -> ent.DisplayName | _ -> func.DisplayName - |> FSharpKeywords.QuoteIdentifierIfNeeded + |> FSharpKeywords.AddBackticksToIdentifierIfNeeded else formatFSharpType displayContext func.ReturnParameter.Type with _ex -> @@ -430,7 +431,7 @@ module SignatureFormatter = let name = if v.DisplayName.StartsWith "( " then v.LogicalName else v.DisplayName - |> FSharpKeywords.QuoteIdentifierIfNeeded + |> FSharpKeywords.AddBackticksToIdentifierIfNeeded let constraints = match v.FullTypeSafe with | Some fulltype when fulltype.IsGenericParameter -> @@ -554,7 +555,7 @@ module SignatureFormatter = let typeDisplay = let name = - let normalisedName = FSharpKeywords.QuoteIdentifierIfNeeded fse.DisplayName + let normalisedName = FSharpKeywords.AddBackticksToIdentifierIfNeeded fse.DisplayName if fse.GenericParameters.Count > 0 then let paramsAndConstraints = fse.GenericParameters diff --git a/src/FsAutoComplete.Core/SignatureHelp.fs b/src/FsAutoComplete.Core/SignatureHelp.fs index ca47407ba..258ec5c97 100644 --- a/src/FsAutoComplete.Core/SignatureHelp.fs +++ b/src/FsAutoComplete.Core/SignatureHelp.fs @@ -2,17 +2,20 @@ module FsAutoComplete.SignatureHelp open System open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices open FsToolkit.ErrorHandling open FsAutoComplete open FSharp.UMX open FsAutoComplete.FCSPatches +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.Syntax +open FSharp.Compiler.Tokenization type SignatureHelpKind = MethodCall | FunctionApplication type SignatureHelpInfo = { /// all potential overloads of the member at the position where signaturehelp was invoked - Methods: FSharpMethodGroupItem [] + Methods: MethodGroupItem [] /// if present, the index of the method we think is the current one (will never be outside the bounds of the Methods array) ActiveOverload: int option /// if present, the index of the parameter on the active method (will never be outside the bounds of the Parameters array on the selected method) @@ -20,26 +23,26 @@ type SignatureHelpInfo = { SigHelpKind: SignatureHelpKind } -let private lineText (lines: ISourceText) (pos: Pos) = lines.GetLineString(pos.Line - 1) +let private lineText (lines: ISourceText) (pos: Position) = lines.GetLineString(pos.Line - 1) -let private charAt (lines: ISourceText) (pos: Pos) = +let private charAt (lines: ISourceText) (pos: Position) = (lineText lines pos).[pos.Column - 1] -let dec (lines: ISourceText) (pos: Pos): Pos = +let dec (lines: ISourceText) (pos: Position): Position = if pos.Column = 0 then let prevLine = lines.GetLineString (pos.Line - 2) // retreat to the end of the previous line - Pos.mkPos (pos.Line - 1) (prevLine.Length - 1) + Position.mkPos (pos.Line - 1) (prevLine.Length - 1) else - Pos.mkPos pos.Line (pos.Column - 1) + Position.mkPos pos.Line (pos.Column - 1) -let inc (lines: ISourceText) (pos: Pos): Pos = +let inc (lines: ISourceText) (pos: Position): Position = let currentLine = lineText lines pos if pos.Column - 1 = currentLine.Length then // advance to the beginning of the next line - Pos.mkPos (pos.Line + 1) 0 + Position.mkPos (pos.Line + 1) 0 else - Pos.mkPos pos.Line (pos.Column + 1) + Position.mkPos pos.Line (pos.Column + 1) let getText (lines: ISourceText) (range: Range) = if range.Start.Line = range.End.Line then @@ -55,7 +58,7 @@ let getText (lines: ISourceText) (range: Range) = yield endLine.Substring(0, range.End.Column - 1) }) -let private getSignatureHelpForFunctionApplication (tyRes: ParseAndCheckResults, caretPos: Pos, endOfPreviousIdentPos: Pos, lines: ISourceText) : Async = +let private getSignatureHelpForFunctionApplication (tyRes: ParseAndCheckResults, caretPos: Position, endOfPreviousIdentPos: Position, lines: ISourceText) : Async = asyncMaybe { let lineStr = lineText lines endOfPreviousIdentPos let! possibleApplicationSymbolEnd = maybe { @@ -71,18 +74,18 @@ let private getSignatureHelpForFunctionApplication (tyRes: ParseAndCheckResults, let! symbolUse = tyRes.GetCheckResults.GetSymbolUseAtLocation(possibleApplicationSymbolEnd.Line, endCol, lineStr, idents) let isValid (mfv: FSharpMemberOrFunctionOrValue) = - not (PrettyNaming.IsOperatorName mfv.DisplayName) && + not (PrettyNaming.IsOperatorDisplayName mfv.DisplayName) && not mfv.IsProperty && mfv.CurriedParameterGroups.Count > 0 match symbolUse.Symbol with | :? FSharpMemberOrFunctionOrValue as mfv when isValid mfv -> - let tooltip = tyRes.GetCheckResults.GetToolTipText(possibleApplicationSymbolEnd.Line, endCol, possibleApplicationSymbolLineStr, idents, FSharpTokenTag.IDENT) + let tooltip = tyRes.GetCheckResults.GetToolTip(possibleApplicationSymbolEnd.Line, endCol, possibleApplicationSymbolLineStr, idents, FSharpTokenTag.IDENT) match tooltip with - | FSharpToolTipText [] - | FSharpToolTipText [FSharpToolTipElement.None] -> return! None + | ToolTipText [] + | ToolTipText [ ToolTipElement.None ] -> return! None | _ -> - let symbolStart = symbolUse.RangeAlternate.Start + let symbolStart = symbolUse.Range.Start let possiblePipelineIdent = tyRes.GetParseResults.TryIdentOfPipelineContainingPosAndNumArgsApplied symbolStart let numArgsAlreadyApplied = possiblePipelineIdent |> Option.map snd |> Option.defaultValue 0 let definedArgs = mfv.CurriedParameterGroups |> Array.ofSeq @@ -103,7 +106,7 @@ let private getSignatureHelpForFunctionApplication (tyRes: ParseAndCheckResults, | None -> let possibleNextIndex = curriedArgsInSource - |> Array.tryFindIndex(fun argRange -> Pos.posGeq argRange.Start caretPos) + |> Array.tryFindIndex(fun argRange -> Position.posGeq argRange.Start caretPos) match possibleNextIndex with | Some index -> Some index @@ -112,7 +115,7 @@ let private getSignatureHelpForFunctionApplication (tyRes: ParseAndCheckResults, Some (numDefinedArgs - (numDefinedArgs - curriedArgsInSource.Length)) else None - let methods = tyRes.GetCheckResults.GetMethods(symbolStart.Line, symbolUse.RangeAlternate.End.Column, lineText lines symbolStart, None) + let methods = tyRes.GetCheckResults.GetMethods(symbolStart.Line, symbolUse.Range.EndColumn, lineText lines symbolStart, None) return { ActiveParameter = Some argumentIndex @@ -124,9 +127,9 @@ let private getSignatureHelpForFunctionApplication (tyRes: ParseAndCheckResults, return! None } -let private getSignatureHelpForMethod (tyRes: ParseAndCheckResults, caretPos: Pos, lines: ISourceText, triggerChar) = +let private getSignatureHelpForMethod (tyRes: ParseAndCheckResults, caretPos: Position, lines: ISourceText, triggerChar) = asyncMaybe { - let! paramLocations = tyRes.GetParseResults.FindNoteworthyParamInfoLocations caretPos + let! paramLocations = tyRes.GetParseResults.FindParameterLocations caretPos let names = paramLocations.LongId let lidEnd = paramLocations.LongIdEndLocation let lineText = lineText lines lidEnd @@ -194,7 +197,7 @@ let private getSignatureHelpForMethod (tyRes: ParseAndCheckResults, caretPos: Po } } -let getSignatureHelpFor (tyRes : ParseAndCheckResults, pos: Pos, lines: ISourceText, triggerChar, possibleSessionKind) = +let getSignatureHelpFor (tyRes : ParseAndCheckResults, pos: Position, lines: ISourceText, triggerChar, possibleSessionKind) = asyncResult { let previousNonWhitespaceCharPos = let rec loop ch pos = diff --git a/src/FsAutoComplete.Core/State.fs b/src/FsAutoComplete.Core/State.fs index 2552671e1..cfbbb7d01 100644 --- a/src/FsAutoComplete.Core/State.fs +++ b/src/FsAutoComplete.Core/State.fs @@ -1,16 +1,18 @@ namespace FsAutoComplete open System -open FSharp.Compiler.SourceCodeServices open System.Collections.Concurrent open System.Threading open FSharp.Compiler.Text open Ionide.ProjInfo.ProjectSystem open FSharp.UMX open System.Diagnostics +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Syntax +open FSharp.Compiler.CodeAnalysis type DeclName = string -type CompletionNamespaceInsert = { Namespace: string; Position: Pos; Scope : ScopeKind } +type CompletionNamespaceInsert = { Namespace: string; Position: Position; Scope : ScopeKind } [] type State = @@ -19,12 +21,12 @@ type State = LastCheckedVersion: ConcurrentDictionary, int> ProjectController: ProjectController - HelpText : ConcurrentDictionary - Declarations: ConcurrentDictionary> + HelpText : ConcurrentDictionary + Declarations: ConcurrentDictionary> CompletionNamespaceInsert : ConcurrentDictionary - mutable CurrentAST: FSharp.Compiler.SyntaxTree.ParsedInput option + mutable CurrentAST: ParsedInput option - NavigationDeclarations : ConcurrentDictionary, FSharpNavigationTopLevelDeclaration[]> + NavigationDeclarations : ConcurrentDictionary, NavigationTopLevelDeclaration[]> CancellationTokens: ConcurrentDictionary, CancellationTokenSource list> ScriptProjectOptions: ConcurrentDictionary, int * FSharpProjectOptions> @@ -112,7 +114,6 @@ type State = LoadTime = DateTime.Now UnresolvedReferences = None OriginalLoadReferences = [] - ExtraProjectInfo = None Stamp = None} member x.TryGetFileCheckerOptionsWithLines(file: string) : ResultOrString = @@ -134,7 +135,7 @@ type State = | None -> ResultOrString.Error (sprintf "File '%s' not parsed" (UMX.untag file)) | Some f -> Ok f.Lines - member x.TryGetFileCheckerOptionsWithLinesAndLineStr(file: string, pos : Pos) : ResultOrString = + member x.TryGetFileCheckerOptionsWithLinesAndLineStr(file: string, pos : Position) : ResultOrString = match x.TryGetFileCheckerOptionsWithLines(file) with | Error x -> Error x | Ok (opts, text) -> diff --git a/src/FsAutoComplete.Core/SymbolCache.fs b/src/FsAutoComplete.Core/SymbolCache.fs index 06c565484..cb86c65e4 100644 --- a/src/FsAutoComplete.Core/SymbolCache.fs +++ b/src/FsAutoComplete.Core/SymbolCache.fs @@ -2,7 +2,7 @@ module SymbolCache open System open FsAutoComplete -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open System.IO open FSharp.UMX @@ -27,8 +27,8 @@ type SymbolUseRange = { member x.Range: FSharp.Compiler.Text.Range = FSharp.Compiler.Text.Range.mkRange x.FileName - (FSharp.Compiler.Text.Pos.mkPos x.StartLine x.StartColumn) - (FSharp.Compiler.Text.Pos.mkPos x.EndLine x.EndColumn) + (FSharp.Compiler.Text.Position.mkPos x.StartLine x.StartColumn) + (FSharp.Compiler.Text.Position.mkPos x.EndLine x.EndColumn) module private PersistentCacheImpl = open Microsoft.Data.Sqlite @@ -139,10 +139,10 @@ module private PersistentCacheImpl = connection <- Some lazyConn let fromSymbolUse (su : FSharpSymbolUse) = - { StartLine = su.RangeAlternate.StartLine - StartColumn = su.RangeAlternate.StartColumn + 1 - EndLine = su.RangeAlternate.EndLine - EndColumn = su.RangeAlternate.EndColumn + 1 + { StartLine = su.Range.StartLine + StartColumn = su.Range.StartColumn + 1 + EndLine = su.Range.EndLine + EndColumn = su.Range.EndColumn + 1 FileName = su.FileName IsFromDefinition = su.IsFromDefinition IsFromAttribute = su.IsFromAttribute diff --git a/src/FsAutoComplete.Core/TipFormatter.fs b/src/FsAutoComplete.Core/TipFormatter.fs index 082d92d8f..ea1def7dc 100644 --- a/src/FsAutoComplete.Core/TipFormatter.fs +++ b/src/FsAutoComplete.Core/TipFormatter.fs @@ -8,8 +8,10 @@ open System.IO open System.Xml open System.Collections.Generic open System.Text.RegularExpressions -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols open FsAutoComplete.Logging +open FSharp.Compiler.Text let inline nl<'T> = Environment.NewLine @@ -934,9 +936,9 @@ type FormatCommentStyle = // -------------------------------------------------------------------------------------- let private buildFormatComment cmt (formatStyle : FormatCommentStyle) (typeDoc: string option) = match cmt with - | FSharpXmlDoc.Text (unprocessed, processed) -> + | FSharpXmlDoc.FromXmlText xmldoc -> try - let document = processed |> String.concat Environment.NewLine + let document = xmldoc.GetXmlText() // We create a "fake" XML document in order to use the same parser for both libraries and user code let xml = sprintf "%s" document let doc = XmlDocument() @@ -954,7 +956,7 @@ let private buildFormatComment cmt (formatStyle : FormatCommentStyle) (typeDoc: | [] -> 0 let indentationSize = - processed + xmldoc.GetElaboratedXmlLines() |> Array.toList |> findIndentationSize @@ -975,7 +977,7 @@ let private buildFormatComment cmt (formatStyle : FormatCommentStyle) (typeDoc: logger.warn (Log.setMessage "TipFormatter - Error while parsing the doc comment" >> Log.addExn ex) sprintf "An error occured when parsing the doc comment, please check that your doc comment is valid.\n\nMore info can be found LSP output" - | FSharpXmlDoc.XmlDocFileSignature(dllFile, memberName) -> + | FSharpXmlDoc.FromXmlFile(dllFile, memberName) -> match getXmlDoc dllFile with | Some doc when doc.ContainsKey memberName -> let typeDoc = @@ -1004,26 +1006,56 @@ let private buildFormatComment cmt (formatStyle : FormatCommentStyle) (typeDoc: | _ -> "" | _ -> "" - -let private formatGenericParamInfo cmt = - let m = Regex.Match(cmt, """(.*) is (.*)""") - if m.Success then - sprintf "* `%s` is `%s`" m.Groups.[1].Value m.Groups.[2].Value - else - cmt - - -let formatTip (FSharpToolTipText tips) : (string * string) list list = +let formatTaggedText (t: TaggedText): string = + match t.Tag with + | TextTag.ActivePatternCase + | TextTag.ActivePatternResult + | TextTag.Alias + | TextTag.Class + | TextTag.Union + | TextTag.UnionCase + | TextTag.Delegate + | TextTag.Enum + | TextTag.Event + | TextTag.Field + | TextTag.Interface + | TextTag.Keyword + | TextTag.LineBreak + | TextTag.Local + | TextTag.Record + | TextTag.RecordField + | TextTag.Method + | TextTag.Member + | TextTag.ModuleBinding + | TextTag.Function + | TextTag.Module + | TextTag.Namespace + | TextTag.NumericLiteral + | TextTag.Operator + | TextTag.Parameter + | TextTag.Property + | TextTag.Space + | TextTag.StringLiteral + | TextTag.Struct + | TextTag.TypeParameter + | TextTag.Text + | TextTag.Punctuation + | TextTag.UnknownType + | TextTag.UnknownEntity -> t.Text + +let formatTaggedTexts = Array.map formatTaggedText >> String.concat "" + +let formatTip (ToolTipText tips) : (string * string) list list = tips |> List.choose (function - | FSharpToolTipElement.Group items -> - let getRemarks (it : FSharpToolTipElementData) = + | ToolTipElement.Group items -> + let getRemarks (it : ToolTipElementData) = it.Remarks - |> Option.map (fun n -> if String.IsNullOrWhiteSpace n then n else "\n\n" + n) + |> Option.map formatTaggedTexts |> Option.defaultValue "" - let makeTooltip (tipElement: FSharpToolTipElementData) = - let header = tipElement.MainDescription + getRemarks tipElement + let makeTooltip (tipElement: ToolTipElementData) = + let header = formatTaggedTexts tipElement.MainDescription + getRemarks tipElement let body = buildFormatComment tipElement.XmlDoc FormatCommentStyle.Legacy None header, body @@ -1031,13 +1063,13 @@ let formatTip (FSharpToolTipText tips) : (string * string) list list = |> List.map makeTooltip |> Some - | FSharpToolTipElement.CompositionError (error) -> Some [("", error)] + | ToolTipElement.CompositionError (error) -> Some [("", error)] | _ -> None) -let formatTipEnhanced (FSharpToolTipText tips) (signature : string) (footer : string) (typeDoc: string option) (formatCommentStyle : FormatCommentStyle) : (string * string * string) list list = +let formatTipEnhanced (ToolTipText tips) (signature : string) (footer : string) (typeDoc: string option) (formatCommentStyle : FormatCommentStyle) : (string * string * string) list list = tips |> List.choose (function - | FSharpToolTipElement.Group items -> + | ToolTipElement.Group items -> Some (items |> List.map (fun i -> let comment = if i.TypeMapping.IsEmpty then @@ -1045,15 +1077,15 @@ let formatTipEnhanced (FSharpToolTipText tips) (signature : string) (footer : st else buildFormatComment i.XmlDoc formatCommentStyle typeDoc + nl + nl + "**Generic Parameters**" + nl + nl - + (i.TypeMapping |> List.map formatGenericParamInfo |> String.concat nl) + + (i.TypeMapping |> List.map formatTaggedTexts |> String.concat nl) (signature, comment, footer))) - | FSharpToolTipElement.CompositionError (error) -> Some [("", error, "")] + | ToolTipElement.CompositionError (error) -> Some [("", error, "")] | _ -> None) -let formatDocumentation (FSharpToolTipText tips) ((signature, (constructors, fields, functions, interfaces, attrs, ts)) : string * (string [] * string [] * string []* string[]* string[]* string[])) (footer : string) (cn: string) = +let formatDocumentation (ToolTipText tips) ((signature, (constructors, fields, functions, interfaces, attrs, ts)) : string * (string [] * string [] * string []* string[]* string[]* string[])) (footer : string) (cn: string) = tips |> List.choose (function - | FSharpToolTipElement.Group items -> + | ToolTipElement.Group items -> Some (items |> List.map (fun i -> let comment = if i.TypeMapping.IsEmpty then @@ -1061,19 +1093,20 @@ let formatDocumentation (FSharpToolTipText tips) ((signature, (constructors, fie else buildFormatComment i.XmlDoc FormatCommentStyle.Documentation None + nl + nl + "**Generic Parameters**" + nl + nl - + (i.TypeMapping |> List.map formatGenericParamInfo |> String.concat "\n") + + (i.TypeMapping |> List.map formatTaggedTexts |> String.concat "\n") (signature, constructors, fields, functions, interfaces, attrs, ts, comment, footer, cn))) - | FSharpToolTipElement.CompositionError (error) -> Some [("", [||],[||], [||], [||], [||], [||], error, "", "")] + | ToolTipElement.CompositionError (error) -> Some [("", [||],[||], [||], [||], [||], [||], error, "", "")] | _ -> None) let formatDocumentationFromXmlSig (xmlSig: string) (assembly: string) ((signature, (constructors, fields, functions, interfaces, attrs, ts)) : string * (string [] * string [] * string [] * string[]* string[]* string[])) (footer : string) (cn: string) = - let xmlDoc = FSharpXmlDoc.XmlDocFileSignature(assembly, xmlSig) + let xmlDoc = FSharpXmlDoc.FromXmlFile(assembly, xmlSig) let comment = buildFormatComment xmlDoc FormatCommentStyle.Documentation None [[(signature, constructors, fields, functions, interfaces, attrs, ts, comment, footer, cn)]] -let extractSignature (FSharpToolTipText tips) = - let getSignature (str: string) = +let extractSignature (ToolTipText tips) = + let getSignature (t: TaggedText []) = + let str = formatTaggedTexts t let nlpos = str.IndexOfAny([|'\r';'\n'|]) let firstLine = if nlpos > 0 then str.[0..nlpos-1] @@ -1087,7 +1120,7 @@ let extractSignature (FSharpToolTipText tips) = let firstResult x = match x with - | FSharpToolTipElement.Group gs -> List.tryPick (fun (t : FSharpToolTipElementData) -> if not (String.IsNullOrWhiteSpace t.MainDescription) then Some t.MainDescription else None) gs + | ToolTipElement.Group gs -> List.tryPick (fun (t : ToolTipElementData) -> if not (Array.isEmpty t.MainDescription) then Some t.MainDescription else None) gs | _ -> None tips @@ -1095,12 +1128,13 @@ let extractSignature (FSharpToolTipText tips) = |> Option.map getSignature |> Option.defaultValue "" -let extractGenerics (FSharpToolTipText tips) = +let extractGenerics (ToolTipText tips) = let firstResult x = match x with - | FSharpToolTipElement.Group gs -> List.tryPick (fun (t : FSharpToolTipElementData) -> if not (t.TypeMapping.IsEmpty) then Some t.TypeMapping else None) gs + | ToolTipElement.Group gs -> List.tryPick (fun (t : ToolTipElementData) -> if not (t.TypeMapping.IsEmpty) then Some t.TypeMapping else None) gs | _ -> None tips |> Seq.tryPick firstResult |> Option.defaultValue [] + |> List.map formatTaggedTexts diff --git a/src/FsAutoComplete.Core/TypedAstPatterns.fs b/src/FsAutoComplete.Core/TypedAstPatterns.fs index 3ae6b0206..fda9d6b3b 100644 --- a/src/FsAutoComplete.Core/TypedAstPatterns.fs +++ b/src/FsAutoComplete.Core/TypedAstPatterns.fs @@ -1,7 +1,8 @@ [] module FsAutoComplete.Patterns -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols /// Active patterns over `FSharpSymbolUse`. diff --git a/src/FsAutoComplete.Core/TypedAstUtils.fs b/src/FsAutoComplete.Core/TypedAstUtils.fs index 90d9f6105..b220e9161 100644 --- a/src/FsAutoComplete.Core/TypedAstUtils.fs +++ b/src/FsAutoComplete.Core/TypedAstUtils.fs @@ -3,7 +3,7 @@ namespace FsAutoComplete open System open System.Text.RegularExpressions -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Symbols open UntypedAstUtils @@ -230,7 +230,7 @@ module TypedAstExtensionHelpers = | :? FSharpUnionCase as fsu -> fsu.XmlDoc | :? FSharpActivePatternCase as apc -> apc.XmlDoc | :? FSharpGenericParameter as gp -> gp.XmlDoc - | _ -> ResizeArray() :> Collections.Generic.IList<_> + | _ -> FSharpXmlDoc.None type FSharpGenericParameterMemberConstraint with member x.IsProperty = diff --git a/src/FsAutoComplete.Core/UnionPatternMatchCaseGenerator.fs b/src/FsAutoComplete.Core/UnionPatternMatchCaseGenerator.fs index f295d5d82..2b79e230a 100644 --- a/src/FsAutoComplete.Core/UnionPatternMatchCaseGenerator.fs +++ b/src/FsAutoComplete.Core/UnionPatternMatchCaseGenerator.fs @@ -3,10 +3,11 @@ module FsAutoComplete.UnionPatternMatchCaseGenerator open System open FsAutoComplete.UntypedAstUtils -open FSharp.Compiler.SyntaxTree +open FSharp.Compiler.Syntax open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Syntax open FsAutoComplete.CodeGenerationUtils +open FSharp.Compiler.Symbols [] type PatternMatchExpr = { @@ -19,7 +20,7 @@ type PatternMatchExpr = { [] type UnionMatchCasesInsertionParams = { - InsertionPos: Pos + InsertionPos: Position IndentColumn: int } @@ -32,7 +33,7 @@ type private Context = { Qualifier: string option } -let private clauseIsCandidateForCodeGen (cursorPos: Pos) (clause: SynMatchClause) = +let private clauseIsCandidateForCodeGen (cursorPos: Position) (SynMatchClause(pat, _, _, _, _, _)) = let rec patIsCandidate (pat: SynPat) = match pat with | SynPat.Paren(innerPat, _) @@ -40,9 +41,7 @@ let private clauseIsCandidateForCodeGen (cursorPos: Pos) (clause: SynMatchClause | SynPat.Const(_, _) -> false | SynPat.Wild(_) -> false // TODO: check if we have to handle these cases - | SynPat.Typed(innerPat, _, _) - | SynPat.Named(innerPat, _, _, _, _) -> - patIsCandidate innerPat + | SynPat.Typed(innerPat, _, _) -> patIsCandidate innerPat | SynPat.OptionalVal(_, _) -> false | SynPat.Or(leftPat, rightPat, _) -> patIsCandidate leftPat || patIsCandidate rightPat @@ -61,18 +60,20 @@ let private clauseIsCandidateForCodeGen (cursorPos: Pos) (clause: SynMatchClause | SynPat.QuoteExpr _ | SynPat.DeprecatedCharRange _ | SynPat.InstanceMember _ - | SynPat.FromParseError _ -> false + | SynPat.FromParseError _ + | SynPat.As _ + | SynPat.Named _ + | SynPat.LongIdent _ -> false - match clause with - | Clause(pat, _, _, _, _) -> patIsCandidate pat + patIsCandidate pat -let private posIsInLhsOfClause (pos: Pos) (clause: SynMatchClause) = +let private posIsInLhsOfClause (pos: Position) (clause: SynMatchClause) = match clause with - | Clause(_, None, _, patternRange, _) -> Range.rangeContainsPos patternRange pos - | Clause(_, Some guardExpr, _, patternRange, _) -> + | SynMatchClause(_, None, _, _, patternRange, _) -> Range.rangeContainsPos patternRange pos + | SynMatchClause(_, Some guardExpr, _, _, patternRange, _) -> Range.rangeContainsPos (Range.unionRanges guardExpr.Range patternRange) pos -let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: ParsedInput) = +let private tryFindPatternMatchExprInParsedInput (pos: Position) (parsedInput: ParsedInput) = let inline getIfPosInRange range f = if Range.rangeContainsPos range pos then f() else None @@ -108,9 +109,10 @@ let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: Parsed None ) - and walkSynTypeDefn(TypeDefn(_componentInfo, representation, members, range)) = + and walkSynTypeDefn(SynTypeDefn(_componentInfo, representation, members, implicitCtor, range)) = getIfPosInRange range (fun () -> walkSynTypeDefnRepr representation + |> Option.orElseWith (fun _ -> Option.bind walkSynMemberDefn implicitCtor) |> Option.orElseWith (fun _ -> List.tryPick walkSynMemberDefn members) ) @@ -147,8 +149,8 @@ let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: Parsed None ) - and walkBinding (Binding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, _headPat, _retTy, expr, _bindingRange, _seqPoint) as binding) = - getIfPosInRange binding.RangeOfBindingAndRhs (fun () -> walkExpr expr) + and walkBinding (SynBinding(_access, _bindingKind, _isInline, _isMutable, _attrs, _xmldoc, _valData, _headPat, _retTy, expr, _bindingRange, _seqPoint) as binding) = + getIfPosInRange binding.RangeOfBindingWithRhs (fun () -> walkExpr expr) and walkExpr expr = getIfPosInRange expr.Range (fun () -> @@ -162,9 +164,9 @@ let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: Parsed | SynExpr.Typed(synExpr, _, _) | SynExpr.Paren(synExpr, _, _, _) | SynExpr.New(_, _, synExpr, _) - | SynExpr.ArrayOrListOfSeqExpr(_, synExpr, _) - | SynExpr.CompExpr(_, _, synExpr, _) - | SynExpr.Lambda(_, _, _, synExpr, _, _) + | SynExpr.ArrayOrListComputed(_, synExpr, _) + | SynExpr.ComputationExpr(_, synExpr, _) + | SynExpr.Lambda(_, _, _, _, synExpr, _, _) | SynExpr.Lazy(synExpr, _) | SynExpr.Do(synExpr, _) | SynExpr.Assert(synExpr, _) -> @@ -202,7 +204,7 @@ let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: Parsed synMatchClauseList, _, _wholeExprRange) as matchLambdaExpr -> synMatchClauseList - |> List.tryPick (fun (Clause(_, _, e, _, _)) -> walkExpr e) + |> List.tryPick (fun (SynMatchClause(_, _, _, e, _, _)) -> walkExpr e) |> Option.orElseWith (fun () -> if isExnMatch then None @@ -220,13 +222,13 @@ let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: Parsed getIfPosInRange synExpr.Range (fun () -> walkExpr synExpr) |> Option.orElseWith (fun () -> synMatchClauseList - |> List.tryPick (fun (Clause(_, _, e, _, _)) -> walkExpr e) + |> List.tryPick (fun (SynMatchClause(_, _, _, e, _, _)) -> walkExpr e) ) |> Option.orElseWith (fun () -> let currentClause = List.tryFind (posIsInLhsOfClause pos) synMatchClauseList if currentClause |> Option.map (clauseIsCandidateForCodeGen pos) |> Option.defaultValue false then match sequencePointInfoForBinding with - | DebugPointAtBinding range -> + | DebugPointAtBinding.Yes range -> { MatchWithOrFunctionRange = range Expr = matchExpr Clauses = synMatchClauseList } @@ -255,7 +257,7 @@ let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: Parsed | Sequentials exprs -> List.tryPick walkExpr exprs - | SynExpr.IfThenElse(synExpr1, synExpr2, synExprOpt, _sequencePointInfoForBinding, _isRecovery, _range, _range2) -> + | SynExpr.IfThenElse(_, _, synExpr1, _, synExpr2, _, synExprOpt, _sequencePointInfoForBinding, _isRecovery, _range, _range2) -> match synExprOpt with | Some synExpr3 -> List.tryPick walkExpr [synExpr1; synExpr2; synExpr3] @@ -275,16 +277,13 @@ let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: Parsed | SynExpr.DotSet(synExpr1, _longIdent, synExpr2, _range) -> List.tryPick walkExpr [synExpr1; synExpr2] - | SynExpr.DotIndexedGet(synExpr, IndexerArgList synExprList, _range, _range2) -> - synExprList - |> List.map fst - |> List.tryPick walkExpr - |> Option.orElseWith (fun _ -> walkExpr synExpr) + | SynExpr.DotIndexedGet(synExpr, argList, _range, _range2) -> + walkExpr argList - | SynExpr.DotIndexedSet(synExpr1, IndexerArgList synExprList, synExpr2, _, _range, _range2) -> - [ yield synExpr1 - yield! synExprList |> List.map fst - yield synExpr2 ] + | SynExpr.DotIndexedSet(synExpr1, argList, synExpr2, _, _range, _range2) -> + [ synExpr1 + argList + synExpr2 ] |> List.tryPick walkExpr | SynExpr.JoinIn(synExpr1, _range, synExpr2, _range2) -> @@ -336,7 +335,7 @@ let private tryFindPatternMatchExprInParsedInput (pos: Pos) (parsedInput: Parsed | _ -> None ) - and walkSynInterfaceImpl (InterfaceImpl(_synType, synBindings, _range)) = + and walkSynInterfaceImpl (SynInterfaceImpl(_synType, synBindings, _range)) = List.tryPick walkBinding synBindings match parsedInput with @@ -367,11 +366,13 @@ let getWrittenCases (patMatchExpr: PatternMatchExpr) = |> List.forall checkPattern | SynPat.OptionalVal(_, _) -> true + | SynPat.Named(_) | SynPat.Wild(_) -> true - | SynPat.Named(innerPat, _, _, _, _) | SynPat.Typed(innerPat, _, _) | SynPat.Attrib(innerPat, _, _) | SynPat.Paren(innerPat, _) -> checkPattern innerPat + | SynPat.As(lhsPat, rhsPat, _range) -> + checkPattern lhsPat && checkPattern rhsPat let getIfArgsAreFree constructorArgs func = match constructorArgs with @@ -420,7 +421,7 @@ let getWrittenCases (patMatchExpr: PatternMatchExpr) = let rec getCasesInClause (x: SynMatchClause) = match x with - | Clause(pat, None, _, _, _) -> getCasesInPattern pat + | SynMatchClause(pat, None, _, _, _, _) -> getCasesInPattern pat | _ -> [] patMatchExpr.Clauses @@ -434,10 +435,10 @@ let shouldGenerateUnionPatternMatchCases (patMatchExpr: PatternMatchExpr) (entit |> Set.count caseCount > 0 && writtenCaseCount < caseCount -let tryFindPatternMatchExprInBufferAtPos (codeGenService: CodeGenerationService) (pos: Pos) (document : Document) = +let tryFindPatternMatchExprInBufferAtPos (codeGenService: CodeGenerationService) (pos: Position) (document : Document) = asyncMaybe { let! parseResults = codeGenService.ParseFileInProject(document.FullName) - let! input = parseResults.ParseTree + let input = parseResults.ParseTree return! tryFindPatternMatchExprInParsedInput pos input } @@ -521,7 +522,7 @@ let tryFindInsertionParams (codeGenService: CodeGenerationService) document (pat firstClauseOnLastLine.Range.StartRange else let clause = firstClauseOnLastLine - let start = Pos.mkPos clause.Range.StartLine 0 + let start = Position.mkPos clause.Range.StartLine 0 Range.mkRange clause.Range.FileName start clause.Range.Start let barTokenOpt = @@ -547,7 +548,7 @@ let checkThatPatternMatchExprEndsWithCompleteClause (expr: PatternMatchExpr) = // In the case when there's nothing in the RHS of the arrow // FCS compiler apparently uses this particular AST representation // but with unitRange = empty - | Clause(_, _, SynExpr.Const(SynConst.Unit, unitRange), _, _) -> + | SynMatchClause(_, _, _, SynExpr.Const(SynConst.Unit, unitRange), _, _) -> let rhsExprExists = unitRange.StartLine <> unitRange.EndLine || unitRange.StartColumn <> unitRange.EndColumn @@ -602,13 +603,13 @@ let private formatCase (ctxt: Context) (case: FSharpUnionCase) = | Some qual -> sprintf "%s.%s" qual case.Name let paramsPattern = - let unionCaseFieldsCount = case.UnionCaseFields.Count + let unionCaseFieldsCount = case.Fields.Count if unionCaseFieldsCount <= 0 then "" else let fieldNames = [| - for field in case.UnionCaseFields -> + for field in case.Fields -> if String.IsNullOrEmpty(field.Name) || isUnnamedUnionCaseField field then "_" else diff --git a/src/FsAutoComplete.Core/UntypedAstUtils.fs b/src/FsAutoComplete.Core/UntypedAstUtils.fs index 1509236e1..7997abe7a 100644 --- a/src/FsAutoComplete.Core/UntypedAstUtils.fs +++ b/src/FsAutoComplete.Core/UntypedAstUtils.fs @@ -1,7 +1,7 @@ /// Code from VisualFSharpPowerTools project: https://github.com/fsprojects/VisualFSharpPowerTools/blob/master/src/FSharp.Editing/Common/UntypedAstUtils.fs module FsAutoComplete.UntypedAstUtils -open FSharp.Compiler.SyntaxTree +open FSharp.Compiler.Syntax open System.Collections.Generic open FSharp.Compiler open FSharp.Compiler.Text @@ -54,8 +54,8 @@ let (|AllSimplePats|) (pats: SynSimplePats) = loop [] pats /// Returns all Idents and LongIdents found in an untyped AST. -let internal getLongIdents (input: ParsedInput option) : IDictionary = - let identsByEndPos = Dictionary() +let internal getLongIdents (input: ParsedInput option) : IDictionary = + let identsByEndPos = Dictionary() let addLongIdent (longIdent: LongIdent) = let idents = longIdentToArray longIdent @@ -68,7 +68,7 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary identsByEndPos.[value.Range.End] <- idents | idents -> for dotRange in lids do - identsByEndPos.[Pos.mkPos dotRange.EndLine (dotRange.EndColumn - 1)] <- idents + identsByEndPos.[Position.mkPos dotRange.EndLine (dotRange.EndColumn - 1)] <- idents identsByEndPos.[value.Range.End] <- idents let addIdent (ident: Ident) = @@ -85,7 +85,7 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary List.iter walkPat pats - | SynPat.Named (pat, ident, _, _, _) -> - walkPat pat + | SynPat.Named (ident, _, _, _) -> addIdent ident | SynPat.Typed (pat, t, _) -> walkPat pat @@ -119,28 +118,28 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary addLongIdentWithDots ident typars - |> Option.iter (fun (SynValTyparDecls (typars, _, constraints)) -> - List.iter walkTyparDecl typars - List.iter walkTypeConstraint constraints) + |> Option.iter (fun (SynValTyparDecls (typars, _)) -> + match typars with + | None -> () + | Some typars -> + typars.TyparDecls |> List.iter walkTyparDecl + typars.Constraints |> List.iter walkTypeConstraint + ) List.iter walkPat pats | SynPat.Paren (pat, _) -> walkPat pat | SynPat.IsInst (t, _) -> walkType t | SynPat.QuoteExpr(e, _) -> walkExpr e | _ -> () - and walkTypar (Typar (_, _, _)) = () + and walkTypar (SynTypar (_, _, _)) = () - and walkBinding (SynBinding.Binding (_, _, _, _, AllAttrs attrs, _, _, pat, returnInfo, e, _, _)) = + and walkBinding (SynBinding (_, _, _, _, AllAttrs attrs, _, _, pat, returnInfo, e, _, _)) = List.iter walkAttribute attrs walkPat pat walkExpr e returnInfo |> Option.iter (fun (SynBindingReturnInfo (t, _, _)) -> walkType t) - and walkInterfaceImpl (InterfaceImpl(_, bindings, _)) = List.iter walkBinding bindings - - and walkIndexerArg = function - | SynIndexerArg.One(e, _fromEnd,_range) -> walkExpr e - | SynIndexerArg.Two(e1,_e1FromEnd,e2,_e2FromEnd,_e1Range,_e2Range) -> List.iter walkExpr [e1; e2] + and walkInterfaceImpl (SynInterfaceImpl(_, bindings, _)) = List.iter walkBinding bindings and walkType = function | SynType.Array (_, t, _) @@ -156,7 +155,7 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary () - and walkClause (Clause (pat, e1, e2, _, _)) = + and walkClause (SynMatchClause (pat, e1, _,e2, _, _)) = walkPat pat walkExpr e2 e1 |> Option.iter walkExpr @@ -176,13 +175,13 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary walkExpr e - | SynExpr.Lambda (_, _, pats, e, _, _) -> + | SynExpr.Lambda (_, _, pats, _, e, _, _) -> walkSimplePats pats walkExpr e | SynExpr.New (_, t, e, _) @@ -225,7 +224,7 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary List.iter walkClause clauses; walkExpr e - | SynExpr.IfThenElse (e1, e2, e3, _, _, _, _) -> + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3, _, _, _, _) -> List.iter walkExpr [e1; e2] e3 |> Option.iter walkExpr | SynExpr.LongIdentSet (ident, e, _) @@ -238,10 +237,10 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary walkExpr e - List.iter walkIndexerArg args + walkExpr args | SynExpr.DotIndexedSet (e1, args, e2, _, _, _) -> walkExpr e1 - List.iter walkIndexerArg args + walkExpr args walkExpr e2 | SynExpr.NamedIndexedPropertySet (ident, e1, e2, _) -> addLongIdentWithDots ident @@ -261,7 +260,7 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary walkMeasure m + | SynExpr.Const (SynConst.Measure(_, _, m), _) -> walkMeasure m | _ -> () and walkMeasure = function @@ -283,11 +282,11 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary () - and walkField (SynField.Field(AllAttrs attrs, _, _, t, _, _, _, _)) = + and walkField (SynField(AllAttrs attrs, _, _, t, _, _, _, _)) = List.iter walkAttribute attrs walkType t - and walkValSig (SynValSig.ValSpfn(AllAttrs attrs, _, _, t, SynValInfo(argInfos, argInfo), _, _, _, _, _, _)) = + and walkValSig (SynValSig(AllAttrs attrs, _, _, t, SynValInfo(argInfos, argInfo), _, _, _, _, _, _)) = List.iter walkAttribute attrs walkType t argInfo :: (argInfos |> List.concat) @@ -299,12 +298,12 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary walkType t | SynMemberSig.Member(vs, _, _) -> walkValSig vs | SynMemberSig.ValField(f, _) -> walkField f - | SynMemberSig.NestedType(SynTypeDefnSig.TypeDefnSig (info, repr, memberSigs, _), _) -> + | SynMemberSig.NestedType(SynTypeDefnSig (info, repr, memberSigs, _), _) -> let isTypeExtensionOrAlias = match repr with | SynTypeDefnSigRepr.Simple(SynTypeDefnSimpleRepr.TypeAbbrev _, _) - | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.TyconAbbrev, _, _) - | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.TyconAugmentation, _, _) -> true + | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.Abbrev, _, _) + | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.Augmentation, _, _) -> true | _ -> false walkComponentInfo isTypeExtensionOrAlias info walkTypeDefnSigRepr repr @@ -330,13 +329,13 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary () - and walkEnumCase (EnumCase(AllAttrs attrs, _, _, _, _)) = List.iter walkAttribute attrs + and walkEnumCase (SynEnumCase(AllAttrs attrs, _, _, _, _, _)) = List.iter walkAttribute attrs and walkUnionCaseType = function - | SynUnionCaseType.UnionCaseFields fields -> List.iter walkField fields - | SynUnionCaseType.UnionCaseFullType (t, _) -> walkType t + | SynUnionCaseKind.Fields fields -> List.iter walkField fields + | SynUnionCaseKind.FullType (t, _) -> walkType t - and walkUnionCase (SynUnionCase.UnionCase (AllAttrs attrs, _, t, _, _, _)) = + and walkUnionCase (SynUnionCase (AllAttrs attrs, _, t, _, _, _)) = List.iter walkAttribute attrs walkUnionCaseType t @@ -347,10 +346,13 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary walkType t | _ -> () - and walkComponentInfo isTypeExtensionOrAlias (ComponentInfo(AllAttrs attrs, typars, constraints, longIdent, _, _, _, _)) = + and walkTyparDecls (typars: SynTyparDecls) = + typars.TyparDecls |> List.iter walkTyparDecl + typars.Constraints |> List.iter walkTypeConstraint + + and walkComponentInfo isTypeExtensionOrAlias (SynComponentInfo(AllAttrs attrs, typars, constraints, longIdent, _, _, _, _)) = List.iter walkAttribute attrs - List.iter walkTyparDecl typars - List.iter walkTypeConstraint constraints + Option.iter walkTyparDecls typars if isTypeExtensionOrAlias then addLongIdent longIdent @@ -364,15 +366,16 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary walkTypeDefnSimple defn | SynTypeDefnSigRepr.Exception _ -> () - and walkTypeDefn (TypeDefn (info, repr, members, _)) = + and walkTypeDefn (SynTypeDefn (info, repr, members, implicitCtor, _)) = let isTypeExtensionOrAlias = match repr with - | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAugmentation, _, _) - | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAbbrev, _, _) + | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Augmentation, _, _) + | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Abbrev, _, _) | SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.TypeAbbrev _, _) -> true | _ -> false walkComponentInfo isTypeExtensionOrAlias info walkTypeDefnRepr repr + Option.iter walkMember implicitCtor List.iter walkMember members and walkSynModuleDecl (decl: SynModuleDecl) = @@ -395,7 +398,7 @@ let internal getLongIdents (input: ParsedInput option) : IDictionary _ /// Checks if given position is part of the typed binding -let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : bool = +let internal isTypedBindingAtPosition (input: ParsedInput) (r: Range) : bool = let mutable result = false let isInside (ran : Range) = @@ -411,10 +414,17 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b and walkAttribute (attr: SynAttribute) = walkExpr attr.ArgExpr - and walkTyparDecl (SynTyparDecl.TyparDecl (AllAttrs attrs, typar)) = + and walkTyparDecl (SynTyparDecl (AllAttrs attrs, typar)) = List.iter walkAttribute attrs walkTypar typar + and walkTyparDecls (typars: SynTyparDecls) = + typars.TyparDecls |> List.iter walkTyparDecl + typars.Constraints |> List.iter walkTypeConstraint + + and walkSynValTyparDecls (SynValTyparDecls(typars, _)) = + Option.iter walkTyparDecls typars + and walkTypeConstraint = function | SynTypeConstraint.WhereTyparIsValueType (t, _) | SynTypeConstraint.WhereTyparIsReferenceType (t, _) @@ -432,8 +442,7 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b | SynPat.Tuple (_, pats, _) | SynPat.ArrayOrList (_, pats, _) | SynPat.Ands (pats, _) -> List.iter walkPat pats - | SynPat.Named (pat, ident, _, _, _) -> - walkPat pat + | SynPat.Named (ident, _, _, _) -> () | SynPat.Typed (pat, t, ran) -> if isInside ran then result <- true walkPat pat @@ -443,29 +452,22 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b List.iter walkAttribute attrs | SynPat.Or (pat1, pat2, _) -> List.iter walkPat [pat1; pat2] | SynPat.LongIdent (ident, _, typars, ConstructorPats pats, _, _) -> - typars - |> Option.iter (fun (SynValTyparDecls (typars, _, constraints)) -> - List.iter walkTyparDecl typars - List.iter walkTypeConstraint constraints) + Option.iter walkSynValTyparDecls typars List.iter walkPat pats | SynPat.Paren (pat, _) -> walkPat pat | SynPat.IsInst (t, _) -> walkType t | SynPat.QuoteExpr(e, _) -> walkExpr e | _ -> () - and walkTypar (Typar (_, _, _)) = () + and walkTypar (SynTypar (_, _, _)) = () - and walkBinding (SynBinding.Binding (_, _, _, _, AllAttrs attrs, _, _, pat, returnInfo, e, _, _)) = + and walkBinding (SynBinding (_, _, _, _, AllAttrs attrs, _, _, pat, returnInfo, e, _, _)) = List.iter walkAttribute attrs walkPat pat walkExpr e returnInfo |> Option.iter (fun (SynBindingReturnInfo (t, _, _)) -> walkType t) - and walkInterfaceImpl (InterfaceImpl(_, bindings, _)) = List.iter walkBinding bindings - - and walkIndexerArg = function - | SynIndexerArg.One(e,_fromEnd,_range) -> walkExpr e - | SynIndexerArg.Two(e1,_e1FromEnd,e2,_e2FromEnd,_e1Range,_e2Range) -> List.iter walkExpr [e1; e2] + and walkInterfaceImpl (SynInterfaceImpl(_, bindings, _)) = List.iter walkBinding bindings and walkType = function | SynType.Array (_, t, _) @@ -480,7 +482,7 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b walkType t; List.iter walkTypeConstraint typeConstraints | _ -> () - and walkClause (Clause (pat, e1, e2, _, _)) = + and walkClause (SynMatchClause (pat, e1, _, e2, _, _)) = walkPat pat walkExpr e2 e1 |> Option.iter walkExpr @@ -503,13 +505,13 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b | SynExpr.AddressOf (_, e, _, _) | SynExpr.DoBang (e, _) | SynExpr.YieldOrReturn (_, e, _) - | SynExpr.ArrayOrListOfSeqExpr (_, e, _) - | SynExpr.CompExpr (_, _, e, _) + | SynExpr.ArrayOrListComputed (_, e, _) + | SynExpr.ComputationExpr (_, e, _) | SynExpr.Do (e, _) | SynExpr.Assert (e, _) | SynExpr.Lazy (e, _) | SynExpr.YieldOrReturnFrom (_, e, _) -> walkExpr e - | SynExpr.Lambda (_, _, pats, e, _, _) -> + | SynExpr.Lambda (_, _, pats, _, e, _, _) -> walkSimplePats pats walkExpr e | SynExpr.New (_, t, e, _) @@ -547,7 +549,7 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b List.iter walkBinding bindings; walkExpr e | SynExpr.TryWith (e, _, clauses, _, _, _, _) -> List.iter walkClause clauses; walkExpr e - | SynExpr.IfThenElse (e1, e2, e3, _, _, _, _) -> + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3, _, _, _, _) -> List.iter walkExpr [e1; e2] e3 |> Option.iter walkExpr | SynExpr.LongIdentSet (ident, e, _) @@ -558,10 +560,10 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b walkExpr e2 | SynExpr.DotIndexedGet (e, args, _, _) -> walkExpr e - List.iter walkIndexerArg args + walkExpr args | SynExpr.DotIndexedSet (e1, args, e2, _, _, _) -> walkExpr e1 - List.iter walkIndexerArg args + walkExpr args walkExpr e2 | SynExpr.NamedIndexedPropertySet (ident, e1, e2, _) -> List.iter walkExpr [e1; e2] @@ -579,7 +581,7 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b List.iter walkTypar ts walkMemberSig sign walkExpr e - | SynExpr.Const (SynConst.Measure(_, m), _) -> walkMeasure m + | SynExpr.Const (SynConst.Measure(_, _, m), _) -> walkMeasure m | _ -> () and walkMeasure = function @@ -602,11 +604,11 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b walkType t | _ -> () - and walkField (SynField.Field(AllAttrs attrs, _, _, t, _, _, _, _)) = + and walkField (SynField(AllAttrs attrs, _, _, t, _, _, _, _)) = List.iter walkAttribute attrs walkType t - and walkValSig (SynValSig.ValSpfn(AllAttrs attrs, _, _, t, SynValInfo(argInfos, argInfo), _, _, _, _, _, _)) = + and walkValSig (SynValSig(AllAttrs attrs, _, _, t, SynValInfo(argInfos, argInfo), _, _, _, _, _, _)) = List.iter walkAttribute attrs walkType t argInfo :: (argInfos |> List.concat) @@ -618,12 +620,12 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b | SynMemberSig.Interface(t, _) -> walkType t | SynMemberSig.Member(vs, _, _) -> walkValSig vs | SynMemberSig.ValField(f, _) -> walkField f - | SynMemberSig.NestedType(SynTypeDefnSig.TypeDefnSig (info, repr, memberSigs, _), _) -> + | SynMemberSig.NestedType(SynTypeDefnSig (info, repr, memberSigs, _), _) -> let isTypeExtensionOrAlias = match repr with | SynTypeDefnSigRepr.Simple(SynTypeDefnSimpleRepr.TypeAbbrev _, _) - | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.TyconAbbrev, _, _) - | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.TyconAugmentation, _, _) -> true + | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.Abbrev, _, _) + | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.Augmentation, _, _) -> true | _ -> false walkComponentInfo isTypeExtensionOrAlias info walkTypeDefnSigRepr repr @@ -649,13 +651,13 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b walkExpr e | _ -> () - and walkEnumCase (EnumCase(AllAttrs attrs, _, _, _, _)) = List.iter walkAttribute attrs + and walkEnumCase (SynEnumCase(AllAttrs attrs, _, _, _, _, _)) = List.iter walkAttribute attrs and walkUnionCaseType = function - | SynUnionCaseType.UnionCaseFields fields -> List.iter walkField fields - | SynUnionCaseType.UnionCaseFullType (t, _) -> walkType t + | SynUnionCaseKind.Fields fields -> List.iter walkField fields + | SynUnionCaseKind.FullType (t, _) -> walkType t - and walkUnionCase (SynUnionCase.UnionCase (AllAttrs attrs, _, t, _, _, _)) = + and walkUnionCase (SynUnionCase (AllAttrs attrs, _, t, _, _, _)) = List.iter walkAttribute attrs walkUnionCaseType t @@ -666,9 +668,9 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b | SynTypeDefnSimpleRepr.TypeAbbrev (_, t, _) -> walkType t | _ -> () - and walkComponentInfo isTypeExtensionOrAlias (ComponentInfo(AllAttrs attrs, typars, constraints, longIdent, _, _, _, _)) = + and walkComponentInfo isTypeExtensionOrAlias (SynComponentInfo(AllAttrs attrs, typars, constraints, longIdent, _, _, _, _)) = List.iter walkAttribute attrs - List.iter walkTyparDecl typars + Option.iter walkTyparDecls typars List.iter walkTypeConstraint constraints and walkTypeDefnRepr = function @@ -681,15 +683,16 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b | SynTypeDefnSigRepr.Simple(defn, _) -> walkTypeDefnSimple defn | SynTypeDefnSigRepr.Exception _ -> () - and walkTypeDefn (TypeDefn (info, repr, members, _)) = + and walkTypeDefn (SynTypeDefn (info, repr, members, implicitCtor, _)) = let isTypeExtensionOrAlias = match repr with - | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAugmentation, _, _) - | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAbbrev, _, _) + | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Augmentation, _, _) + | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Abbrev, _, _) | SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.TypeAbbrev _, _) -> true | _ -> false walkComponentInfo isTypeExtensionOrAlias info walkTypeDefnRepr repr + Option.iter walkMember implicitCtor List.iter walkMember members and walkSynModuleDecl (decl: SynModuleDecl) = @@ -705,14 +708,14 @@ let internal isTypedBindingAtPosition (input: ParsedInput option) (r: Range) : b | _ -> () match input with - | Some (ParsedInput.ImplFile input) -> + | ParsedInput.ImplFile input -> walkImplFileInput input | _ -> () //debug "%A" idents result /// Gives all ranges for current position -let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range list = +let internal getRangesAtPosition input (r: Position) : Range list = let mutable result = [] @@ -739,9 +742,16 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li addIfInside attr.Range walkExpr attr.ArgExpr - and walkTyparDecl (SynTyparDecl.TyparDecl (AllAttrs attrs, typar)) = + and walkTyparDecl (SynTyparDecl (AllAttrs attrs, typar)) = List.iter walkAttribute attrs walkTypar typar + + and walkTyparDecls (typars: SynTyparDecls) = + typars.TyparDecls |> List.iter walkTyparDecl + typars.Constraints |> List.iter walkTypeConstraint + + and walkSynValTyparDecls (SynValTyparDecls(typars, _)) = + Option.iter walkTyparDecls typars and walkTypeConstraint = function | SynTypeConstraint.WhereTyparIsValueType (t, r) @@ -770,9 +780,8 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynPat.Ands (pats, r) -> addIfInside r List.iter walkPat pats - | SynPat.Named (pat, ident, _, _, r) -> + | SynPat.Named (ident, _, _, r) -> addIfInside r - walkPat pat | SynPat.Typed (pat, t, r) -> addIfInside r walkPat pat @@ -786,10 +795,7 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li List.iter walkPat [pat1; pat2] | SynPat.LongIdent (ident, _, typars, ConstructorPats pats, _, r) -> addIfInside r - typars - |> Option.iter (fun (SynValTyparDecls (typars, _, constraints)) -> - List.iter walkTyparDecl typars - List.iter walkTypeConstraint constraints) + Option.iter walkSynValTyparDecls typars List.iter walkPat pats | SynPat.Paren (pat, r) -> addIfInside r @@ -808,24 +814,24 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynPat.DeprecatedCharRange(_, _, r) -> addIfInside r | SynPat.InstanceMember(_, _, _, accessibility, r) -> addIfInside r | SynPat.FromParseError(_, r) ->addIfInside r + | SynPat.As(lpat, rpat, r) -> + addIfInside r + walkPat lpat + walkPat rpat - and walkTypar (Typar (_, _, _)) = () + and walkTypar (SynTypar (_, _, _)) = () - and walkBinding (SynBinding.Binding (_, _, _, _, AllAttrs attrs, _, _, pat, returnInfo, e, r, _)) = + and walkBinding (SynBinding (_, _, _, _, AllAttrs attrs, _, _, pat, returnInfo, e, r, _)) = addIfInside r List.iter walkAttribute attrs walkPat pat walkExpr e returnInfo |> Option.iter (fun (SynBindingReturnInfo (t, r, _)) -> addIfInside r; walkType t) - and walkInterfaceImpl (InterfaceImpl(_, bindings, r)) = + and walkInterfaceImpl (SynInterfaceImpl(_, bindings, r)) = addIfInside r List.iter walkBinding bindings - and walkIndexerArg = function - | SynIndexerArg.One(e,_fromEnd,_range) -> walkExpr e - | SynIndexerArg.Two(e1,_e1FromEnd,e2,_e2FromEnd,_e1Range,_e2Range) -> List.iter walkExpr [e1; e2] - and walkType = function | SynType.Array (_, t, r) | SynType.HashConstraint (t, r) @@ -860,7 +866,7 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li walkType innerType - and walkClause (Clause (pat, e1, e2, r, _)) = + and walkClause (SynMatchClause (pat, e1, _, e2, r, _)) = addIfInside r walkPat pat walkExpr e2 @@ -892,8 +898,8 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynExpr.AddressOf (_, e, _, r) | SynExpr.DoBang (e, r) | SynExpr.YieldOrReturn (_, e, r) - | SynExpr.ArrayOrListOfSeqExpr (_, e, r) - | SynExpr.CompExpr (_, _, e, r) + | SynExpr.ArrayOrListComputed (_, e, r) + | SynExpr.ComputationExpr (_, e, r) | SynExpr.Do (e, r) | SynExpr.Assert (e, r) | SynExpr.Lazy (e, r) @@ -905,7 +911,7 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li walkExpr e1 walkExpr e2 walkExpr ifNotE - | SynExpr.Lambda (_, _, pats, e, _, r) -> + | SynExpr.Lambda (_, _, pats, _, e, _, r) -> addIfInside r walkSimplePats pats walkExpr e @@ -960,7 +966,7 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynExpr.TryWith (e, _, clauses, r, _, _, _) -> addIfInside r List.iter walkClause clauses; walkExpr e - | SynExpr.IfThenElse (e1, e2, e3, _, _, _, r) -> + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3, _, _, _, r) -> addIfInside r List.iter walkExpr [e1; e2] e3 |> Option.iter walkExpr @@ -975,11 +981,11 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynExpr.DotIndexedGet (e, args, _, r) -> addIfInside r walkExpr e - List.iter walkIndexerArg args + walkExpr args | SynExpr.DotIndexedSet (e1, args, e2, _, _, r) -> addIfInside r walkExpr e1 - List.iter walkIndexerArg args + walkExpr args walkExpr e2 | SynExpr.NamedIndexedPropertySet (ident, e1, e2, r) -> addIfInside r @@ -1004,7 +1010,7 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li List.iter walkTypar ts walkMemberSig sign walkExpr e - | SynExpr.Const (SynConst.Measure(_, m), r) -> + | SynExpr.Const (SynConst.Measure(_, _, m), r) -> addIfInside r walkMeasure m | SynExpr.Const (_, r) -> @@ -1025,10 +1031,18 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynExpr.FromParseError(expr, r) -> addIfInside r | SynExpr.DiscardAfterMissingQualificationAfterDot(_, r) -> addIfInside r | SynExpr.Fixed(expr, r) -> addIfInside r - | SynExpr.InterpolatedString(parts, r) -> + | SynExpr.InterpolatedString(parts, kind, r) -> addIfInside r for part in parts do walkInterpolatedStringPart part + | SynExpr.IndexFromEnd(itemExpr, r) -> + addIfInside r + walkExpr itemExpr + | SynExpr.IndexRange(e1, _, e2, _, _, r) -> + addIfInside r + Option.iter walkExpr e1 + Option.iter walkExpr e2 + and walkMeasure = function | SynMeasure.Product (m1, m2, r) @@ -1060,12 +1074,12 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynSimplePat.Id(ident, altNameRefCell, isCompilerGenerated, isThisVar, isOptArg, r) -> addIfInside r - and walkField (SynField.Field(AllAttrs attrs, _, _, t, _, _, _, r)) = + and walkField (SynField(AllAttrs attrs, _, _, t, _, _, _, r)) = addIfInside r List.iter walkAttribute attrs walkType t - and walkValSig (SynValSig.ValSpfn(AllAttrs attrs, _, _, t, SynValInfo(argInfos, argInfo), _, _, _, _, _, r)) = + and walkValSig (SynValSig(AllAttrs attrs, _, _, t, SynValInfo(argInfos, argInfo), _, _, _, _, _, r)) = addIfInside r List.iter walkAttribute attrs walkType t @@ -1084,13 +1098,13 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynMemberSig.ValField(f, r) -> addIfInside r walkField f - | SynMemberSig.NestedType(SynTypeDefnSig.TypeDefnSig (info, repr, memberSigs, _), r) -> + | SynMemberSig.NestedType(SynTypeDefnSig (info, repr, memberSigs, _), r) -> addIfInside r let isTypeExtensionOrAlias = match repr with | SynTypeDefnSigRepr.Simple(SynTypeDefnSimpleRepr.TypeAbbrev _, _) - | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.TyconAbbrev, _, _) - | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.TyconAugmentation, _, _) -> true + | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.Abbrev, _, _) + | SynTypeDefnSigRepr.ObjectModel(SynTypeDefnKind.Augmentation, _, _) -> true | _ -> false walkComponentInfo isTypeExtensionOrAlias info walkTypeDefnSigRepr repr @@ -1133,15 +1147,15 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li walkExpr e | SynMemberDefn.Open(longId, r) -> addIfInside r - and walkEnumCase (EnumCase(AllAttrs attrs, _, _, _, r)) = + and walkEnumCase (SynEnumCase(AllAttrs attrs, _, _, _, _, r)) = addIfInside r List.iter walkAttribute attrs and walkUnionCaseType = function - | SynUnionCaseType.UnionCaseFields fields -> List.iter walkField fields - | SynUnionCaseType.UnionCaseFullType (t, _) -> walkType t + | SynUnionCaseKind.Fields fields -> List.iter walkField fields + | SynUnionCaseKind.FullType (t, _) -> walkType t - and walkUnionCase (SynUnionCase.UnionCase (AllAttrs attrs, _, t, _, _, r)) = + and walkUnionCase (SynUnionCase (AllAttrs attrs, _, t, _, _, r)) = addIfInside r List.iter walkAttribute attrs walkUnionCaseType t @@ -1164,10 +1178,10 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynTypeDefnSimpleRepr.None(r) -> addIfInside r | SynTypeDefnSimpleRepr.Exception(_) -> () - and walkComponentInfo isTypeExtensionOrAlias (ComponentInfo(AllAttrs attrs, typars, constraints, longIdent, _, _, _, r)) = + and walkComponentInfo isTypeExtensionOrAlias (SynComponentInfo(AllAttrs attrs, typars, constraints, longIdent, _, _, _, r)) = addIfInside r List.iter walkAttribute attrs - List.iter walkTyparDecl typars + Option.iter walkTyparDecls typars List.iter walkTypeConstraint constraints and walkTypeDefnRepr = function @@ -1184,16 +1198,17 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynTypeDefnSigRepr.Simple(defn, _) -> walkTypeDefnSimple defn | SynTypeDefnSigRepr.Exception _ -> () - and walkTypeDefn (TypeDefn (info, repr, members, r)) = + and walkTypeDefn (SynTypeDefn (info, repr, members, implicitCtor, r)) = addIfInside r let isTypeExtensionOrAlias = match repr with - | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAugmentation, _, _) - | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.TyconAbbrev, _, _) + | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Augmentation, _, _) + | SynTypeDefnRepr.ObjectModel (SynTypeDefnKind.Abbrev, _, _) | SynTypeDefnRepr.Simple (SynTypeDefnSimpleRepr.TypeAbbrev _, _) -> true | _ -> false walkComponentInfo isTypeExtensionOrAlias info walkTypeDefnRepr repr + Option.iter walkMember implicitCtor List.iter walkMember members and walkSynModuleDecl (decl: SynModuleDecl) = @@ -1221,8 +1236,8 @@ let internal getRangesAtPosition (input: ParsedInput option) (r: Pos) : Range li | SynModuleDecl.HashDirective(_, r) -> addIfInside r match input with - | Some (ParsedInput.ImplFile input) -> - walkImplFileInput input + | ParsedInput.ImplFile input -> + walkImplFileInput input | _ -> () //debug "%A" idents result @@ -1243,8 +1258,8 @@ let getQuotationRanges ast = | SynExpr.Typed (expr, _, _) | SynExpr.Paren (expr, _, _, _) | SynExpr.New (_, _, expr, _) - | SynExpr.ArrayOrListOfSeqExpr (_, expr, _) - | SynExpr.CompExpr (_, _, expr, _) + | SynExpr.ArrayOrListComputed (_, expr, _) + | SynExpr.ComputationExpr (_, expr, _) | SynExpr.ForEach (_, _, _, _, _, expr(*body*), _) | SynExpr.YieldOrReturn (_, expr, _) | SynExpr.YieldOrReturnFrom (_, expr, _) @@ -1263,7 +1278,7 @@ let getQuotationRanges ast = | SynExpr.Upcast (expr, _, _) | SynExpr.InferredUpcast (expr, _) | SynExpr.InferredDowncast (expr, _) - | SynExpr.Lambda (_, _, _, expr, _, _) + | SynExpr.Lambda (_, _, _, _, expr, _, _) | SynExpr.AddressOf (_, expr, _, _) -> visitExpr expr | SynExpr.App (_,_, expr1(*funcExpr*),expr2(*argExpr*), _) @@ -1282,7 +1297,7 @@ let getQuotationRanges ast = | SynExpr.TryWith (expr, _, clauses, _, _, _, _) | SynExpr.Match (_, expr, clauses, _) -> visitExpr expr; visitMatches clauses - | SynExpr.IfThenElse (cond, trueBranch, falseBranchOpt, _, _, _, _) -> + | SynExpr.IfThenElse (_, _, cond, _, trueBranch, _, falseBranchOpt, _, _, _, _) -> visitExpr cond; visitExpr trueBranch falseBranchOpt |> Option.iter visitExpr | SynExpr.LetOrUse (_, _, bindings, body, _) -> visitBindindgs bindings; visitExpr body @@ -1293,12 +1308,11 @@ let getQuotationRanges ast = fields |> List.choose (fun (_, expr, _) -> expr) |> List.iter visitExpr | _ -> () - and visitBinding (Binding(_, _, _, _, _, _, _, _, _, body, _, _)) = visitExpr body + and visitBinding (SynBinding(_, _, _, _, _, _, _, _, _, body, _, _)) = visitExpr body and visitBindindgs = List.iter visitBinding and visitPattern = function | SynPat.QuoteExpr (expr, _) -> visitExpr expr - | SynPat.Named (pat, _, _, _, _) | SynPat.Paren (pat, _) | SynPat.Typed (pat, _, _) -> visitPattern pat | SynPat.Ands (pats, _) @@ -1313,7 +1327,7 @@ let getQuotationRanges ast = | SynPat.Record(xs, _) -> xs |> List.map snd |> List.iter visitPattern | _ -> () - and visitMatch (SynMatchClause.Clause (pat, _, expr, _, _)) = visitPattern pat; visitExpr expr + and visitMatch (SynMatchClause (pat, _, _, expr, _, _)) = visitPattern pat; visitExpr expr and visitMatches = List.iter visitMatch @@ -1324,11 +1338,12 @@ let getQuotationRanges ast = | _ -> () let visitType ty = - let (SynTypeDefn.TypeDefn (_, repr, defns, _)) = ty + let (SynTypeDefn (_, repr, defns, implicitCtor, _)) = ty match repr with | SynTypeDefnRepr.ObjectModel (_, objDefns, _) -> for d in objDefns do visitMember d | _ -> () + Option.iter visitMember implicitCtor for d in defns do visitMember d let rec visitDeclarations decls = @@ -1355,13 +1370,13 @@ let internal getStringLiterals ast : Range list = let visitType ty = match ty with - | SynType.StaticConstant (SynConst.String(_, r), _) -> result.Add r + | SynType.StaticConstant (SynConst.String(_, _, r), _) -> result.Add r | _ -> () let rec visitExpr = function - | SynExpr.ArrayOrListOfSeqExpr (_, expr, _) - | SynExpr.CompExpr (_, _, expr, _) - | SynExpr.Lambda (_, _, _, expr, _, _) + | SynExpr.ArrayOrListComputed (_, expr, _) + | SynExpr.ComputationExpr (_, expr, _) + | SynExpr.Lambda (_, _, _, _, expr, _, _) | SynExpr.YieldOrReturn (_, expr, _) | SynExpr.YieldOrReturnFrom (_, expr, _) | SynExpr.New (_, _, expr, _) @@ -1397,7 +1412,7 @@ let internal getStringLiterals ast : Range list = | SynExpr.Match (_, expr, clauses, _) | SynExpr.TryWith(expr, _, clauses, _, _, _, _) -> visitExpr expr; visitMatches clauses - | SynExpr.IfThenElse(cond, trueBranch, falseBranchOpt, _, _, _, _) -> + | SynExpr.IfThenElse(_, _, cond, _, trueBranch, _, falseBranchOpt, _, _, _, _) -> visitExpr cond visitExpr trueBranch falseBranchOpt |> Option.iter visitExpr @@ -1408,13 +1423,13 @@ let internal getStringLiterals ast : Range list = fields |> List.choose (fun (_, expr, _) -> expr) |> List.iter visitExpr | SynExpr.MatchLambda (_, _, clauses, _, _) -> visitMatches clauses | SynExpr.ObjExpr (_, _, bindings, _, _ , _) -> visitBindindgs bindings - | SynExpr.Const (SynConst.String (_, r), _) -> result.Add r + | SynExpr.Const (SynConst.String (_, _, r), _) -> result.Add r | SynExpr.TypeApp(_, _, tys, _, _, _, _) -> List.iter visitType tys | _ -> () - and visitBinding (Binding(_, _, _, _, _, _, _, _, _, body, _, _)) = visitExpr body + and visitBinding (SynBinding(_, _, _, _, _, _, _, _, _, body, _, _)) = visitExpr body and visitBindindgs = List.iter visitBinding - and visitMatch (SynMatchClause.Clause (_, _, expr, _, _)) = visitExpr expr + and visitMatch (SynMatchClause (_, _, _, expr, _, _)) = visitExpr expr and visitMatches = List.iter visitMatch let visitMember = function @@ -1424,13 +1439,14 @@ let internal getStringLiterals ast : Range list = | _ -> () let visitTypeDefn ty = - let (SynTypeDefn.TypeDefn (_, repr, memberDefns, _)) = ty + let (SynTypeDefn (_, repr, memberDefns, implicitCtor, _)) = ty match repr with | SynTypeDefnRepr.ObjectModel (_, defns, _) -> for d in defns do visitMember d | SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.TypeAbbrev(_, SynType.App(_, _, tys, _,_ , _, _), _), _) -> List.iter visitType tys | _ -> () + Option.iter visitMember implicitCtor List.iter visitMember memberDefns let rec visitDeclarations decls = @@ -1453,7 +1469,7 @@ let internal getStringLiterals ast : Range list = List.ofSeq result /// Get path to containing module/namespace of a given position -let getModuleOrNamespacePath (pos: Pos) (ast: ParsedInput) = +let getModuleOrNamespacePath (pos: Position) (ast: ParsedInput) = let idents = match ast with | ParsedInput.ImplFile (ParsedImplFileInput(_, _, _, _, _, modules, _)) -> @@ -1461,9 +1477,9 @@ let getModuleOrNamespacePath (pos: Pos) (ast: ParsedInput) = decls |> List.fold (fun acc -> function - | SynModuleDecl.NestedModule (componentInfo, _, nestedModuleDecls, _, nestedModuleRange) -> + | SynModuleDecl.NestedModule (componentInfo, _, nestedModuleDecls, _, nestedModuleRange) -> if Range.rangeContainsPos moduleRange pos then - let (ComponentInfo(_,_,_,longIdent,_,_,_,_)) = componentInfo + let (SynComponentInfo(_,_,_,longIdent,_,_,_,_)) = componentInfo walkModuleOrNamespace (longIdent::acc) (nestedModuleDecls, nestedModuleRange) else acc | _ -> acc) idents @@ -1480,7 +1496,7 @@ let getModuleOrNamespacePath (pos: Pos) (ast: ParsedInput) = function | SynModuleSigDecl.NestedModule (componentInfo, _, nestedModuleDecls, nestedModuleRange) -> if Range.rangeContainsPos moduleRange pos then - let (ComponentInfo(_,_,_,longIdent,_,_,_,_)) = componentInfo + let (SynComponentInfo(_,_,_,longIdent,_,_,_,_)) = componentInfo walkModuleOrNamespaceSig (longIdent::acc) (nestedModuleDecls, nestedModuleRange) else acc | _ -> acc) idents @@ -1540,6 +1556,10 @@ module HashDirectiveInfo = else directory + let (|StringDirective|_|) (p: ParsedHashDirectiveArgument) = + match p with + | ParsedHashDirectiveArgument.String(v, _, _) -> Some v + | _ -> None // separate function to reduce nesting one level let parseDirectives modules file = [| @@ -1547,7 +1567,7 @@ module HashDirectiveInfo = for (SynModuleOrNamespace (_, _, _, declarations, _, _, _, _)) in modules do for decl in declarations do match decl with - | SynModuleDecl.HashDirective (ParsedHashDirective("I",[directory],range),_) -> + | SynModuleDecl.HashDirective (ParsedHashDirective("I",[StringDirective directory],range),_) -> let directory = makeRootedDirectoryIfNecessary (getDirectoryOfFile file) directory if directoryExists directory then @@ -1557,32 +1577,35 @@ module HashDirectiveInfo = | SynModuleDecl.HashDirective (ParsedHashDirective ("load",files,range),_) -> for f in files do - if isPathRooted f && fileExists f then + match f with + | StringDirective f -> + if isPathRooted f && fileExists f then - // this is absolute reference to an existing script, easiest case - yield Load (ExistingFile f, range) - - else - // I'm not sure if the order is correct, first checking relative to file containing the #load directive - // then checking for undocumented resolution using previously parsed #I directives - let fileRelativeToCurrentFile = baseDirectory f - if fileExists fileRelativeToCurrentFile then - // this is existing file relative to current file - yield Load (ExistingFile fileRelativeToCurrentFile, range) + // this is absolute reference to an existing script, easiest case + yield Load (ExistingFile f, range) else - // match file against first include which seemingly have it found - let maybeFile = - includesSoFar - |> Seq.tryPick (function - | (ResolvedDirectory d) -> - let filePath = d f - if fileExists filePath then Some filePath else None - ) - match maybeFile with - | None -> () // can't load this file even using any of the #I directives... - | Some f -> - yield Load (ExistingFile f,range) + // I'm not sure if the order is correct, first checking relative to file containing the #load directive + // then checking for undocumented resolution using previously parsed #I directives + let fileRelativeToCurrentFile = baseDirectory f + if fileExists fileRelativeToCurrentFile then + // this is existing file relative to current file + yield Load (ExistingFile fileRelativeToCurrentFile, range) + + else + // match file against first include which seemingly have it found + let maybeFile = + includesSoFar + |> Seq.tryPick (function + | (ResolvedDirectory d) -> + let filePath = d f + if fileExists filePath then Some filePath else None + ) + match maybeFile with + | None -> () // can't load this file even using any of the #I directives... + | Some f -> + yield Load (ExistingFile f,range) + | _ -> () | _ -> () |] @@ -1591,7 +1614,7 @@ module HashDirectiveInfo = | _ -> [||] /// returns the Some (complete file name of a resolved #load directive at position) or None - let getHashLoadDirectiveResolvedPathAtPosition (pos: Pos) (ast: ParsedInput) : string option = + let getHashLoadDirectiveResolvedPathAtPosition (pos: Position) (ast: ParsedInput) : string option = getIncludeAndLoadDirectives ast |> Array.tryPick ( function @@ -1638,15 +1661,11 @@ module Printf = | SynTypeConstraint.WhereTyparSupportsMember (_, sign, _) -> walkMemberSig sign | _ -> () - and walkBinding (SynBinding.Binding (_, _, _, _, _, _, _, _, returnInfo, e, _, _)) = + and walkBinding (SynBinding (_, _, _, _, _, _, _, _, returnInfo, e, _, _)) = walkExpr e returnInfo |> Option.iter (fun (SynBindingReturnInfo (t, _, _)) -> walkType t) - and walkInterfaceImpl (InterfaceImpl(_, bindings, _)) = List.iter walkBinding bindings - - and walkIndexerArg = function - | SynIndexerArg.One(e,_fromEnd,_range) -> walkExpr e - | SynIndexerArg.Two(e1,_e1FromEnd,e2,_e2FromEnd,_e1Range,_e2Range) -> List.iter walkExpr [e1; e2] + and walkInterfaceImpl (SynInterfaceImpl(_, bindings, _)) = List.iter walkBinding bindings and walkType = function | SynType.Array (_, t, _) @@ -1661,7 +1680,7 @@ module Printf = walkType t; List.iter walkTypeConstraint typeConstraints | _ -> () - and walkClause (Clause (_, e1, e2, _, _)) = + and walkClause (SynMatchClause (_, e1, _, e2, _, _)) = walkExpr e2 e1 |> Option.iter walkExpr @@ -1673,7 +1692,7 @@ module Printf = and walkExpr e = match e with - | SynExpr.App (_, _, SynExpr.Ident _, SynExpr.Const (SynConst.String (_, stringRange), _), r) -> + | SynExpr.App (_, _, SynExpr.Ident _, SynExpr.Const (SynConst.String (_, _, stringRange), _), r) -> match !appStack with | (lastApp :: _) as apps when Range.rangeContainsRange lastApp.Range e.Range -> let intersectsWithFuncOrString (arg: Range) = @@ -1715,12 +1734,12 @@ module Printf = | _ -> () addAppWithArg { Range = e.Range; Arg = e2.Range } - if op.idText = (SourceCodeServices.PrettyNaming.CompileOpName "||>") - || op.idText = (SourceCodeServices.PrettyNaming.CompileOpName "|||>") then + if op.idText = (PrettyNaming.CompileOpName "||>") + || op.idText = (PrettyNaming.CompileOpName "|||>") then deconstruct e1 walkExpr e2 else - if op.idText = (SourceCodeServices.PrettyNaming.CompileOpName "|>") then + if op.idText = (PrettyNaming.CompileOpName "|>") then addAppWithArg { Range = e.Range; Arg = e1.Range } walkExpr e2 walkExpr e1 @@ -1743,13 +1762,13 @@ module Printf = | SynExpr.AddressOf (_, e, _, _) | SynExpr.DoBang (e, _) | SynExpr.YieldOrReturn (_, e, _) - | SynExpr.ArrayOrListOfSeqExpr (_, e, _) - | SynExpr.CompExpr (_, _, e, _) + | SynExpr.ArrayOrListComputed (_, e, _) + | SynExpr.ComputationExpr (_, e, _) | SynExpr.Do (e, _) | SynExpr.Assert (e, _) | SynExpr.Lazy (e, _) | SynExpr.YieldOrReturnFrom (_, e, _) -> walkExpr e - | SynExpr.Lambda (_, _, pats, e, _, _) -> + | SynExpr.Lambda (_, _, pats, _, e, _, _) -> walkSimplePats pats walkExpr e | SynExpr.New (_, t, e, _) @@ -1781,7 +1800,7 @@ module Printf = List.iter walkBinding bindings; walkExpr e | SynExpr.TryWith (e, _, clauses, _, _, _, _) -> List.iter walkClause clauses; walkExpr e - | SynExpr.IfThenElse (e1, e2, e3, _, _, _, _) -> + | SynExpr.IfThenElse (_, _, e1, _, e2, _, e3, _, _, _, _) -> List.iter walkExpr [e1; e2] e3 |> Option.iter walkExpr | SynExpr.LongIdentSet (_, e, _) @@ -1791,10 +1810,10 @@ module Printf = walkExpr e2 | SynExpr.DotIndexedGet (e, args, _, _) -> walkExpr e - List.iter walkIndexerArg args + walkExpr args | SynExpr.DotIndexedSet (e1, args, e2, _, _, _) -> walkExpr e1 - List.iter walkIndexerArg args + walkExpr args walkExpr e2 | SynExpr.NamedIndexedPropertySet (_, e1, e2, _) -> List.iter walkExpr [e1; e2] | SynExpr.DotNamedIndexedPropertySet (e1, _, e2, e3, _) -> List.iter walkExpr [e1; e2; e3] @@ -1807,7 +1826,7 @@ module Printf = | SynExpr.TraitCall (_, sign, e, _) -> walkMemberSig sign walkExpr e - | SynExpr.Const (SynConst.Measure(_, m), _) -> walkMeasure m + | SynExpr.Const (SynConst.Measure(_, _, m), _) -> walkMeasure m | _ -> () and walkMeasure = function @@ -1825,13 +1844,13 @@ module Printf = | SynSimplePat.Typed(_, t, _) -> walkType t | _ -> () - and walkField (SynField.Field(_, _, _, t, _, _, _, _)) = walkType t + and walkField (SynField(_, _, _, t, _, _, _, _)) = walkType t and walkMemberSig = function | SynMemberSig.Inherit (t, _) | SynMemberSig.Interface(t, _) -> walkType t | SynMemberSig.ValField(f, _) -> walkField f - | SynMemberSig.NestedType(SynTypeDefnSig.TypeDefnSig (_, repr, memberSigs, _), _) -> + | SynMemberSig.NestedType(SynTypeDefnSig (_, repr, memberSigs, _), _) -> walkTypeDefnSigRepr repr List.iter walkMemberSig memberSigs | SynMemberSig.Member _ -> () @@ -1862,8 +1881,9 @@ module Printf = | SynTypeDefnSigRepr.Simple _ -> () | SynTypeDefnSigRepr.Exception _ -> () - and walkTypeDefn (TypeDefn (_, repr, members, _)) = + and walkTypeDefn (SynTypeDefn (_, repr, members, implicitCtor, _)) = walkTypeDefnRepr repr + Option.iter walkMember implicitCtor List.iter walkMember members and walkSynModuleDecl (decl: SynModuleDecl) = @@ -1890,16 +1910,16 @@ module Completion = | StringLiteral | Unknown - let atPos (pos: Pos, ast: ParsedInput): Context = + let atPos (pos: Position, ast: ParsedInput): Context = let visitor = - { new SourceCodeServices.AstTraversal.AstVisitorBase() with + { new SyntaxVisitorBase() with member x.VisitExpr(path, traverseExpr, defaultTraverse, expr): Context option = if Range.rangeContainsPos expr.Range pos then match expr with | SynExpr.Const(SynConst.String _, _) -> Some Context.StringLiteral - | SynExpr.InterpolatedString (parts, _) -> + | SynExpr.InterpolatedString (parts, _, _) -> parts |> List.tryPick ( function | SynInterpolatedStringPart.String(s, m) when Range.rangeContainsPos m pos -> Some Context.StringLiteral @@ -1910,5 +1930,5 @@ module Completion = | _ -> defaultTraverse expr else None } - FSharp.Compiler.SourceCodeServices.AstTraversal.Traverse(pos, ast, visitor) + SyntaxTraversal.Traverse(pos, ast, visitor) |> Option.defaultValue Context.Unknown diff --git a/src/FsAutoComplete.Core/UnusedDeclarationsAnalyzer.fs b/src/FsAutoComplete.Core/UnusedDeclarationsAnalyzer.fs index 901debc73..219770720 100644 --- a/src/FsAutoComplete.Core/UnusedDeclarationsAnalyzer.fs +++ b/src/FsAutoComplete.Core/UnusedDeclarationsAnalyzer.fs @@ -2,7 +2,8 @@ namespace FsAutoComplete open FsAutoComplete -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Symbols +open FSharp.Compiler.CodeAnalysis module UnusedDeclarationsAnalyzer = open System.Collections.Generic @@ -41,7 +42,7 @@ module UnusedDeclarationsAnalyzer = let unusedRanges = definitions |> Seq.map (fun defSu -> defSu, usages.Contains defSu.Symbol.DeclarationLocation.Value) - |> Seq.groupBy (fun (defSu, _) -> defSu.RangeAlternate) + |> Seq.groupBy (fun (defSu, _) -> defSu.Range) |> Seq.filter (fun (_, defSus) -> defSus |> Seq.forall (fun (_, isUsed) -> not isUsed)) |> Seq.choose (fun (range, defSus) -> diff --git a/src/FsAutoComplete.Core/Utils.fs b/src/FsAutoComplete.Core/Utils.fs index fe0d8db94..595ca35c8 100644 --- a/src/FsAutoComplete.Core/Utils.fs +++ b/src/FsAutoComplete.Core/Utils.fs @@ -6,7 +6,7 @@ open System.Threading.Tasks open System.IO open System.Collections.Concurrent open System -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis open FSharp.UMX module Map = diff --git a/src/FsAutoComplete/CodeFixes.fs b/src/FsAutoComplete/CodeFixes.fs index 16beaecdb..813ca8f18 100644 --- a/src/FsAutoComplete/CodeFixes.fs +++ b/src/FsAutoComplete/CodeFixes.fs @@ -12,7 +12,7 @@ open FSharp.Compiler.Text module FcsRange = FSharp.Compiler.Text.Range type FcsRange = FSharp.Compiler.Text.Range -type FcsPos = FSharp.Compiler.Text.Pos +type FcsPos = FSharp.Compiler.Text.Position module LspTypes = LanguageServerProtocol.Types @@ -22,8 +22,8 @@ module Types = type GetRangeText = string -> LspTypes.Range -> ResultOrString type GetFileLines = string -> ResultOrString type GetLineText = FSharp.Compiler.Text.ISourceText -> LspTypes.Range -> Result - type GetParseResultsForFile = string -> FSharp.Compiler.Text.Pos -> Async> - type GetProjectOptionsForFile = string -> ResultOrString + type GetParseResultsForFile = string -> FSharp.Compiler.Text.Position -> Async> + type GetProjectOptionsForFile = string -> ResultOrString [] type FixKind = @@ -88,7 +88,7 @@ module Navigation = if pos <= runningLength + lineLength then let column = pos - runningLength found <- true - fcsPos <- FSharp.Compiler.Text.Pos.mkPos lineNumber column + fcsPos <- FSharp.Compiler.Text.Position.mkPos lineNumber column else lineNumber <- lineNumber + 1 runningLength <- runningLength + lineLength diff --git a/src/FsAutoComplete/CodeFixes/AddExplicitTypeToParameter.fs b/src/FsAutoComplete/CodeFixes/AddExplicitTypeToParameter.fs index fe7461c12..6a74e7757 100644 --- a/src/FsAutoComplete/CodeFixes/AddExplicitTypeToParameter.fs +++ b/src/FsAutoComplete/CodeFixes/AddExplicitTypeToParameter.fs @@ -6,8 +6,10 @@ open FsAutoComplete.CodeFix.Types open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Symbols open FsAutoComplete.FCSPatches +open FSharp.Compiler.Syntax let fix (getParseResultsForFile: GetParseResultsForFile): CodeFix = fun codeActionParams -> @@ -27,21 +29,21 @@ let fix (getParseResultsForFile: GetParseResultsForFile): CodeFix = // TODO: remove patched functions and uncomment this boolean check after FCS 40 update let isLambdaIfFunction = // funcOrValue.IsFunction && - parseFileResults.IsBindingALambdaAtPositionPatched symbolUse.RangeAlternate.Start + parseFileResults.IsBindingALambdaAtPositionPatched symbolUse.Range.Start (funcOrValue.IsValue || isLambdaIfFunction) && - parseFileResults.IsPositionContainedInACurriedParameter symbolUse.RangeAlternate.Start && - not (parseFileResults.IsTypeAnnotationGivenAtPositionPatched symbolUse.RangeAlternate.Start) && + parseFileResults.IsPositionContainedInACurriedParameter symbolUse.Range.Start && + not (parseFileResults.IsTypeAnnotationGivenAtPositionPatched symbolUse.Range.Start) && not funcOrValue.IsMember && not funcOrValue.IsMemberThisValue && not funcOrValue.IsConstructorThisValue && - not (PrettyNaming.IsOperatorName funcOrValue.DisplayName) + not (PrettyNaming.IsOperatorDisplayName funcOrValue.DisplayName) match symbolUse.Symbol with | :? FSharpMemberOrFunctionOrValue as v when isValidParameterWithoutTypeAnnotation v symbolUse -> let typeString = v.FullType.Format symbolUse.DisplayContext let title = "Add explicit type annotation" - let fcsSymbolRange = symbolUse.RangeAlternate + let fcsSymbolRange = symbolUse.Range let protocolSymbolRange = fcsRangeToLsp fcsSymbolRange let! symbolText = sourceText.GetText(fcsSymbolRange) diff --git a/src/FsAutoComplete/CodeFixes/AddMissingFunKeyword.fs b/src/FsAutoComplete/CodeFixes/AddMissingFunKeyword.fs index 4ca4f8e56..5450969b8 100644 --- a/src/FsAutoComplete/CodeFixes/AddMissingFunKeyword.fs +++ b/src/FsAutoComplete/CodeFixes/AddMissingFunKeyword.fs @@ -50,7 +50,7 @@ let fix (getFileLines: GetFileLines) (getLineText: GetLineText): CodeFix = match Lexer.getSymbol fcsPos.Line fcsPos.Column line SymbolLookupKind.Fuzzy [||] with | Some lexSym -> let fcsStartPos = - FSharp.Compiler.Text.Pos.mkPos lexSym.Line lexSym.LeftColumn + FSharp.Compiler.Text.Position.mkPos lexSym.Line lexSym.LeftColumn let symbolStartRange = fcsPosToProtocolRange fcsStartPos diff --git a/src/FsAutoComplete/CodeFixes/AddMissingRecKeyword.fs b/src/FsAutoComplete/CodeFixes/AddMissingRecKeyword.fs index e4e77ef05..78a6de66f 100644 --- a/src/FsAutoComplete/CodeFixes/AddMissingRecKeyword.fs +++ b/src/FsAutoComplete/CodeFixes/AddMissingRecKeyword.fs @@ -50,10 +50,10 @@ let fix (getFileLines: GetFileLines) (getLineText: GetLineText): CodeFix = match Lexer.getSymbol fcsPos.Line fcsPos.Column line SymbolLookupKind.Fuzzy [||] with | Some lexSym -> let fcsStartPos = - FSharp.Compiler.Text.Pos.mkPos lexSym.Line lexSym.LeftColumn + FSharp.Compiler.Text.Position.mkPos lexSym.Line lexSym.LeftColumn let fcsEndPos = - FSharp.Compiler.Text.Pos.mkPos lexSym.Line lexSym.RightColumn + FSharp.Compiler.Text.Position.mkPos lexSym.Line lexSym.RightColumn let protocolRange = fcsRangeToLsp (FSharp.Compiler.Text.Range.mkRange (UMX.untag fileName) fcsStartPos fcsEndPos) diff --git a/src/FsAutoComplete/CodeFixes/AddTypeToIndeterminateValue.fs b/src/FsAutoComplete/CodeFixes/AddTypeToIndeterminateValue.fs index 7d3e82316..6c66abf70 100644 --- a/src/FsAutoComplete/CodeFixes/AddTypeToIndeterminateValue.fs +++ b/src/FsAutoComplete/CodeFixes/AddTypeToIndeterminateValue.fs @@ -5,7 +5,8 @@ open FsAutoComplete.CodeFix.Types open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols /// fix inderminate type errors by adding an explicit type to a value let fix @@ -22,7 +23,7 @@ let fix let! (tyRes, line, lines) = getParseResultsForFile typedFileName fcsRange.Start let! (endColumn, identIslands) = Lexer.findLongIdents(fcsRange.Start.Column, line) |> Result.ofOption (fun _ -> "No long ident at position") match tyRes.GetCheckResults.GetDeclarationLocation(fcsRange.Start.Line, endColumn, line, List.ofArray identIslands) with - | FSharpFindDeclResult.DeclFound declRange when declRange.FileName = filename -> + | FindDeclResult.DeclFound declRange when declRange.FileName = filename -> let! projectOptions = getProjectOptionsForFile typedFileName let protocolDeclRange = fcsRangeToLsp declRange let! declText = lines.GetText declRange diff --git a/src/FsAutoComplete/CodeFixes/ChangeComparisonToMutableAssignment.fs b/src/FsAutoComplete/CodeFixes/ChangeComparisonToMutableAssignment.fs index fad1b02a7..8b1c4a484 100644 --- a/src/FsAutoComplete/CodeFixes/ChangeComparisonToMutableAssignment.fs +++ b/src/FsAutoComplete/CodeFixes/ChangeComparisonToMutableAssignment.fs @@ -6,7 +6,7 @@ open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.LspHelpers -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Symbols /// a codefix that changes equality checking to mutable assignment when the compiler thinks it's relevant let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = @@ -34,7 +34,7 @@ let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = // only do anything if the value is mutable | :? FSharpMemberOrFunctionOrValue as mfv when mfv.IsMutable || mfv.HasSetterMethod -> // try to find the '=' at from the start of the range - let endOfMutableValue = fcsPosToLsp symbol.RangeAlternate.End + let endOfMutableValue = fcsPosToLsp symbol.Range.End match walkForwardUntilCondition lines endOfMutableValue (fun c -> c = '=') with | Some equalsPos -> diff --git a/src/FsAutoComplete/CodeFixes/ChangeTypeOfNameToNameOf.fs b/src/FsAutoComplete/CodeFixes/ChangeTypeOfNameToNameOf.fs index 279245f95..84451368b 100644 --- a/src/FsAutoComplete/CodeFixes/ChangeTypeOfNameToNameOf.fs +++ b/src/FsAutoComplete/CodeFixes/ChangeTypeOfNameToNameOf.fs @@ -6,31 +6,28 @@ open FsAutoComplete.CodeFix.Types open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.SyntaxTree +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Syntax type FSharpParseFileResults with member this.TryRangeOfTypeofWithNameAndTypeExpr pos = - this.ParseTree - |> Option.bind (fun pt -> - AstTraversal.Traverse(pos, pt , { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_path, _, defaultTraverse, expr) = - match expr with - | SynExpr.DotGet(expr, _, _, range) -> - match expr with - | SynExpr.TypeApp(SynExpr.Ident(ident), _, typeArgs, _, _, _, _) -> - let onlyOneTypeArg = - match typeArgs with - | [] -> false - | [_] -> true - | _ -> false - if ident.idText = "typeof" && onlyOneTypeArg then - Some {| NamedIdentRange = typeArgs.Head.Range; FullExpressionRange = range |} - else - defaultTraverse expr - | _ -> defaultTraverse expr - | _ -> defaultTraverse expr }) - ) + SyntaxTraversal.Traverse(pos, this.ParseTree , { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_path, _, defaultTraverse, expr) = + match expr with + | SynExpr.DotGet(expr, _, _, range) -> + match expr with + | SynExpr.TypeApp(SynExpr.Ident(ident), _, typeArgs, _, _, _, _) -> + let onlyOneTypeArg = + match typeArgs with + | [] -> false + | [_] -> true + | _ -> false + if ident.idText = "typeof" && onlyOneTypeArg then + Some {| NamedIdentRange = typeArgs.Head.Range; FullExpressionRange = range |} + else + defaultTraverse expr + | _ -> defaultTraverse expr + | _ -> defaultTraverse expr }) let fix (getParseResultsForFile: GetParseResultsForFile): CodeFix = fun codeActionParams -> diff --git a/src/FsAutoComplete/CodeFixes/RemoveUnusedBinding.fs b/src/FsAutoComplete/CodeFixes/RemoveUnusedBinding.fs index 6aa47bff6..30ab3e277 100644 --- a/src/FsAutoComplete/CodeFixes/RemoveUnusedBinding.fs +++ b/src/FsAutoComplete/CodeFixes/RemoveUnusedBinding.fs @@ -7,14 +7,14 @@ open FsAutoComplete.CodeFix.Types open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers -open FSharp.Compiler.SourceCodeServices -open FSharp.Compiler.SyntaxTree +open FSharp.Compiler.CodeAnalysis +open FSharp.Compiler.Syntax open FSharp.Compiler.Text let posBetween (range: Range) tester = - Pos.posGeq tester range.Start // positions on this one are flipped to simulate Pos.posLte, because that doesn't exist - && Pos.posGeq range.End tester + Position.posGeq tester range.Start // positions on this one are flipped to simulate Pos.posLte, because that doesn't exist + && Position.posGeq range.End tester type private ReplacmentRangeResult = | FullBinding of bindingRange: Range @@ -22,49 +22,46 @@ type private ReplacmentRangeResult = type FSharpParseFileResults with member private this.TryRangeOfBindingWithHeadPatternWithPos (diagnosticRange: range) = - this.ParseTree - |> Option.bind (fun input -> - AstTraversal.Traverse(diagnosticRange.Start, input, { new AstTraversal.AstVisitorBase<_>() with - member _.VisitExpr(_, _, defaultTraverse, expr) = - defaultTraverse expr - override _.VisitPat(defaultTraverse, pat: SynPat) = - // if the diagnostic was for this specific pattern in its entirety, then we're don - if Range.equals pat.Range diagnosticRange then Some (Pattern diagnosticRange) - else - match pat with - | SynPat.Paren (inner, m) -> - // otherwise if the pattern inside a parens - if Range.rangeContainsRange m diagnosticRange - then - // explicitly matches - if Range.equals inner.Range diagnosticRange - // then return the range of the parens, so the entire pattern gets removed - then Some (Pattern m) - else defaultTraverse inner - else defaultTraverse inner - | pat -> defaultTraverse pat + SyntaxTraversal.Traverse(diagnosticRange.Start, this.ParseTree, { new SyntaxVisitorBase<_>() with + member _.VisitExpr(_, _, defaultTraverse, expr) = + defaultTraverse expr + override _.VisitPat(_, defaultTraverse, pat: SynPat) = + // if the diagnostic was for this specific pattern in its entirety, then we're don + if Range.equals pat.Range diagnosticRange then Some (Pattern diagnosticRange) + else + match pat with + | SynPat.Paren (inner, m) -> + // otherwise if the pattern inside a parens + if Range.rangeContainsRange m diagnosticRange + then + // explicitly matches + if Range.equals inner.Range diagnosticRange + // then return the range of the parens, so the entire pattern gets removed + then Some (Pattern m) + else defaultTraverse inner + else defaultTraverse inner + | pat -> defaultTraverse pat - override _.VisitBinding(defaultTraverse, binding) = - match binding with - | SynBinding.Binding(_, SynBindingKind.NormalBinding, _, _, _, _, _, pat, _, _, _, _) as binding -> - // walk the patterns in the binding first, to allow the parameter traversal a chance to fire - match defaultTraverse binding with - | None -> - // otherwise if the diagnostic was in this binding's head pattern then do teh replacement - if Range.rangeContainsRange binding.RangeOfHeadPat diagnosticRange then - Some (FullBinding binding.RangeOfBindingAndRhs) - else - // Check if it's an operator - match pat with - | SynPat.LongIdent(LongIdentWithDots([id], _), _, _, _, _, _) when id.idText.StartsWith("op_") -> - if Range.rangeContainsRange id.idRange diagnosticRange then - Some (FullBinding binding.RangeOfBindingAndRhs) - else - defaultTraverse binding - | _ -> defaultTraverse binding - | Some range -> Some range - | _ -> defaultTraverse binding }) - ) + override _.VisitBinding(_, defaultTraverse, binding) = + match binding with + | SynBinding(_, SynBindingKind.Normal, _, _, _, _, _, pat, _, _, _, _) as binding -> + // walk the patterns in the binding first, to allow the parameter traversal a chance to fire + match defaultTraverse binding with + | None -> + // otherwise if the diagnostic was in this binding's head pattern then do teh replacement + if Range.rangeContainsRange binding.RangeOfHeadPattern diagnosticRange then + Some (FullBinding binding.RangeOfBindingWithRhs) + else + // Check if it's an operator + match pat with + | SynPat.LongIdent(LongIdentWithDots([id], _), _, _, _, _, _) when id.idText.StartsWith("op_") -> + if Range.rangeContainsRange id.idRange diagnosticRange then + Some (FullBinding binding.RangeOfBindingWithRhs) + else + defaultTraverse binding + | _ -> defaultTraverse binding + | Some range -> Some range + | _ -> defaultTraverse binding }) let fix (getParseResults: GetParseResultsForFile): CodeFix = Run.ifDiagnosticByCode diff --git a/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs b/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs index 4640f8026..4abca8bf4 100644 --- a/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs +++ b/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs @@ -4,15 +4,15 @@ open LanguageServerProtocol.Types open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types open FsToolkit.ErrorHandling -open FSharp.Compiler.SourceCodeServices open FsAutoComplete.LspHelpers open FsAutoComplete open FSharp.Compiler.Text +open FSharp.Compiler.EditorServices type LineText = string /// a codefix the provides suggestions for opening modules or using qualified names when an identifier is found that needs qualification -let fix (getParseResultsForFile: GetParseResultsForFile) (getNamespaceSuggestions: ParseAndCheckResults -> FcsPos -> LineText -> Async * list>>) = +let fix (getParseResultsForFile: GetParseResultsForFile) (getNamespaceSuggestions: ParseAndCheckResults -> FcsPos -> LineText -> Async * list>>) = /// insert a line of text at a given line let insertLine line lineStr = @@ -21,11 +21,11 @@ let fix (getParseResultsForFile: GetParseResultsForFile) (getNamespaceSuggestion End = { Line = line; Character = 0 } } NewText = lineStr } - let adjustInsertionPoint (lines: ISourceText) (ctx: InsertContext) = + let adjustInsertionPoint (lines: ISourceText) (ctx: InsertionContext) = let l = ctx.Pos.Line match ctx.ScopeKind with - | TopModule when l > 1 -> + | ScopeKind.TopModule when l > 1 -> let line = lines.GetLineString (l - 2) let isImplicitTopLevelModule = @@ -34,7 +34,7 @@ let fix (getParseResultsForFile: GetParseResultsForFile) (getNamespaceSuggestion && not (line.EndsWith "=")) if isImplicitTopLevelModule then 1 else l - | TopModule -> 1 + | ScopeKind.TopModule -> 1 | ScopeKind.Namespace when l > 1 -> [ 0 .. l - 1 ] |> List.mapi (fun i line -> i, lines.GetLineString line) @@ -77,7 +77,7 @@ let fix (getParseResultsForFile: GetParseResultsForFile) (getNamespaceSuggestion let edits = [| yield insertLine docLine lineStr if text.GetLineString(docLine + 1).Trim() <> "" then yield insertLine (docLine + 1) "" - if (ctx.Pos.Column = 0 || ctx.ScopeKind = Namespace) + if (ctx.Pos.Column = 0 || ctx.ScopeKind = ScopeKind.Namespace) && docLine > 0 && not (text.GetLineString(docLine - 1).StartsWith "open") then yield insertLine (docLine - 1) "" |] diff --git a/src/FsAutoComplete/CommandResponse.fs b/src/FsAutoComplete/CommandResponse.fs index ffc4e14bd..41b28002d 100644 --- a/src/FsAutoComplete/CommandResponse.fs +++ b/src/FsAutoComplete/CommandResponse.fs @@ -3,9 +3,11 @@ namespace FsAutoComplete open System open FSharp.Compiler -open FSharp.Compiler.SourceCodeServices open Ionide.ProjInfo.ProjectSystem open FSharp.UMX +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.Xml module internal CompletionUtils = let getIcon (glyph : FSharpGlyph) = @@ -34,14 +36,14 @@ module internal CompletionUtils = let getEnclosingEntityChar = function - | FSharpEnclosingEntityKind.Namespace -> "N" - | FSharpEnclosingEntityKind.Module -> "M" - | FSharpEnclosingEntityKind.Class -> "C" - | FSharpEnclosingEntityKind.Exception -> "E" - | FSharpEnclosingEntityKind.Interface -> "I" - | FSharpEnclosingEntityKind.Record -> "R" - | FSharpEnclosingEntityKind.Enum -> "En" - | FSharpEnclosingEntityKind.DU -> "D" + | NavigationEntityKind.Namespace -> "N" + | NavigationEntityKind.Module -> "M" + | NavigationEntityKind.Class -> "C" + | NavigationEntityKind.Exception -> "E" + | NavigationEntityKind.Interface -> "I" + | NavigationEntityKind.Record -> "R" + | NavigationEntityKind.Enum -> "En" + | NavigationEntityKind.Union -> "D" module internal ClassificationUtils = @@ -86,6 +88,7 @@ module internal ClassificationUtils = | SemanticClassificationType.Value | SemanticClassificationType.LocalValue -> "variable" | SemanticClassificationType.Plaintext -> "text" + | n -> "unknown" module CommandResponse = open FSharp.Compiler.Text @@ -207,15 +210,15 @@ module CommandResponse = Message: string Subcategory: string } - static member IsIgnored(e:FSharp.Compiler.SourceCodeServices.FSharpDiagnostic) = + static member IsIgnored(e: FSharpDiagnostic) = // FST-1027 support in Fake 5 e.ErrorNumber = 213 && e.Message.StartsWith "'paket:" - static member OfFSharpError(e:FSharp.Compiler.SourceCodeServices.FSharpDiagnostic) = + static member OfFSharpError(e: FSharpDiagnostic) = { FileName = e.FileName - StartLine = e.StartLineAlternate - EndLine = e.EndLineAlternate + StartLine = e.StartLine + EndLine = e.EndLine StartColumn = e.StartColumn + 1 EndColumn = e.EndColumn + 1 Severity = e.Severity @@ -237,7 +240,7 @@ module CommandResponse = EnclosingEntity: string IsAbstract: bool } - static member OfDeclarationItem(e:FSharpNavigationDeclarationItem, fn) = + static member OfDeclarationItem(e: NavigationItem, fn) = let (glyph, glyphChar) = CompletionUtils.getIcon e.Glyph { UniqueName = e.UniqueName @@ -495,7 +498,7 @@ module CommandResponse = Data = { CommandName = commandName ParameterStr = parameterStr} } - let declarations (serialize : Serializer) (decls : (FSharpNavigationTopLevelDeclaration * string) []) = + let declarations (serialize : Serializer) (decls : (NavigationTopLevelDeclaration * string) []) = let decls' = decls |> Array.map (fun (d, fn) -> { Declaration = Declaration.OfDeclarationItem (d.Declaration, UMX.untag fn); @@ -513,9 +516,9 @@ module CommandResponse = | _ -> failwith "Shouldn't happen" serialize { Kind = "formattedDocumentation"; Data = data } - let formattedDocumentationForSymbol (serialize : Serializer) xml assembly (xmlDoc : string list) (signature, footer, cn) = + let formattedDocumentationForSymbol (serialize : Serializer) xml assembly (xmldoc: string[]) (signature, footer, cn) = let data = TipFormatter.formatDocumentationFromXmlSig xml assembly signature footer cn |> List.map(List.map(fun (n,cns, fds, funcs, intf, attrs, ts, m,f, cn) -> - let m = if String.IsNullOrWhiteSpace m then xmlDoc |> String.concat Environment.NewLine else m + let m = if String.IsNullOrWhiteSpace m then xmldoc |> String.concat Environment.NewLine else m {XmlKey = cn; Constructors = cns |> Seq.toList; Fields = fds |> Seq.toList; Functions = funcs |> Seq.toList; Interfaces = intf |> Seq.toList; Attributes = attrs |> Seq.toList; Types = ts |> Seq.toList; Footer =f; Signature = n; Comment = m} )) serialize { Kind = "formattedDocumentation"; Data = data } diff --git a/src/FsAutoComplete/FsAutoComplete.Lsp.fs b/src/FsAutoComplete/FsAutoComplete.Lsp.fs index 3c304a716..ac86ccdbc 100644 --- a/src/FsAutoComplete/FsAutoComplete.Lsp.fs +++ b/src/FsAutoComplete/FsAutoComplete.Lsp.fs @@ -9,7 +9,6 @@ open FsAutoComplete.Utils open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types open FsAutoComplete.Logging -open FSharp.Compiler.SourceCodeServices open LanguageServerProtocol open LanguageServerProtocol.LspResult open LanguageServerProtocol.Server @@ -23,11 +22,14 @@ open FSharp.Analyzers open FSharp.Compiler.Text open CliWrap open CliWrap.Buffered +open FSharp.Compiler.Tokenization +open FSharp.Compiler.EditorServices +open FSharp.Compiler.Symbols module FcsRange = FSharp.Compiler.Text.Range type FcsRange = FSharp.Compiler.Text.Range -module FcsPos = FSharp.Compiler.Text.Pos -type FcsPos = FSharp.Compiler.Text.Pos +module FcsPos = FSharp.Compiler.Text.Position +type FcsPos = FSharp.Compiler.Text.Position module Result = let ofCoreResponse (r: CoreResponse<'a>) = @@ -1147,7 +1149,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS elif d.NamespaceToOpen.IsSome then d.Name else - FSharpKeywords.QuoteIdentifierIfNeeded d.Name + FSharpKeywords.AddBackticksToIdentifierIfNeeded d.Name let label = match d.NamespaceToOpen with @@ -1354,7 +1356,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS let edits = symbols |> Array.map (fun sym -> - let range = fcsRangeToLsp sym.RangeAlternate + let range = fcsRangeToLsp sym.Range let range = { range with @@ -1469,7 +1471,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS let ranges: FSharp.Compiler.Text.Range [] = match res with - | LocationResponse.Use (_, uses) -> uses |> Array.map (fun u -> u.RangeAlternate) + | LocationResponse.Use (_, uses) -> uses |> Array.map (fun u -> u.Range) | LocationResponse.UseRange uses -> uses |> Array.map (fun u -> u.Range) let filtered = @@ -1502,7 +1504,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS | CoreResponse.Res (symbol, uses) -> uses |> Array.map (fun s -> - { DocumentHighlight.Range = fcsRangeToLsp s.RangeAlternate + { DocumentHighlight.Range = fcsRangeToLsp s.Range Kind = None }) |> Some |> success @@ -1523,7 +1525,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS let ranges: FSharp.Compiler.Text.Range [] = match res with - | LocationResponse.Use (_, uses) -> uses |> Array.map (fun u -> u.RangeAlternate) + | LocationResponse.Use (_, uses) -> uses |> Array.map (fun u -> u.Range) | LocationResponse.UseRange uses -> uses |> Array.map (fun u -> u.Range) let mappedRanges = ranges |> Array.map fcsRangeToLspLocation @@ -1959,7 +1961,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS let locs = uses - |> Array.map (fun n -> fcsRangeToLspLocation n.RangeAlternate) + |> Array.map (fun n -> fcsRangeToLspLocation n.Range) let args = [| JToken.FromObject(Path.LocalPathToUri file) @@ -2565,12 +2567,18 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS | Ok (CoreResponse.InfoRes msg) | Ok (CoreResponse.ErrorRes msg) -> AsyncLspResult.internalError msg | Ok (CoreResponse.Res (xml, assembly, doc, signature, footer, cn)) -> + let xmldoc = + match doc with + | FSharpXmlDoc.None -> [||] + | FSharpXmlDoc.FromXmlFile _ -> [||] + | FSharpXmlDoc.FromXmlText d -> d.GetElaboratedXmlLines() + { Content = CommandResponse.formattedDocumentationForSymbol FsAutoComplete.JsonSerializer.writeJson xml assembly - doc + xmldoc (signature, footer, cn) } |> success |> async.Return @@ -2626,7 +2634,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS member private x.handleSemanticTokens - (getTokens: Async>>) + (getTokens: Async>>) : AsyncLspResult = asyncResult { match! getTokens |> AsyncResult.ofCoreResponse with @@ -2634,9 +2642,9 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS | Some rangesAndHighlights -> let lspTypedRanges = rangesAndHighlights - |> Array.map (fun (struct (fcsRange, fcsTokenType)) -> - let ty, mods = ClassificationUtils.map fcsTokenType - struct (fcsRangeToLsp fcsRange, ty, mods)) + |> Array.map (fun item -> + let ty, mods = ClassificationUtils.map item.Type + struct (fcsRangeToLsp item.Range, ty, mods)) match encodeSemanticHighlightRanges lspTypedRanges with | None -> return! success None @@ -2743,8 +2751,8 @@ let startCore backgroundServiceEnabled toolsPath workspaceLoaderFactory = let state = State.Initial toolsPath workspaceLoaderFactory - let originalFs = FileSystemAutoOpens.FileSystem - FileSystemAutoOpens.FileSystem <- FsAutoComplete.FileSystem(originalFs, state.Files.TryFind) + let originalFs = FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem + FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem <- FsAutoComplete.FileSystem(originalFs, state.Files.TryFind) LanguageServerProtocol.Server.start requestsHandlings input output FSharpLspClient (fun lspClient -> new FSharpLspServer(backgroundServiceEnabled, state, lspClient)) diff --git a/src/FsAutoComplete/JsonSerializer.fs b/src/FsAutoComplete/JsonSerializer.fs index f9e5aa923..b04a6450e 100644 --- a/src/FsAutoComplete/JsonSerializer.fs +++ b/src/FsAutoComplete/JsonSerializer.fs @@ -3,7 +3,7 @@ open System open Newtonsoft.Json open FSharp.Compiler.Text -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Diagnostics open Microsoft.FSharp.Reflection module private JsonSerializerConverters = diff --git a/src/FsAutoComplete/LspHelpers.fs b/src/FsAutoComplete/LspHelpers.fs index 3901e5d85..2bed7a3ae 100644 --- a/src/FsAutoComplete/LspHelpers.fs +++ b/src/FsAutoComplete/LspHelpers.fs @@ -4,15 +4,16 @@ open System open System.IO open LanguageServerProtocol.Types open FsAutoComplete.Utils -open FSharp.Compiler.SourceCodeServices open FSharp.Reflection open System.Collections.Generic open Ionide.ProjInfo.ProjectSystem +open FSharp.Compiler.Diagnostics +open FSharp.Compiler.EditorServices module FcsRange = FSharp.Compiler.Text.Range type FcsRange = FSharp.Compiler.Text.Range -module FcsPos = FSharp.Compiler.Text.Pos -type FcsPos = FSharp.Compiler.Text.Pos +module FcsPos = FSharp.Compiler.Text.Position +type FcsPos = FSharp.Compiler.Text.Position [] module Conversions = @@ -108,8 +109,8 @@ module Conversions = { Range = { - Start = { Line = error.StartLineAlternate - 1; Character = error.StartColumn } - End = { Line = error.EndLineAlternate - 1; Character = error.EndColumn } + Start = { Line = error.StartLine - 1; Character = error.StartColumn } + End = { Line = error.EndLine - 1; Character = error.EndColumn } } Severity = fcsSeverityToDiagnostic error.Severity Source = "F# Compiler" @@ -121,8 +122,8 @@ module Conversions = CodeDescription = Some { Href = Some (Uri (urlForCompilerCode error.ErrorNumber))} } - let getSymbolInformations (uri: DocumentUri) (glyphToSymbolKind: FSharpGlyph -> SymbolKind option) (topLevel: FSharpNavigationTopLevelDeclaration) (symbolFilter: SymbolInformation -> bool): SymbolInformation [] = - let inner (container: string option) (decl: FSharpNavigationDeclarationItem): SymbolInformation option = + let getSymbolInformations (uri: DocumentUri) (glyphToSymbolKind: FSharpGlyph -> SymbolKind option) (topLevel: NavigationTopLevelDeclaration) (symbolFilter: SymbolInformation -> bool): SymbolInformation [] = + let inner (container: string option) (decl: NavigationItem): SymbolInformation option = // We should nearly always have a kind, if the client doesn't send weird capabilities, // if we don't why not assume module... let kind = defaultArg (glyphToSymbolKind decl.Glyph) SymbolKind.Module @@ -153,8 +154,8 @@ module Conversions = Array.last parts info.Name.StartsWith fieldName && info.ContainerName = Some containerName - let getCodeLensInformation (uri: DocumentUri) (typ: string) (topLevel: FSharpNavigationTopLevelDeclaration): CodeLens [] = - let map (decl: FSharpNavigationDeclarationItem): CodeLens = + let getCodeLensInformation (uri: DocumentUri) (typ: string) (topLevel: NavigationTopLevelDeclaration): CodeLens [] = + let map (decl: NavigationItem): CodeLens = { Command = None Data = Some (Newtonsoft.Json.Linq.JToken.FromObject [|uri; typ |] ) @@ -169,11 +170,11 @@ module Conversions = && n.Glyph <> FSharpGlyph.EnumMember && n.Glyph <> FSharpGlyph.Property || n.IsAbstract - || n.EnclosingEntityKind = FSharpEnclosingEntityKind.Interface - || n.EnclosingEntityKind = FSharpEnclosingEntityKind.Record - || n.EnclosingEntityKind = FSharpEnclosingEntityKind.DU - || n.EnclosingEntityKind = FSharpEnclosingEntityKind.Enum - || n.EnclosingEntityKind = FSharpEnclosingEntityKind.Exception) + || n.EnclosingEntityKind = NavigationEntityKind.Interface + || n.EnclosingEntityKind = NavigationEntityKind.Record + || n.EnclosingEntityKind = NavigationEntityKind.Union + || n.EnclosingEntityKind = NavigationEntityKind.Enum + || n.EnclosingEntityKind = NavigationEntityKind.Exception) ) |> Array.map map @@ -370,7 +371,7 @@ module Structure = | Structure.Scope.Member | Structure.Scope.LetOrUse | Structure.Scope.Val - | Structure.Scope.CompExpr + | Structure.Scope.ComputationExpr | Structure.Scope.IfThenElse | Structure.Scope.ThenInIfThenElse | Structure.Scope.ElseInIfThenElse @@ -389,7 +390,6 @@ module Structure = | Structure.Scope.MatchLambda | Structure.Scope.MatchClause | Structure.Scope.Lambda - | Structure.Scope.CompExprInternal | Structure.Scope.Quote | Structure.Scope.Record | Structure.Scope.SpecialFunc @@ -513,6 +513,7 @@ module ClassificationUtils = | SemanticClassificationType.Value | SemanticClassificationType.LocalValue -> SemanticTokenTypes.Variable, [] | SemanticClassificationType.Plaintext -> SemanticTokenTypes.Text, [] + | unknown -> SemanticTokenTypes.Text, [] type PlainNotification= { Content: string } diff --git a/src/FsAutoComplete/Program.fs b/src/FsAutoComplete/Program.fs index 70910f860..9611415d9 100644 --- a/src/FsAutoComplete/Program.fs +++ b/src/FsAutoComplete/Program.fs @@ -1,7 +1,6 @@ module FsAutoComplete.Program open System -open FSharp.Compiler.SourceCodeServices open FsAutoComplete.JsonSerializer open Argu open Serilog @@ -29,7 +28,7 @@ let entry args = .Enrich.FromLogContext() .Destructure.FSharpTypes() .Destructure.ByTransforming(fun r -> box {| FileName = r.FileName; Start = r.Start; End = r.End |}) - .Destructure.ByTransforming(fun r -> box {| Line = r.Line; Column = r.Column |}) + .Destructure.ByTransforming(fun r -> box {| Line = r.Line; Column = r.Column |}) .Destructure.ByTransforming(fun tok -> tok.ToString() |> box) .Destructure.ByTransforming(fun di -> box di.FullName) .WriteTo.Async( diff --git a/test/FsAutoComplete.Tests.Lsp/Helpers.fs b/test/FsAutoComplete.Tests.Lsp/Helpers.fs index ef888f249..453223f81 100644 --- a/test/FsAutoComplete.Tests.Lsp/Helpers.fs +++ b/test/FsAutoComplete.Tests.Lsp/Helpers.fs @@ -117,9 +117,9 @@ type ClientEvents = IObservable let createServer (state: State) = let event = new System.Reactive.Subjects.ReplaySubject<_>() let client = FSharpLspClient ((fun name o -> event.OnNext (name ,o); AsyncLspResult.success ()), { new LanguageServerProtocol.Server.ClientRequestSender with member __.Send _ _ = AsyncLspResult.notImplemented}) - let originalFs = FSharp.Compiler.SourceCodeServices.FileSystemAutoOpens.FileSystem + let originalFs = FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem let fs = FsAutoComplete.FileSystem(originalFs, state.Files.TryFind) - FSharp.Compiler.SourceCodeServices.FileSystemAutoOpens.FileSystem <- fs + FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem <- fs let server = new FSharpLspServer(false, state, client) server, event :> ClientEvents diff --git a/test/FsAutoComplete.Tests.Lsp/Program.fs b/test/FsAutoComplete.Tests.Lsp/Program.fs index 314404172..6c71843d4 100644 --- a/test/FsAutoComplete.Tests.Lsp/Program.fs +++ b/test/FsAutoComplete.Tests.Lsp/Program.fs @@ -109,7 +109,7 @@ let main args = .Destructure.FSharpTypes() .Destructure.ByTransforming(fun r -> box {| FileName = r.FileName; Start = r.Start; End = r.End |}) - .Destructure.ByTransforming(fun r -> box {| Line = r.Line; Column = r.Column |}) + .Destructure.ByTransforming(fun r -> box {| Line = r.Line; Column = r.Column |}) .Destructure.ByTransforming(fun tok -> tok.ToString() |> box) .Destructure.ByTransforming(fun di -> box di.FullName) .WriteTo.Async( diff --git a/test/OptionAnalyzer/Analyzer.fs b/test/OptionAnalyzer/Analyzer.fs index a58cf16ca..8510ed739 100644 --- a/test/OptionAnalyzer/Analyzer.fs +++ b/test/OptionAnalyzer/Analyzer.fs @@ -2,96 +2,96 @@ open System open FSharp.Analyzers.SDK -open FSharp.Compiler.SourceCodeServices +open FSharp.Compiler.Symbols open FSharp.Compiler.Text open FsAutoComplete.Logging let rec visitExpr memberCallHandler (e:FSharpExpr) = match e with - | BasicPatterns.AddressOf(lvalueExpr) -> + | FSharpExprPatterns.AddressOf(lvalueExpr) -> visitExpr memberCallHandler lvalueExpr - | BasicPatterns.AddressSet(lvalueExpr, rvalueExpr) -> + | FSharpExprPatterns.AddressSet(lvalueExpr, rvalueExpr) -> visitExpr memberCallHandler lvalueExpr; visitExpr memberCallHandler rvalueExpr - | BasicPatterns.Application(funcExpr, typeArgs, argExprs) -> + | FSharpExprPatterns.Application(funcExpr, typeArgs, argExprs) -> visitExpr memberCallHandler funcExpr; visitExprs memberCallHandler argExprs - | BasicPatterns.Call(objExprOpt, memberOrFunc, typeArgs1, typeArgs2, argExprs) -> + | FSharpExprPatterns.Call(objExprOpt, memberOrFunc, typeArgs1, typeArgs2, argExprs) -> memberCallHandler e.Range memberOrFunc visitObjArg memberCallHandler objExprOpt; visitExprs memberCallHandler argExprs - | BasicPatterns.Coerce(targetType, inpExpr) -> + | FSharpExprPatterns.Coerce(targetType, inpExpr) -> visitExpr memberCallHandler inpExpr - | BasicPatterns.FastIntegerForLoop(startExpr, limitExpr, consumeExpr, isUp) -> + | FSharpExprPatterns.FastIntegerForLoop(startExpr, limitExpr, consumeExpr, isUp) -> visitExpr memberCallHandler startExpr; visitExpr memberCallHandler limitExpr; visitExpr memberCallHandler consumeExpr - | BasicPatterns.ILAsm(asmCode, typeArgs, argExprs) -> + | FSharpExprPatterns.ILAsm(asmCode, typeArgs, argExprs) -> visitExprs memberCallHandler argExprs - | BasicPatterns.ILFieldGet (objExprOpt, fieldType, fieldName) -> + | FSharpExprPatterns.ILFieldGet (objExprOpt, fieldType, fieldName) -> visitObjArg memberCallHandler objExprOpt - | BasicPatterns.ILFieldSet (objExprOpt, fieldType, fieldName, valueExpr) -> + | FSharpExprPatterns.ILFieldSet (objExprOpt, fieldType, fieldName, valueExpr) -> visitObjArg memberCallHandler objExprOpt - | BasicPatterns.IfThenElse (guardExpr, thenExpr, elseExpr) -> + | FSharpExprPatterns.IfThenElse (guardExpr, thenExpr, elseExpr) -> visitExpr memberCallHandler guardExpr; visitExpr memberCallHandler thenExpr; visitExpr memberCallHandler elseExpr - | BasicPatterns.Lambda(lambdaVar, bodyExpr) -> + | FSharpExprPatterns.Lambda(lambdaVar, bodyExpr) -> visitExpr memberCallHandler bodyExpr - | BasicPatterns.Let((bindingVar, bindingExpr), bodyExpr) -> + | FSharpExprPatterns.Let((bindingVar, bindingExpr), bodyExpr) -> visitExpr memberCallHandler bindingExpr; visitExpr memberCallHandler bodyExpr - | BasicPatterns.LetRec(recursiveBindings, bodyExpr) -> + | FSharpExprPatterns.LetRec(recursiveBindings, bodyExpr) -> List.iter (snd >> visitExpr memberCallHandler) recursiveBindings; visitExpr memberCallHandler bodyExpr - | BasicPatterns.NewArray(arrayType, argExprs) -> + | FSharpExprPatterns.NewArray(arrayType, argExprs) -> visitExprs memberCallHandler argExprs - | BasicPatterns.NewDelegate(delegateType, delegateBodyExpr) -> + | FSharpExprPatterns.NewDelegate(delegateType, delegateBodyExpr) -> visitExpr memberCallHandler delegateBodyExpr - | BasicPatterns.NewObject(objType, typeArgs, argExprs) -> + | FSharpExprPatterns.NewObject(objType, typeArgs, argExprs) -> visitExprs memberCallHandler argExprs - | BasicPatterns.NewRecord(recordType, argExprs) -> + | FSharpExprPatterns.NewRecord(recordType, argExprs) -> visitExprs memberCallHandler argExprs - | BasicPatterns.NewTuple(tupleType, argExprs) -> + | FSharpExprPatterns.NewTuple(tupleType, argExprs) -> visitExprs memberCallHandler argExprs - | BasicPatterns.NewUnionCase(unionType, unionCase, argExprs) -> + | FSharpExprPatterns.NewUnionCase(unionType, unionCase, argExprs) -> visitExprs memberCallHandler argExprs - | BasicPatterns.Quote(quotedExpr) -> + | FSharpExprPatterns.Quote(quotedExpr) -> visitExpr memberCallHandler quotedExpr - | BasicPatterns.FSharpFieldGet(objExprOpt, recordOrClassType, fieldInfo) -> + | FSharpExprPatterns.FSharpFieldGet(objExprOpt, recordOrClassType, fieldInfo) -> visitObjArg memberCallHandler objExprOpt - | BasicPatterns.FSharpFieldSet(objExprOpt, recordOrClassType, fieldInfo, argExpr) -> + | FSharpExprPatterns.FSharpFieldSet(objExprOpt, recordOrClassType, fieldInfo, argExpr) -> visitObjArg memberCallHandler objExprOpt; visitExpr memberCallHandler argExpr - | BasicPatterns.Sequential(firstExpr, secondExpr) -> + | FSharpExprPatterns.Sequential(firstExpr, secondExpr) -> visitExpr memberCallHandler firstExpr; visitExpr memberCallHandler secondExpr - | BasicPatterns.TryFinally(bodyExpr, finalizeExpr) -> + | FSharpExprPatterns.TryFinally(bodyExpr, finalizeExpr) -> visitExpr memberCallHandler bodyExpr; visitExpr memberCallHandler finalizeExpr - | BasicPatterns.TryWith(bodyExpr, _, _, catchVar, catchExpr) -> + | FSharpExprPatterns.TryWith(bodyExpr, _, _, catchVar, catchExpr) -> visitExpr memberCallHandler bodyExpr; visitExpr memberCallHandler catchExpr - | BasicPatterns.TupleGet(tupleType, tupleElemIndex, tupleExpr) -> + | FSharpExprPatterns.TupleGet(tupleType, tupleElemIndex, tupleExpr) -> visitExpr memberCallHandler tupleExpr - | BasicPatterns.DecisionTree(decisionExpr, decisionTargets) -> + | FSharpExprPatterns.DecisionTree(decisionExpr, decisionTargets) -> visitExpr memberCallHandler decisionExpr; List.iter (snd >> visitExpr memberCallHandler) decisionTargets - | BasicPatterns.DecisionTreeSuccess (decisionTargetIdx, decisionTargetExprs) -> + | FSharpExprPatterns.DecisionTreeSuccess (decisionTargetIdx, decisionTargetExprs) -> visitExprs memberCallHandler decisionTargetExprs - | BasicPatterns.TypeLambda(genericParam, bodyExpr) -> + | FSharpExprPatterns.TypeLambda(genericParam, bodyExpr) -> visitExpr memberCallHandler bodyExpr - | BasicPatterns.TypeTest(ty, inpExpr) -> + | FSharpExprPatterns.TypeTest(ty, inpExpr) -> visitExpr memberCallHandler inpExpr - | BasicPatterns.UnionCaseSet(unionExpr, unionType, unionCase, unionCaseField, valueExpr) -> + | FSharpExprPatterns.UnionCaseSet(unionExpr, unionType, unionCase, unionCaseField, valueExpr) -> visitExpr memberCallHandler unionExpr; visitExpr memberCallHandler valueExpr - | BasicPatterns.UnionCaseGet(unionExpr, unionType, unionCase, unionCaseField) -> + | FSharpExprPatterns.UnionCaseGet(unionExpr, unionType, unionCase, unionCaseField) -> visitExpr memberCallHandler unionExpr - | BasicPatterns.UnionCaseTest(unionExpr, unionType, unionCase) -> + | FSharpExprPatterns.UnionCaseTest(unionExpr, unionType, unionCase) -> visitExpr memberCallHandler unionExpr - | BasicPatterns.UnionCaseTag(unionExpr, unionType) -> + | FSharpExprPatterns.UnionCaseTag(unionExpr, unionType) -> visitExpr memberCallHandler unionExpr - | BasicPatterns.ObjectExpr(objType, baseCallExpr, overrides, interfaceImplementations) -> + | FSharpExprPatterns.ObjectExpr(objType, baseCallExpr, overrides, interfaceImplementations) -> visitExpr memberCallHandler baseCallExpr List.iter (visitObjMember memberCallHandler) overrides List.iter (snd >> List.iter (visitObjMember memberCallHandler)) interfaceImplementations - | BasicPatterns.TraitCall(sourceTypes, traitName, typeArgs, typeInstantiation, argTypes, argExprs) -> + | FSharpExprPatterns.TraitCall(sourceTypes, traitName, typeArgs, typeInstantiation, argTypes, argExprs) -> visitExprs memberCallHandler argExprs - | BasicPatterns.ValueSet(valToSet, valueExpr) -> + | FSharpExprPatterns.ValueSet(valToSet, valueExpr) -> visitExpr memberCallHandler valueExpr - | BasicPatterns.WhileLoop(guardExpr, bodyExpr) -> + | FSharpExprPatterns.WhileLoop(guardExpr, bodyExpr) -> visitExpr memberCallHandler guardExpr; visitExpr memberCallHandler bodyExpr - | BasicPatterns.BaseValue baseType -> () - | BasicPatterns.DefaultValue defaultType -> () - | BasicPatterns.ThisValue thisType -> () - | BasicPatterns.Const(constValueObj, constType) -> () - | BasicPatterns.Value(valueToGet) -> () + | FSharpExprPatterns.BaseValue baseType -> () + | FSharpExprPatterns.DefaultValue defaultType -> () + | FSharpExprPatterns.ThisValue thisType -> () + | FSharpExprPatterns.Const(constValueObj, constType) -> () + | FSharpExprPatterns.Value(valueToGet) -> () | _ -> () and visitExprs f exprs = From 777b6c76396ba71c446d06547bb45debe0b5dbe3 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Fri, 5 Nov 2021 16:50:32 -0500 Subject: [PATCH 5/7] update proj-info and revert local patch --- paket.dependencies | 8 ++--- paket.lock | 32 +++++++++---------- .../FsAutoComplete.Core.fsproj | 2 -- src/FsAutoComplete.Core/paket.references | 4 +++ src/FsAutoComplete/FsAutoComplete.fsproj | 2 -- src/FsAutoComplete/paket.references | 2 ++ 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/paket.dependencies b/paket.dependencies index dd3468a8f..78fa7d4eb 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -13,10 +13,10 @@ github TheAngryByrd/FsLibLog:f81cba440bf0476bb4e2262b57a067a0d6ab78a7 src/FsLibL nuget Argu ~> 5.2.0 nuget Fantomas.Client nuget FSharp.Compiler.Service ~> 41 -nuget Ionide.ProjInfo 0.54.2 -nuget Ionide.ProjInfo.FCS 0.54.2 -nuget Ionide.ProjInfo.ProjectSystem 0.54.2 -nuget Ionide.ProjInfo.Sln 0.54.2 +nuget Ionide.ProjInfo 0.55.0 +nuget Ionide.ProjInfo.FCS 0.55.0 +nuget Ionide.ProjInfo.ProjectSystem 0.55.0 +nuget Ionide.ProjInfo.Sln 0.55.0 nuget Microsoft.Build copy_local:false nuget Microsoft.Build.Framework copy_local:false nuget Microsoft.Build.Utilities.Core copy_local:false diff --git a/paket.lock b/paket.lock index 556217df1..54a525766 100644 --- a/paket.lock +++ b/paket.lock @@ -93,25 +93,25 @@ NUGET ICSharpCode.Decompiler (7.1.0.6543) System.Collections.Immutable (>= 5.0) System.Reflection.Metadata (>= 5.0) - Ionide.ProjInfo (0.54.2) - FSharp.Core (>= 5.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo.Sln (>= 0.54.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Microsoft.Build (>= 16.10) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Microsoft.Build.Framework (>= 16.10) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo (0.55) + FSharp.Core (>= 6.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo.Sln (>= 0.55) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Microsoft.Build (>= 16.11) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Microsoft.Build.Framework (>= 16.11) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) SemanticVersioning (>= 2.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo.FCS (0.54.2) - FSharp.Compiler.Service (>= 39.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - FSharp.Core (>= 5.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo (>= 0.54.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo.ProjectSystem (0.54.2) - FSharp.Compiler.Service (>= 39.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo.FCS (0.55) + FSharp.Compiler.Service (>= 41.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + FSharp.Core (>= 6.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo (>= 0.55) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo.ProjectSystem (0.55) + FSharp.Compiler.Service (>= 41.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) FSharp.Control.Reactive (>= 5.0.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - FSharp.Core (>= 5.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo (>= 0.54.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo.FCS (>= 0.54.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo.Sln (>= 0.54.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + FSharp.Core (>= 6.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo (>= 0.55) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo.FCS (>= 0.55) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + Ionide.ProjInfo.Sln (>= 0.55) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) Newtonsoft.Json (>= 13.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - Ionide.ProjInfo.Sln (0.54.2) + Ionide.ProjInfo.Sln (0.55) McMaster.NETCore.Plugins (1.4) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) Microsoft.DotNet.PlatformAbstractions (>= 3.1.6) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp2.1)) Microsoft.Extensions.DependencyModel (>= 5.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp2.1)) diff --git a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj index c7f03498a..469f825e6 100644 --- a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj +++ b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj @@ -6,8 +6,6 @@ - - diff --git a/src/FsAutoComplete.Core/paket.references b/src/FsAutoComplete.Core/paket.references index 6c4ec253f..09835dfa4 100644 --- a/src/FsAutoComplete.Core/paket.references +++ b/src/FsAutoComplete.Core/paket.references @@ -1,4 +1,7 @@ FSharp.Compiler.Service +Ionide.ProjInfo +Ionide.ProjInfo.FCS +Ionide.ProjInfo.ProjectSystem FSharp.Analyzers.SDK Newtonsoft.Json #Fake.Runtime @@ -10,5 +13,6 @@ System.Configuration.ConfigurationManager FSharp.UMX FsToolkit.ErrorHandling Fantomas.Client + System.Reflection.Metadata Microsoft.Build.Utilities.Core diff --git a/src/FsAutoComplete/FsAutoComplete.fsproj b/src/FsAutoComplete/FsAutoComplete.fsproj index bb7d3a769..a215b870b 100644 --- a/src/FsAutoComplete/FsAutoComplete.fsproj +++ b/src/FsAutoComplete/FsAutoComplete.fsproj @@ -33,8 +33,6 @@ - - diff --git a/src/FsAutoComplete/paket.references b/src/FsAutoComplete/paket.references index 04299f7a2..fc078834f 100644 --- a/src/FsAutoComplete/paket.references +++ b/src/FsAutoComplete/paket.references @@ -10,6 +10,8 @@ FSharp.UMX #FSharpLint.Core FsToolkit.ErrorHandling ICSharpCode.Decompiler +Ionide.ProjInfo +Ionide.ProjInfo.ProjectSystem Microsoft.Data.Sqlite Microsoft.NETFramework.ReferenceAssemblies Microsoft.SourceLink.GitHub From 3e71b75560929fef08b6d98ec62bac175014194f Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Sat, 6 Nov 2021 11:47:35 -0500 Subject: [PATCH 6/7] mostly working scripts and projects --- src/FsAutoComplete.Core/CodeGeneration.fs | 8 +- src/FsAutoComplete.Core/Commands.fs | 61 ++++++------ .../CompilerServiceInterface.fs | 4 +- src/FsAutoComplete.Core/Debug.fs | 32 ++++--- src/FsAutoComplete.Core/Sourcelink.fs | 1 - src/FsAutoComplete/FsAutoComplete.Lsp.fs | 95 ++++++++----------- utils/fcs39-validate.fsx | 2 +- 7 files changed, 95 insertions(+), 108 deletions(-) diff --git a/src/FsAutoComplete.Core/CodeGeneration.fs b/src/FsAutoComplete.Core/CodeGeneration.fs index e6eec9215..82093c30d 100644 --- a/src/FsAutoComplete.Core/CodeGeneration.fs +++ b/src/FsAutoComplete.Core/CodeGeneration.fs @@ -39,8 +39,8 @@ type CodeGenerationService(checker : FSharpCompilerServiceChecker, state : State if symbol.Kind = kind then match state.TryGetFileCheckerOptionsWithLinesAndLineStr(fileName, pos) with | ResultOrString.Error _ -> return! None - | ResultOrString.Ok (opts, _, line) -> - let! result = checker.TryGetRecentCheckResultsForFile(fileName, opts) + | ResultOrString.Ok (opts, text, line) -> + let! result = checker.TryGetRecentCheckResultsForFile(fileName, opts, text) let symbolUse = result.TryGetSymbolUse pos line return! Some (symbol, symbolUse) else @@ -50,9 +50,9 @@ type CodeGenerationService(checker : FSharpCompilerServiceChecker, state : State member x.ParseFileInProject(fileName) = match state.TryGetFileCheckerOptionsWithLines fileName with | ResultOrString.Error _ -> None - | ResultOrString.Ok (opts, lines) -> + | ResultOrString.Ok (opts, text) -> try - checker.TryGetRecentCheckResultsForFile(fileName, opts) |> Option.map (fun n -> n.GetParseResults) + checker.TryGetRecentCheckResultsForFile(fileName, opts, text) |> Option.map (fun n -> n.GetParseResults) with | _ -> None diff --git a/src/FsAutoComplete.Core/Commands.fs b/src/FsAutoComplete.Core/Commands.fs index 2f98a86d5..54644b9be 100644 --- a/src/FsAutoComplete.Core/Commands.fs +++ b/src/FsAutoComplete.Core/Commands.fs @@ -350,6 +350,14 @@ type Commands let parseFilesInTheBackground files = async { + let rec loopForProjOpts file = async { + match state.GetProjectOptions file with + | None -> + do! Async.Sleep (TimeSpan.FromSeconds 1.) + return! loopForProjOpts file + | Some opts -> return Utils.projectOptionsToParseOptions opts + } + for file in files do try let sourceOpt = @@ -377,11 +385,8 @@ type Commands match sourceOpt with | None -> () | Some source -> - let opts = - state.GetProjectOptions' file - |> Utils.projectOptionsToParseOptions - async { + let! opts = loopForProjOpts file let! parseRes = checker.ParseFile(file, source, opts) fileParsed.Trigger parseRes } @@ -675,13 +680,16 @@ type Commands state.GetCancellationTokens filename |> List.iter (fun cts -> cts.Cancel()) - member x.TryGetRecentTypeCheckResultsForFile(file: string, opts) = - checker.TryGetRecentCheckResultsForFile(file, opts) + member x.TryGetRecentTypeCheckResultsForFile(file: string) = + match state.TryGetFileCheckerOptionsWithLines file with + | Ok (opts, text) -> + checker.TryGetRecentCheckResultsForFile(file, opts, text) + | _ -> None ///Gets recent type check results, waiting for the results of in-progress type checking - /// if version of file in memory is grater than last type checked version. + /// if version of file in memory is greater than last type checked version. /// It also waits if there are no FSharpProjectOptions available for given file - member x.TryGetLatestTypeCheckResultsForFile(file: string) = + member x.GetLatestTypeCheckResultsForFile(file: string) = let stateVersion = state.TryGetFileVersion file let checkedVersion = state.TryGetLastCheckedVersion file @@ -698,28 +706,23 @@ type Commands |> Event.filter (fun (_, n, _) -> n = file) |> Event.map ignore |> Async.AwaitEvent - |> Async.bind (fun _ -> x.TryGetLatestTypeCheckResultsForFile(file)) + |> Async.bind (fun _ -> x.GetLatestTypeCheckResultsForFile(file)) | Some _, None | None, Some _ -> x.FileChecked |> Event.filter (fun (_, n, _) -> n = file) |> Event.map ignore |> Async.AwaitEvent - |> Async.bind (fun _ -> x.TryGetLatestTypeCheckResultsForFile(file)) + |> Async.bind (fun _ -> x.GetLatestTypeCheckResultsForFile(file)) | _ -> - match state.TryGetFileCheckerOptionsWithLines(file) with - | ResultOrString.Ok (opts, _) -> - x.TryGetRecentTypeCheckResultsForFile(file, opts) - |> async.Return - | ResultOrString.Error _ -> + match x.TryGetRecentTypeCheckResultsForFile(file) with + | Some results -> async.Return results + | None -> x.FileChecked |> Event.filter (fun (_, n, _) -> n = file) |> Event.map ignore |> Async.AwaitEvent - |> Async.bind (fun _ -> x.TryGetLatestTypeCheckResultsForFile(file)) - - - + |> Async.bind (fun _ -> x.GetLatestTypeCheckResultsForFile(file)) member x.TryGetFileCheckerOptionsWithLinesAndLineStr(file: string, pos) = state.TryGetFileCheckerOptionsWithLinesAndLineStr(file, pos) @@ -1334,7 +1337,7 @@ type Commands asyncResult { let! (opts, source) = state.TryGetFileCheckerOptionsWithLines file - let tyResOpt = checker.TryGetRecentCheckResultsForFile(file, opts) + let tyResOpt = checker.TryGetRecentCheckResultsForFile(file, opts, source) match tyResOpt with | None -> () @@ -1352,7 +1355,7 @@ type Commands asyncResult { let! (opts, source) = state.TryGetFileCheckerOptionsWithLines file - match checker.TryGetRecentCheckResultsForFile(file, opts) with + match checker.TryGetRecentCheckResultsForFile(file, opts, source) with | None -> return () | Some tyRes -> let! unused = UnusedOpens.getUnusedOpens (tyRes.GetCheckResults, (fun i -> source.GetLineString(i - 1))) @@ -1468,18 +1471,10 @@ type Commands /// gets the semantic classification ranges for a file, optionally filtered by a given range. member x.GetHighlighting(file: string, range: Range option) = async { - let! res = x.TryGetLatestTypeCheckResultsForFile file - - let res = - match res with - | Some res -> - let r = res.GetCheckResults.GetSemanticClassification(range) - - let filteredRanges = scrubRanges r - Some filteredRanges - | None -> None - - return CoreResponse.Res res + let! res = x.GetLatestTypeCheckResultsForFile file + let r = res.GetCheckResults.GetSemanticClassification(range) + let filteredRanges = scrubRanges r + return CoreResponse.Res filteredRanges } member __.SetWorkspaceRoot(root: string option) = workspaceRoot <- root diff --git a/src/FsAutoComplete.Core/CompilerServiceInterface.fs b/src/FsAutoComplete.Core/CompilerServiceInterface.fs index df46ac4f7..c7b80307f 100644 --- a/src/FsAutoComplete.Core/CompilerServiceInterface.fs +++ b/src/FsAutoComplete.Core/CompilerServiceInterface.fs @@ -329,7 +329,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = | ex -> return ResultOrString.Error(ex.ToString()) } - member __.TryGetRecentCheckResultsForFile(file: string, options, ?source) = + member __.TryGetRecentCheckResultsForFile(file: string, options, source) = let opName = sprintf "TryGetRecentCheckResultsForFile - %A" file checkerLogger.info @@ -338,7 +338,7 @@ type FSharpCompilerServiceChecker(backgroundServiceEnabled, hasAnalyzers) = let options = clearProjectReferences options - checker.TryGetRecentCheckResultsForFile(UMX.untag file, options, ?sourceText = source, userOpName = opName) + checker.TryGetRecentCheckResultsForFile(UMX.untag file, options, sourceText = source, userOpName = opName) |> Option.map (fun (pr, cr, _) -> ParseAndCheckResults(pr, cr, entityCache)) member x.GetUsesOfSymbol diff --git a/src/FsAutoComplete.Core/Debug.fs b/src/FsAutoComplete.Core/Debug.fs index c70fa2032..d4d71669d 100644 --- a/src/FsAutoComplete.Core/Debug.fs +++ b/src/FsAutoComplete.Core/Debug.fs @@ -66,29 +66,35 @@ module Debug = override __.OnEventWritten eventArgs = let message = - match eventArgs.EventName with - | "Log" -> Log.setMessage "Inside Compiler Function {function}" >> logFunctionName eventArgs.Payload.[0] - | "LogMessage" -> Log.setMessage "({function}) {message}" >> logFunctionName eventArgs.Payload.[1] >> Log.addContextDestructured "message" (eventArgs.Payload.[0] :?> string) - | "BlockStart" | "BlockMessageStart" -> + match eventArgs.EventId with + | 0 -> Log.setMessage (string eventArgs.Payload.[0]) + | 1 -> Log.setMessage "In {function}" >> logFunctionName eventArgs.Payload.[0] + | 2 -> Log.setMessage "{function}: {message}" >> logFunctionName eventArgs.Payload.[1] >> Log.addContextDestructured "message" eventArgs.Payload.[0] + | 3 -> inflightEvents.TryAdd(eventArgs.Task, DateTimeOffset.UtcNow) |> ignore - id - | "BlockEnd" -> + Log.setMessage "Started {function}" >> logFunctionName eventArgs.Payload.[0] + | 4 -> match inflightEvents.TryRemove(eventArgs.Task) with | true, startTime -> let delta = DateTimeOffset.UtcNow - startTime - Log.setMessage "Finished compiler function {function} in {seconds}" >> logFunctionName eventArgs.Payload.[0] >> Log.addContextDestructured "seconds" delta.TotalSeconds - | false, _ -> id - | "BlockMessageStop" -> + Log.setMessage "Finished {function} in {seconds}" >> logFunctionName eventArgs.Payload.[0] >> Log.addContextDestructured "seconds" delta.TotalSeconds + | false, _ -> + Log.setMessage "Finished {function}" >> logFunctionName eventArgs.Payload.[0] + | 5 -> + inflightEvents.TryAdd(eventArgs.Task, DateTimeOffset.UtcNow) |> ignore + Log.setMessage "Started {function}: {message}" >> logFunctionName eventArgs.Payload.[1] >> Log.addContextDestructured "message" eventArgs.Payload.[0] + | 6 -> match inflightEvents.TryRemove(eventArgs.Task) with | true, startTime -> let delta = DateTimeOffset.UtcNow - startTime - Log.setMessage "Finished compiler function {function} with parameter {parameter} in {seconds}" + Log.setMessage "Finished {function}: {message} ({seconds} seconds)" >> logFunctionName eventArgs.Payload.[1] >> Log.addContextDestructured "seconds" delta.TotalSeconds - >> Log.addContextDestructured "parameter" (eventArgs.Payload.[0]) - | false, _ -> id + >> Log.addContextDestructured "message" (eventArgs.Payload.[0]) + | false, _ -> + Log.setMessage "Finished {function}: {message}" >> logFunctionName eventArgs.Payload.[1] >> Log.addContextDestructured "message" eventArgs.Payload.[0] | other -> - Log.setMessage "Unknown event {name} with payload {payload}" >> Log.addContextDestructured "name" eventArgs.EventName >> Log.addContextDestructured "payload" (eventArgs.Payload |> Seq.toList) + Log.setMessage "Unknown event {name}({id}) with payload {payload}" >> Log.addContext "id" other >> Log.addContextDestructured "name" eventArgs.EventName >> Log.addContextDestructured "payload" (eventArgs.Payload |> Seq.toList) (eventLevelToLogLevel eventArgs.Level) message diff --git a/src/FsAutoComplete.Core/Sourcelink.fs b/src/FsAutoComplete.Core/Sourcelink.fs index 04a5d2ac0..3729617cd 100644 --- a/src/FsAutoComplete.Core/Sourcelink.fs +++ b/src/FsAutoComplete.Core/Sourcelink.fs @@ -41,7 +41,6 @@ let private compareRepoPath (d: Document) targetFile = if Environment.isWindows then let s = UMX.untag d.Name let s' = normalizePath s |> UMX.untag - let s' = s'.Replace(@"\", "/") let s' = UMX.tag s' s' = targetFile else diff --git a/src/FsAutoComplete/FsAutoComplete.Lsp.fs b/src/FsAutoComplete/FsAutoComplete.Lsp.fs index ac86ccdbc..ea6c7ae36 100644 --- a/src/FsAutoComplete/FsAutoComplete.Lsp.fs +++ b/src/FsAutoComplete/FsAutoComplete.Lsp.fs @@ -591,7 +591,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS return! AsyncLspResult.internalError s | ResultOrString.Ok (options, lines, lineStr) -> try - let tyResOpt = commands.TryGetRecentTypeCheckResultsForFile(file, options) + let tyResOpt = commands.TryGetRecentTypeCheckResultsForFile(file) match tyResOpt with | None -> @@ -600,7 +600,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS >> Log.addContextDestructured "file" file ) - return! AsyncLspResult.internalError "Cached typecheck results not yet available" + return! AsyncLspResult.success Unchecked.defaultof<_> | Some tyRes -> let! r = Async.Catch(f arg pos tyRes lineStr lines) @@ -638,43 +638,32 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS return! try async { - let! tyResOpt = commands.TryGetLatestTypeCheckResultsForFile(file) - + let! tyRes = commands.GetLatestTypeCheckResultsForFile(file) return! - match tyResOpt with - | None -> + match commands.TryGetFileCheckerOptionsWithLinesAndLineStr(file, pos) with + | ResultOrString.Error s -> logger.error ( - Log.setMessage - "PositionHandler - Cached typecheck results for {file} not yet available and are required" + Log.setMessage "PositionHandler - Getting file checker options for {file} failed" + >> Log.addContextDestructured "error" s >> Log.addContextDestructured "file" file ) - AsyncLspResult.internalError "Cached typecheck results not yet available" - | Some tyRes -> - match commands.TryGetFileCheckerOptionsWithLinesAndLineStr(file, pos) with - | ResultOrString.Error s -> - logger.error ( - Log.setMessage "PositionHandler - Getting file checker options for {file} failed" - >> Log.addContextDestructured "error" s - >> Log.addContextDestructured "file" file - ) + AsyncLspResult.internalError s + | ResultOrString.Ok (options, lines, lineStr) -> + async { + let! r = Async.Catch(f arg pos tyRes lineStr lines) - AsyncLspResult.internalError s - | ResultOrString.Ok (options, lines, lineStr) -> - async { - let! r = Async.Catch(f arg pos tyRes lineStr lines) - - match r with - | Choice1Of2 r -> return r - | Choice2Of2 e -> - logger.error ( - Log.setMessage "PositionHandler - Failed during child operation on file {file}" - >> Log.addContextDestructured "file" file - >> Log.addExn e - ) + match r with + | Choice1Of2 r -> return r + | Choice2Of2 e -> + logger.error ( + Log.setMessage "PositionHandler - Failed during child operation on file {file}" + >> Log.addContextDestructured "file" file + >> Log.addExn e + ) - return LspResult.internalError e.Message - } + return LspResult.internalError e.Message + } } with | e -> @@ -708,7 +697,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS AsyncLspResult.internalError s | ResultOrString.Ok (options, lines) -> try - let tyResOpt = commands.TryGetRecentTypeCheckResultsForFile(file, options) + let tyResOpt = commands.TryGetRecentTypeCheckResultsForFile(file) match tyResOpt with | None -> @@ -791,7 +780,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS let! (projectOptions, fileLines, lineAtPos) = commands.TryGetFileCheckerOptionsWithLinesAndLineStr(fileName, pos) - match! commands.TryGetLatestTypeCheckResultsForFile(fileName) with + match commands.TryGetRecentTypeCheckResultsForFile(fileName) with | None -> return! Error $"No typecheck results available for %A{fileName}" | Some tyRes -> return tyRes, lineAtPos, fileLines } @@ -1115,16 +1104,16 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS let! typeCheckResults = match p.Context with | None -> - commands.TryGetRecentTypeCheckResultsForFile(file, options) + commands.TryGetRecentTypeCheckResultsForFile(file) |> Result.ofOption (fun _ -> JsonRpc.Error.InternalErrorMessage "No Typecheck results") |> async.Return | Some ctx -> //ctx.triggerKind = CompletionTriggerKind.Invoked || if (ctx.triggerCharacter = Some '.') then - commands.TryGetLatestTypeCheckResultsForFile(file) - |> Async.map (Result.ofOption (fun _ -> JsonRpc.Error.InternalErrorMessage "No Typecheck results")) + commands.GetLatestTypeCheckResultsForFile(file) + |> Async.map Ok else - commands.TryGetRecentTypeCheckResultsForFile(file, options) + commands.TryGetRecentTypeCheckResultsForFile(file) |> Result.ofOption (fun _ -> JsonRpc.Error.InternalErrorMessage "No Typecheck results") |> async.Return @@ -1737,7 +1726,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS | ResultOrString.Ok (options, lines, lineStr) -> try async { - let! tyResOpt = commands.TryGetLatestTypeCheckResultsForFile(file) + let tyResOpt = commands.TryGetRecentTypeCheckResultsForFile(file) match tyResOpt with | None -> return [] @@ -1872,7 +1861,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS | ResultOrString.Ok (options, _, lineStr) -> try async { - let! tyResOpt = commands.TryGetLatestTypeCheckResultsForFile(file) + let tyResOpt = commands.TryGetRecentTypeCheckResultsForFile(file) return! match tyResOpt with @@ -2141,7 +2130,7 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS | ResultOrString.Ok (options, _, lineStr) -> try async { - let! tyResOpt = commands.TryGetLatestTypeCheckResultsForFile(file) + let tyResOpt = commands.TryGetRecentTypeCheckResultsForFile(file) return! match tyResOpt with @@ -2634,21 +2623,19 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS member private x.handleSemanticTokens - (getTokens: Async>>) + (getTokens: Async>) : AsyncLspResult = asyncResult { - match! getTokens |> AsyncResult.ofCoreResponse with - | None -> return! LspResult.internalError "No highlights found" - | Some rangesAndHighlights -> - let lspTypedRanges = - rangesAndHighlights - |> Array.map (fun item -> - let ty, mods = ClassificationUtils.map item.Type - struct (fcsRangeToLsp item.Range, ty, mods)) - - match encodeSemanticHighlightRanges lspTypedRanges with - | None -> return! success None - | Some encoded -> return! success (Some { Data = encoded; ResultId = None }) // TODO: provide a resultId when we support delta ranges + let! rangesAndHighlights = getTokens |> AsyncResult.ofCoreResponse + let lspTypedRanges = + rangesAndHighlights + |> Array.map (fun item -> + let ty, mods = ClassificationUtils.map item.Type + struct (fcsRangeToLsp item.Range, ty, mods)) + + match encodeSemanticHighlightRanges lspTypedRanges with + | None -> return! success None + | Some encoded -> return! success (Some { Data = encoded; ResultId = None }) // TODO: provide a resultId when we support delta ranges } override x.TextDocumentSemanticTokensFull(p: SemanticTokensParams) : AsyncLspResult = diff --git a/utils/fcs39-validate.fsx b/utils/fcs39-validate.fsx index f6f8f9128..e148d1961 100644 --- a/utils/fcs39-validate.fsx +++ b/utils/fcs39-validate.fsx @@ -1,4 +1,4 @@ - #r "nuget: FSharp.Compiler.Service, 39.0.0" +#r "nuget: FSharp.Compiler.Service, 39.0.0" open FSharp.Compiler.SourceCodeServices open FSharp.Compiler.Text open System.IO From cfeed4cb2508ab6c583dba4fa3702c5ceb275921 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Sat, 6 Nov 2021 11:57:53 -0500 Subject: [PATCH 7/7] fix indentation --- src/FsAutoComplete.Core/ParseAndCheckResults.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FsAutoComplete.Core/ParseAndCheckResults.fs b/src/FsAutoComplete.Core/ParseAndCheckResults.fs index 702f22ce2..dd8ebcb4b 100644 --- a/src/FsAutoComplete.Core/ParseAndCheckResults.fs +++ b/src/FsAutoComplete.Core/ParseAndCheckResults.fs @@ -653,8 +653,8 @@ type ParseAndCheckResults && List.isEmpty longName.QualifyingIdents return Some(sortedDecls, residue, shouldKeywords) - with - | :? TimeoutException -> return None + with + | :? TimeoutException -> return None } member __.GetAllEntities(publicOnly: bool) : AssemblySymbol list =