From 44a49a863a481d4adaf6032c9951cc48539e2c2a Mon Sep 17 00:00:00 2001 From: Jimmy Byrd Date: Sat, 1 Jul 2023 18:17:59 -0400 Subject: [PATCH] Swap maybe for option CEs --- .../AbstractClassStubGenerator.fs | 2 +- src/FsAutoComplete.Core/CodeGeneration.fs | 2 +- src/FsAutoComplete.Core/FileSystem.fs | 2 + src/FsAutoComplete.Core/InlayHints.fs | 6 +- .../RecordStubGenerator.fs | 6 +- src/FsAutoComplete.Core/SignatureHelp.fs | 6 +- .../UnionPatternMatchCaseGenerator.fs | 9 +- src/FsAutoComplete.Core/Utils.fs | 142 ------------------ .../CodeFixes/AddExplicitTypeAnnotation.fs | 2 +- 9 files changed, 19 insertions(+), 158 deletions(-) diff --git a/src/FsAutoComplete.Core/AbstractClassStubGenerator.fs b/src/FsAutoComplete.Core/AbstractClassStubGenerator.fs index f6183cf02..ed67a2ed5 100644 --- a/src/FsAutoComplete.Core/AbstractClassStubGenerator.fs +++ b/src/FsAutoComplete.Core/AbstractClassStubGenerator.fs @@ -98,7 +98,7 @@ let tryFindAbstractClassExprInBufferAtPos (pos: Position) (document: IFSACSourceText) = - asyncMaybe { + asyncOption { let! parseResults = codeGenService.ParseFileInProject document.FileName return! tryFindAbstractClassExprInParsedInput pos parseResults.ParseTree } diff --git a/src/FsAutoComplete.Core/CodeGeneration.fs b/src/FsAutoComplete.Core/CodeGeneration.fs index ff915f93f..0e3c5ecd3 100644 --- a/src/FsAutoComplete.Core/CodeGeneration.fs +++ b/src/FsAutoComplete.Core/CodeGeneration.fs @@ -53,7 +53,7 @@ type CodeGenerationService(checker: FSharpCompilerServiceChecker, state: State) } override x.GetSymbolAndUseAtPositionOfKind(fileName, pos: Position, kind) = - asyncMaybe { + asyncOption { let! symbol = (x :> ICodeGenerationService).GetSymbolAtPosition(fileName, pos) if symbol.Kind = kind then diff --git a/src/FsAutoComplete.Core/FileSystem.fs b/src/FsAutoComplete.Core/FileSystem.fs index 22316b919..bc29e1bd8 100644 --- a/src/FsAutoComplete.Core/FileSystem.fs +++ b/src/FsAutoComplete.Core/FileSystem.fs @@ -523,6 +523,8 @@ module RoslynSourceText = new Object() with override _.ToString() = sourceText.ToString() + override _.Equals(x) = sourceText.Equals(x) + override _.GetHashCode() = let checksum = sourceText.GetChecksum() diff --git a/src/FsAutoComplete.Core/InlayHints.fs b/src/FsAutoComplete.Core/InlayHints.fs index e329bcdd2..7cd7fb66a 100644 --- a/src/FsAutoComplete.Core/InlayHints.fs +++ b/src/FsAutoComplete.Core/InlayHints.fs @@ -556,7 +556,7 @@ let private rangeOfNamedPat (text: IFSACSourceText) (pat: SynPat) = match pat with | SynPat.Named(accessibility = None) -> pat.Range | SynPat.Named(ident = SynIdent(ident = ident); accessibility = Some(access)) -> - maybe { + option { let start = ident.idRange.Start let! line = text.GetLine start @@ -706,7 +706,7 @@ let tryGetExplicitTypeInfo (text: IFSACSourceText, ast: ParsedInput) (pos: Posit // * `let f2 = fun (Value v) -> v + 1` // -> compiler generated `_arg1` in `args`, // and `v` is inside match expression in `body` & `parsedData` (-> `SynPat` ) - maybe { + option { let! pat = pats |> List.tryFind (fun p -> rangeContainsPos p.Range pos) let rec tryGetIdent pat = @@ -861,7 +861,7 @@ let tryGetDetailedExplicitTypeInfo (text: IFSACSourceText, parseAndCheck: ParseAndCheckResults) (pos: Position) = - maybe { + option { let! line = text.GetLine pos let! symbolUse = parseAndCheck.TryGetSymbolUse pos line diff --git a/src/FsAutoComplete.Core/RecordStubGenerator.fs b/src/FsAutoComplete.Core/RecordStubGenerator.fs index 258204472..3991ddb63 100644 --- a/src/FsAutoComplete.Core/RecordStubGenerator.fs +++ b/src/FsAutoComplete.Core/RecordStubGenerator.fs @@ -72,7 +72,7 @@ type RecordStubsInsertionParams = Some(fieldInfo, indentColumn, fieldLine) | _ -> None) - maybe { + option { let! maxLineIdx = fieldAndStartColumnAndLineIdxList |> List.unzip3 @@ -212,7 +212,7 @@ let walkAndFindRecordBinding (pos, input) = SyntaxTraversal.Traverse(pos, input, walker) let tryFindRecordExprInBufferAtPos (codeGenService: ICodeGenerationService) (pos: Position) (document: Document) = - asyncMaybe { + asyncOption { let! parseResults = codeGenService.ParseFileInProject(document.FullName) let! found = walkAndFindRecordBinding (pos, parseResults.ParseTree) @@ -270,7 +270,7 @@ let shouldGenerateRecordStub (recordExpr: RecordExpr) (entity: FSharpEntity) = fieldCount > 0 && writtenFieldCount < fieldCount let tryFindRecordDefinitionFromPos (codeGenService: ICodeGenerationService) (pos: Position) (document: Document) = - asyncMaybe { + asyncOption { let! recordExpression, insertionPos = tryFindStubInsertionParamsAtPos codeGenService pos document let! symbol, symbolUse = diff --git a/src/FsAutoComplete.Core/SignatureHelp.fs b/src/FsAutoComplete.Core/SignatureHelp.fs index 2398f0716..a779c1fdb 100644 --- a/src/FsAutoComplete.Core/SignatureHelp.fs +++ b/src/FsAutoComplete.Core/SignatureHelp.fs @@ -33,11 +33,11 @@ let private getSignatureHelpForFunctionApplication endOfPreviousIdentPos: Position, lines: IFSACSourceText ) : Async = - asyncMaybe { + asyncOption { let! lineStr = lines.GetLine endOfPreviousIdentPos let! possibleApplicationSymbolEnd = - maybe { + option { if tyRes.GetParseResults.IsPosContainedInApplicationPatched endOfPreviousIdentPos then let! funcRange = tyRes.GetParseResults.TryRangeOfFunctionOrMethodBeingAppliedPatched endOfPreviousIdentPos return funcRange.End @@ -130,7 +130,7 @@ let private getSignatureHelpForMethod lines: IFSACSourceText, triggerChar ) = - asyncMaybe { + asyncOption { let! paramLocations = tyRes.GetParseResults.FindParameterLocations caretPos let names = paramLocations.LongId let lidEnd = paramLocations.LongIdEndLocation diff --git a/src/FsAutoComplete.Core/UnionPatternMatchCaseGenerator.fs b/src/FsAutoComplete.Core/UnionPatternMatchCaseGenerator.fs index 4c8b6788b..08e9c81d1 100644 --- a/src/FsAutoComplete.Core/UnionPatternMatchCaseGenerator.fs +++ b/src/FsAutoComplete.Core/UnionPatternMatchCaseGenerator.fs @@ -8,6 +8,7 @@ open FSharp.Compiler.Text open FSharp.Compiler.Syntax open FsAutoComplete.CodeGenerationUtils open FSharp.Compiler.Symbols +open FsToolkit.ErrorHandling [] type PatternMatchExpr = @@ -375,7 +376,7 @@ let shouldGenerateUnionPatternMatchCases (patMatchExpr: PatternMatchExpr) (entit caseCount > 0 && writtenCaseCount < caseCount let tryFindPatternMatchExprInBufferAtPos (codeGenService: ICodeGenerationService) (pos: Position) (document: Document) = - asyncMaybe { + asyncOption { let! parseResults = codeGenService.ParseFileInProject(document.FullName) let input = parseResults.ParseTree return! tryFindPatternMatchExprInParsedInput pos input @@ -494,7 +495,7 @@ let checkThatPatternMatchExprEndsWithCompleteClause (expr: PatternMatchExpr) = let tryFindCaseInsertionParamsAtPos (codeGenService: ICodeGenerationService) pos document = - asyncMaybe { + asyncOption { let! patMatchExpr = tryFindPatternMatchExprInBufferAtPos codeGenService pos document if checkThatPatternMatchExprEndsWithCompleteClause patMatchExpr then @@ -505,13 +506,13 @@ let tryFindCaseInsertionParamsAtPos (codeGenService: ICodeGenerationService) pos } let tryFindUnionDefinitionFromPos (codeGenService: ICodeGenerationService) pos document = - asyncMaybe { + asyncOption { let! patMatchExpr, insertionParams = tryFindCaseInsertionParamsAtPos codeGenService pos document let! symbol, symbolUse = codeGenService.GetSymbolAndUseAtPositionOfKind(document.FullName, pos, SymbolKind.Ident) let! superficialTypeDefinition = - asyncMaybe { + asyncOption { let! symbolUse = symbolUse match symbolUse.Symbol with diff --git a/src/FsAutoComplete.Core/Utils.fs b/src/FsAutoComplete.Core/Utils.fs index c055d8772..a8d433032 100644 --- a/src/FsAutoComplete.Core/Utils.fs +++ b/src/FsAutoComplete.Core/Utils.fs @@ -76,8 +76,6 @@ module ProcessHelper = () } - - type ResultOrString<'a> = Result<'a, string> type Serializer = obj -> string @@ -251,141 +249,6 @@ module AsyncResult = let inline bimap okF errF r = Async.map (Result.bimap okF errF) r let inline ofOption recover o = Async.map (Result.ofOption recover) o -// Maybe computation expression builder, copied from ExtCore library -/// https://github.com/jack-pappas/ExtCore/blob/master/ExtCore/Control.fs -[] -type MaybeBuilder() = - // 'T -> M<'T> - [] - member inline __.Return value : 'T option = Some value - - // M<'T> -> M<'T> - [] - member inline __.ReturnFrom value : 'T option = value - - // unit -> M<'T> - [] - member inline __.Zero() : unit option = Some() // TODO: Should this be None? - - // (unit -> M<'T>) -> M<'T> - [] - member __.Delay(f: unit -> 'T option) : 'T option = f () - - // M<'T> -> M<'T> -> M<'T> - // or - // M -> M<'T> -> M<'T> - [] - member inline __.Combine(r1, r2: 'T option) : 'T option = - match r1 with - | None -> None - | Some() -> r2 - - // M<'T> * ('T -> M<'U>) -> M<'U> - [] - member inline __.Bind(value, f: 'T -> 'U option) : 'U option = Option.bind f value - - // 'T * ('T -> M<'U>) -> M<'U> when 'U :> IDisposable - [] - member __.Using(resource: ('T :> IDisposable), body: _ -> _ option) : _ option = - try - body resource - finally - if not <| obj.ReferenceEquals(null, box resource) then - resource.Dispose() - - // (unit -> bool) * M<'T> -> M<'T> - [] - member x.While(guard, body: _ option) : _ option = - if guard () then - // OPTIMIZE: This could be simplified so we don't need to make calls to Bind and While. - x.Bind(body, (fun () -> x.While(guard, body))) - else - x.Zero() - - // seq<'T> * ('T -> M<'U>) -> M<'U> - // or - // seq<'T> * ('T -> M<'U>) -> seq> - [] - member x.For(sequence: seq<_>, body: 'T -> unit option) : _ option = - // OPTIMIZE: This could be simplified so we don't need to make calls to Using, While, Delay. - x.Using(sequence.GetEnumerator(), (fun enum -> x.While(enum.MoveNext, x.Delay(fun () -> body enum.Current)))) - -[] -type AsyncMaybeBuilder() = - [] - member __.Return value : Async<'T option> = Some value |> async.Return - - [] - member __.ReturnFrom value : Async<'T option> = value - - [] - member __.ReturnFrom(value: 'T option) : Async<'T option> = async.Return value - - [] - member __.Zero() : Async = Some() |> async.Return - - [] - member __.Delay(f: unit -> Async<'T option>) : Async<'T option> = f () - - [] - member __.Combine(r1, r2: Async<'T option>) : Async<'T option> = - async { - let! r1' = r1 - - match r1' with - | None -> return None - | Some() -> return! r2 - } - - [] - member __.Bind(value: Async<'T option>, f: 'T -> Async<'U option>) : Async<'U option> = - async { - let! value' = value - - match value' with - | None -> return None - | Some result -> return! f result - } - - [] - member __.Bind(value: 'T option, f: 'T -> Async<'U option>) : Async<'U option> = - async { - match value with - | None -> return None - | Some result -> return! f result - } - - [] - member __.Using(resource: ('T :> IDisposable), body: _ -> Async<_ option>) : Async<_ option> = - try - body resource - finally - if not << isNull <| resource then - resource.Dispose() - - [] - member x.While(guard, body: Async<_ option>) : Async<_ option> = - if guard () then - x.Bind(body, (fun () -> x.While(guard, body))) - else - x.Zero() - - [] - member x.For(sequence: seq<_>, body: 'T -> Async) : Async<_ option> = - x.Using(sequence.GetEnumerator(), (fun enum -> x.While(enum.MoveNext, x.Delay(fun () -> body enum.Current)))) - - [] - member inline __.TryWith(computation: Async<'T option>, catchHandler: exn -> Async<'T option>) : Async<'T option> = - async.TryWith(computation, catchHandler) - - [] - member inline __.TryFinally(computation: Async<'T option>, compensation: unit -> unit) : Async<'T option> = - async.TryFinally(computation, compensation) - -[] -module AsyncMaybe = - let inline liftAsync (async: Async<'T>) : Async<_ option> = async |> Async.map Some - [] [] @@ -533,9 +396,6 @@ module List = |> List.groupBy (fst) |> List.map (fun (key, list) -> key, list |> List.map snd) - - - [] [] module String = @@ -731,8 +591,6 @@ type Path with let inline debug msg = Printf.kprintf Debug.WriteLine msg let inline fail msg = Printf.kprintf Debug.Fail msg -let asyncMaybe = AsyncMaybeBuilder() -let maybe = MaybeBuilder() let chooseByPrefix (prefix: string) (s: string) = diff --git a/src/FsAutoComplete/CodeFixes/AddExplicitTypeAnnotation.fs b/src/FsAutoComplete/CodeFixes/AddExplicitTypeAnnotation.fs index c56235876..c96ced627 100644 --- a/src/FsAutoComplete/CodeFixes/AddExplicitTypeAnnotation.fs +++ b/src/FsAutoComplete/CodeFixes/AddExplicitTypeAnnotation.fs @@ -30,7 +30,7 @@ let private isPositionContainedInUntypedImplicitCtorParameter input pos = member _.VisitModuleDecl(_, defaultTraverse, decl) = match decl with | SynModuleDecl.Types(typeDefns = typeDefns) -> - maybe { + option { let! ctorArgs = typeDefns |> List.tryPick (function