@@ -150,6 +150,9 @@ codeLens recorder st plId CodeLensParams{_textDocument} = do
150150 | (range, command) <- rangeCommands
151151 ]
152152
153+ -- | Find every test in the document and pair its source range with the
154+ -- 'Command' that evaluates it. Shared by the code action and code lens
155+ -- providers.
153156mkRangeCommands :: Recorder (WithPriority Log ) -> IdeState -> PluginId -> TextDocumentIdentifier -> ExceptT PluginError (HandlerM Config ) [(Range , Command )]
154157mkRangeCommands recorder st plId textDocument =
155158 let dbg = logWith recorder Debug
@@ -309,6 +312,9 @@ initialiseSessionForEval needs_quickcheck st nfp = do
309312 getSession
310313 return env2
311314
315+ -- | Convert the typechecker's import specs into the interface representation,
316+ -- so the reconstructed iface for the current module records what it imports
317+ -- (needed when re-adding the rdr env, see 'initialiseSessionForEval').
312318#if MIN_VERSION_ghc(9,13,0)
313319mkIfaceImports :: [ImportUserSpec ] -> [IfaceImport ]
314320mkIfaceImports = map go
@@ -325,12 +331,15 @@ mkIfaceImports = map go
325331 go (ImpUserSpec decl (ImpUserEverythingBut ns)) = IfaceImport decl (ImpIfaceEverythingBut ns)
326332#endif
327333
334+ -- | Prepend an edit adding a trailing newline when the module does not end in
335+ -- one, so the appended results land on their own line.
328336addFinalReturn :: Text -> [TextEdit ] -> [TextEdit ]
329337addFinalReturn mdlText edits
330338 | not (null edits) && not (T. null mdlText) && T. last mdlText /= ' \n ' =
331339 finalReturn mdlText : edits
332340 | otherwise = edits
333341
342+ -- | An empty edit at the very end of the module that inserts a newline.
334343finalReturn :: Text -> TextEdit
335344finalReturn txt =
336345 let ls = T. lines txt
@@ -339,6 +348,7 @@ finalReturn txt =
339348 p = Position l c
340349 in TextEdit (Range p p) " \n "
341350
351+ -- | The current (possibly unsaved) contents of the module as seen by the IDE.
342352moduleText :: IdeState -> Uri -> ExceptT PluginError (HandlerM config ) Text
343353moduleText state uri = do
344354 contents <-
@@ -349,6 +359,8 @@ moduleText state uri = do
349359 toNormalizedUri uri
350360 pure $ Rope. toText contents
351361
362+ -- | Flatten sections into their individual tests, tagging each with the index
363+ -- ('EvalId') of its containing section.
352364testsBySection :: [Section ] -> [(Section , EvalId , Test )]
353365testsBySection sections =
354366 [(section, ident, test)
@@ -370,6 +382,9 @@ evalSetup = do
370382 context <- getContext
371383 setContext (IIDecl preludeAsP : IIDecl systemIO : IIDecl ghcIOHandle : context)
372384
385+ -- | Evaluate every test and produce the 'TextEdit's that write the results
386+ -- back into the document, prefixing/padding each result line as the section's
387+ -- format requires.
373388runTests :: Recorder (WithPriority Log ) -> EvalConfig -> TEnv -> [(Section , Test )] -> Ghc [TextEdit ]
374389runTests recorder EvalConfig {.. } e tests = do
375390 df <- getInteractiveDynFlags
@@ -400,6 +415,10 @@ runTests recorder EvalConfig{..} e tests = do
400415 " Add QuickCheck to your cabal dependencies to run this test."
401416 runTest e df test = evals recorder (eval_cfg_exception && not (isProperty test)) e df (asStatements test)
402417
418+ -- | Build the edit that replaces a test's old result with @resultLines@. For a
419+ -- test that sits on the closing @-}@ line of a block comment, the result is
420+ -- inserted before @-}@ on fresh lines; otherwise it simply overwrites the
421+ -- existing result range.
403422asEdit :: Format -> Test -> [Text ] -> TextEdit
404423asEdit (MultiLine commRange) test resultLines
405424 -- A test in a block comment, ending with @-\}@ without newline in-between.
@@ -618,6 +637,9 @@ ghciLikeCommands =
618637 , (" type" , doTypeCmd)
619638 ]
620639
640+ -- | Dispatch a GHCi-like command (e.g. @:type@, @:kind@, @:info@) to its
641+ -- handler, matching by exact name or unique prefix. Throws if no command
642+ -- matches.
621643evalGhciLikeCmd :: Text -> Text -> Ghc (Maybe [Text ])
622644evalGhciLikeCmd cmd arg = do
623645 df <- getSessionDynFlags
@@ -630,6 +652,8 @@ evalGhciLikeCmd cmd arg = do
630652 <$> hndler df arg
631653 _ -> E. throw $ GhciLikeCmdNotImplemented cmd arg
632654
655+ -- | Implement @:info@ / @:info!@: show the definition, fixity and instances of
656+ -- each named thing. The 'Bool' is the @!@ variant, including all instances.
633657doInfoCmd :: Bool -> DynFlags -> Text -> Ghc (Maybe Text )
634658doInfoCmd allInfo dflags s = do
635659 sdocs <- mapM infoThing (T. words s)
@@ -675,6 +699,8 @@ doInfoCmd allInfo dflags s = do
675699 = ppr fixity <+> pprInfixName (GHC. getName thing)
676700 | otherwise = empty
677701
702+ -- | Implement @:kind@ / @:kind!@: show a type's kind. The 'Bool' is the @!@
703+ -- variant, additionally normalising and showing the type itself.
678704doKindCmd :: Bool -> DynFlags -> Text -> Ghc (Maybe Text )
679705doKindCmd False df arg = do
680706 let input = T. strip arg
@@ -688,6 +714,8 @@ doKindCmd True df arg = do
688714 tyDoc = " =" <+> pprSigmaType ty
689715 pure $ Just $ T. pack (showSDoc df $ kindDoc $$ tyDoc)
690716
717+ -- | Implement @:type@: show the type of an expression. Accepts a leading
718+ -- @+d@ to request the defaulted type (see 'parseExprMode').
691719doTypeCmd :: DynFlags -> Text -> Ghc (Maybe Text )
692720doTypeCmd dflags arg = do
693721 let (emod, expr) = parseExprMode arg
@@ -704,6 +732,8 @@ doTypeCmd dflags arg = do
704732 $$ nest 2 (" ::" <+> pprSigmaType ty)
705733 else expr <> " :: " <> rawType <> " \n "
706734
735+ -- | Split a @:type@ argument into its mode and expression: a leading @+d@
736+ -- selects defaulting ('TM_Default'), anything else the plain type ('TM_Inst').
707737parseExprMode :: Text -> (TcRnExprMode , T. Text )
708738parseExprMode rawArg = case T. break isSpace rawArg of
709739 (" +d" , rest) -> (TM_Default , T. strip rest)
0 commit comments