Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions src/FsAutoComplete.Core/CompilerServiceInterface.fs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ type CompilerProjectOption =

member x.SourceFilesTagged =
match x with
| BackgroundCompiler(options) -> options.SourceFiles |> Array.toList
| TransparentCompiler(snapshot) -> snapshot.SourceFiles |> List.map (fun f -> f.FileName)
|> List.map Utils.normalizePath
| BackgroundCompiler(options) -> options.SourceFiles |> Array.map Utils.normalizePath |> Array.toList
| TransparentCompiler(snapshot) -> snapshot.SourceFiles |> List.map (fun f -> Utils.normalizePath f.FileName)

member x.ReferencedProjectsPath =
match x with
Expand Down Expand Up @@ -189,12 +188,16 @@ type FSharpCompilerServiceChecker
None

let processFSIArgs args =
(([||], [||]), args)
||> Array.fold (fun (args, files) arg ->
let argsOut = ResizeArray()
let filesOut = ResizeArray()

for arg in args do
match arg with
| StartsWith "--use:" file
| StartsWith "--load:" file -> args, Array.append files [| file |]
| arg -> Array.append args [| arg |], files)
| StartsWith "--load:" file -> filesOut.Add(file)
| arg -> argsOut.Add(arg)

argsOut.ToArray(), filesOut.ToArray()

let (|Reference|_|) (opt: string) =
if opt.StartsWith("-r:", StringComparison.Ordinal) then
Expand Down
25 changes: 22 additions & 3 deletions src/FsAutoComplete.Core/FileSystem.fs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ module RoslynSourceText =

type RoslynSourceTextFile(fileName: string<LocalPath>, sourceText: SourceText) =

let cachedLines =
lazy (sourceText.Lines |> Seq.toArray |> Array.map (fun l -> l.ToString()))

let walk
(
x: IFSACSourceText,
Expand Down Expand Up @@ -250,8 +253,7 @@ module RoslynSourceText =
member x.TotalRange: Range =
(Range.mkRange (UMX.untag fileName) Position.pos0 ((x :> IFSACSourceText).LastFilePosition))

member x.Lines: string array =
sourceText.Lines |> Seq.toArray |> Array.map (fun l -> l.ToString())
member x.Lines: string array = cachedLines.Value

member this.GetText(range: Range) : Result<string, string> =
range.ToRoslynTextSpan(sourceText) |> sourceText.GetSubText |> string |> Ok
Expand Down Expand Up @@ -488,7 +490,24 @@ type FileSystem(actualFs: IFileSystem, tryFindFile: string<LocalPath> -> Volatil
>> Log.addContext "hash" (file.Source.GetHashCode())
)

file.Source.ToString() |> System.Text.Encoding.UTF8.GetBytes)
// Write source text to bytes in chunks via CopyTo, avoiding a full intermediate string allocation
let source = file.Source :> FSharp.Compiler.Text.ISourceText
let length = source.Length
let ms = new MemoryStream()
let utf8NoBom = System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier = false)
use sw = new StreamWriter(ms, utf8NoBom, bufferSize = 4096, leaveOpen = true)
let chunkSize = 8192
let charBuffer = Array.zeroCreate (min length chunkSize)
let mutable offset = 0

while offset < length do
let count = min (length - offset) charBuffer.Length
source.CopyTo(offset, charBuffer, 0, count)
sw.Write(charBuffer, 0, count)
offset <- offset + count

sw.Flush()
ms.ToArray())

/// translation of the BCL's Windows logic for Path.IsPathRooted.
///
Expand Down
18 changes: 13 additions & 5 deletions src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -763,10 +763,14 @@ type AdaptiveFSharpLspServer
| Error e -> return Error e
}

let getCompletions forceGetTypeCheckResultsStale =
let getCompletions forceGetTypeCheckResultsStale rereadFile =
asyncResult {

let! volatileFile = state.GetOpenFileOrRead filePath
let! volatileFile =
if rereadFile then
state.GetOpenFileOrRead filePath
else
async { return Ok volatileFile }

let! lineStr =
volatileFile.Source
Expand Down Expand Up @@ -815,8 +819,12 @@ type AdaptiveFSharpLspServer
match e with
| "Should not have empty completions" ->
// If we don't get any completions, assume we need to wait for a full typecheck
getCompletions state.GetOpenFileTypeCheckResults
| _ -> getCompletions state.GetOpenFileTypeCheckResultsCached
// No need to re-read the file — only the typecheck results matter
getCompletions state.GetOpenFileTypeCheckResults false
| "TextDocumentCompletion was sent before TextDocumentDidChange" ->
// File content is stale, re-read on next attempt
getCompletions state.GetOpenFileTypeCheckResultsCached true
| _ -> getCompletions state.GetOpenFileTypeCheckResultsCached true

let getCodeToInsert (d: DeclarationListItem) =
match d.NamespaceToOpen with
Expand Down Expand Up @@ -850,7 +858,7 @@ type AdaptiveFSharpLspServer
(TimeSpan.FromMilliseconds(15.))
100
handleError
(getCompletions state.GetOpenFileTypeCheckResultsCached)
(getCompletions state.GetOpenFileTypeCheckResultsCached false)
|> AsyncResult.ofStringErr
with
| None -> return! LspResult.success (None)
Expand Down
2 changes: 1 addition & 1 deletion src/FsAutoComplete/LspServers/AdaptiveServerState.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,7 @@ type AdaptiveState
let tags =
[ SemanticConventions.fsac_sourceCodePath, box (UMX.untag file.Source.FileName)
SemanticConventions.projectFilePath, box (options.ProjectFileName)
"source.text", box (file.Source.String)
"source.length", box (file.Source.Length)
"source.version", box (file.Version)

]
Expand Down
Loading