Skip to content

Commit 31f1ff8

Browse files
committed
Merge branch 'meta-use-any-term' into cata
2 parents 9eac5ac + f0872f9 commit 31f1ff8

File tree

13 files changed

+102
-39
lines changed

13 files changed

+102
-39
lines changed

plugins/hls-tactics-plugin/src/Wingman/LanguageServer.hs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{-# LANGUAGE CPP #-}
22
{-# LANGUAGE OverloadedStrings #-}
33
{-# LANGUAGE RankNTypes #-}
4+
{-# LANGUAGE TupleSections #-}
45
{-# LANGUAGE TypeFamilies #-}
56

67
{-# LANGUAGE NoMonoLocalBinds #-}
7-
{-# LANGUAGE TupleSections #-}
88

99
module Wingman.LanguageServer where
1010

@@ -17,7 +17,6 @@ import Control.Monad.State (State, evalState)
1717
import Control.Monad.Trans.Maybe
1818
import Data.Bifunctor (first)
1919
import Data.Coerce
20-
import Data.Foldable (toList)
2120
import Data.Functor ((<&>))
2221
import Data.Functor.Identity (runIdentity)
2322
import qualified Data.HashMap.Strict as Map
@@ -67,7 +66,6 @@ import Wingman.GHC
6766
import Wingman.Judgements
6867
import Wingman.Judgements.SYB (everythingContaining, metaprogramQ)
6968
import Wingman.Judgements.Theta
70-
import Wingman.Machinery (getOccNameType)
7169
import Wingman.Metaprogramming.Lexer (ParserContext(..))
7270
import Wingman.Range
7371
import Wingman.StaticPlugin (pattern WingmanMetaprogram, pattern MetaprogramSyntax)
@@ -581,6 +579,10 @@ mkWorkspaceEdits dflags ccs uri pm g = do
581579
in first (InfrastructureError . T.pack) response
582580

583581

582+
------------------------------------------------------------------------------
583+
-- | Add ExactPrint annotations to every metaprogram in the source tree.
584+
-- Usually the ExactPrint module can do this for us, but we've enabled
585+
-- QuasiQuotes, so the round-trip print/parse journey will crash.
584586
annotateMetaprograms :: Data a => a -> Transform a
585587
annotateMetaprograms = everywhereM $ mkM $ \case
586588
L ss (WingmanMetaprogram mp) -> do
@@ -591,6 +593,8 @@ annotateMetaprograms = everywhereM $ mkM $ \case
591593
(x :: LHsExpr GhcPs) -> pure x
592594

593595

596+
------------------------------------------------------------------------------
597+
-- | Find the source of a tactic metaprogram at the given span.
594598
getMetaprogramAtSpan
595599
:: Tracked age SrcSpan
596600
-> Tracked age TcGblEnv
@@ -603,36 +607,19 @@ getMetaprogramAtSpan (unTrack -> ss)
603607
. unTrack
604608

605609

606-
getOccNameTypes
607-
:: Foldable t
608-
=> IdeState
609-
-> NormalizedFilePath
610-
-> t OccName
611-
-> MaybeT IO (M.Map OccName Type)
612-
getOccNameTypes state nfp occs = do
613-
let stale a = runStaleIde "getOccNameTypes" state nfp a
614-
615-
TrackedStale (unTrack -> tcmod) _ <- stale TypeCheck
616-
TrackedStale (unTrack -> hscenv) _ <- stale GhcSessionDeps
617-
618-
let tcgblenv = tmrTypechecked tcmod
619-
modul = extractModule tcgblenv
620-
rdrenv = tcg_rdr_env tcgblenv
621-
lift $ fmap M.fromList $
622-
fmap join $ for (toList occs) $ \occ ->
623-
fmap (maybeToList . fmap (occ, )) $
624-
getOccNameType (hscEnv hscenv) rdrenv modul occ
625-
626-
610+
------------------------------------------------------------------------------
611+
-- | The metaprogram parser needs the ability to lookup terms from the module
612+
-- and imports. The 'ParserContext' contains everything we need to find that
613+
-- stuff.
627614
getParserState
628615
:: IdeState
629616
-> NormalizedFilePath
630-
-> Context
617+
-> Context
631618
-> MaybeT IO ParserContext
632619
getParserState state nfp ctx = do
633-
let stale a = runStaleIde "getOccNameTypes" state nfp a
620+
let stale a = runStaleIde "getParserState" state nfp a
634621

635-
TrackedStale (unTrack -> tcmod) _ <- stale TypeCheck
622+
TrackedStale (unTrack -> tcmod) _ <- stale TypeCheck
636623
TrackedStale (unTrack -> hscenv) _ <- stale GhcSessionDeps
637624

638625
let tcgblenv = tmrTypechecked tcmod

plugins/hls-tactics-plugin/src/Wingman/Machinery.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ useNameFromContext f name = do
332332
Nothing -> throwError $ NotInScope name
333333

334334

335+
------------------------------------------------------------------------------
336+
-- | Find the type of an 'OccName' that is defined in the current module.
335337
lookupNameInContext :: MonadReader Context m => OccName -> m (Maybe CType)
336338
lookupNameInContext name = do
337339
ctx <- asks ctxModuleFuncs
@@ -340,6 +342,8 @@ lookupNameInContext name = do
340342
Nothing -> empty
341343

342344

345+
------------------------------------------------------------------------------
346+
-- | Build a 'HyInfo' for an imported term.
343347
createImportedHyInfo :: OccName -> CType -> HyInfo CType
344348
createImportedHyInfo on ty = HyInfo
345349
{ hi_name = on
@@ -348,6 +352,10 @@ createImportedHyInfo on ty = HyInfo
348352
}
349353

350354

355+
------------------------------------------------------------------------------
356+
-- | Lookup the type of any 'OccName' that was imported. Necessarily done in
357+
-- IO, so we only expose this functionality to the parser. Internal Haskell
358+
-- code that wants to lookup terms should do it via 'KnownThings'.
351359
getOccNameType
352360
:: HscEnv
353361
-> OccEnv [GlobalRdrElt]

plugins/hls-tactics-plugin/src/Wingman/Metaprogramming/Lexer.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import qualified Text.Megaparsec.Char.Lexer as L
2020
import Wingman.Types (Context)
2121

2222

23+
------------------------------------------------------------------------------
24+
-- | Everything we need in order to call 'Wingman.Machinery.getOccNameType'.
2325
data ParserContext = ParserContext
2426
{ ps_hscEnv :: HscEnv
2527
, ps_occEnv :: OccEnv [GlobalRdrElt]

plugins/hls-tactics-plugin/src/Wingman/Metaprogramming/Parser.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,21 @@ import Wingman.Types
2727
nullary :: T.Text -> TacticsM () -> Parser (TacticsM ())
2828
nullary name tac = identifier name $> tac
2929

30+
3031
unary_occ :: T.Text -> (OccName -> TacticsM ()) -> Parser (TacticsM ())
3132
unary_occ name tac = tac <$> (identifier name *> variable)
3233

34+
35+
------------------------------------------------------------------------------
36+
-- | Like 'unary_occ', but runs directly in the 'Parser' monad.
3337
unary_occM :: T.Text -> (OccName -> Parser (TacticsM ())) -> Parser (TacticsM ())
3438
unary_occM name tac = tac =<< (identifier name *> variable)
3539

40+
3641
variadic_occ :: T.Text -> ([OccName] -> TacticsM ()) -> Parser (TacticsM ())
3742
variadic_occ name tac = tac <$> (identifier name *> P.many variable)
3843

44+
3945
oneTactic :: Parser (TacticsM ())
4046
oneTactic =
4147
P.choice
@@ -106,6 +112,9 @@ wrapError :: String -> String
106112
wrapError err = "```\n" <> err <> "\n```\n"
107113

108114

115+
------------------------------------------------------------------------------
116+
-- | Attempt to run a metaprogram tactic, returning the proof state, or the
117+
-- errors.
109118
attempt_it
110119
:: Context
111120
-> Judgement
@@ -130,6 +139,8 @@ parseMetaprogram
130139
. P.runParserT tacticProgram "<splice>"
131140

132141

142+
------------------------------------------------------------------------------
143+
-- | Like 'getOccNameType', but runs in the 'Parser' monad.
133144
getOccTy :: OccName -> Parser Type
134145
getOccTy occ = do
135146
ParserContext hscenv rdrenv modul _ <- ask

plugins/hls-tactics-plugin/src/Wingman/Tactics.hs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,23 @@ import qualified Data.Set as S
2424
import DataCon
2525
import Development.IDE.GHC.Compat
2626
import GHC.Exts
27+
import GHC.SourceGen ((@@))
2728
import GHC.SourceGen.Expr
2829
import Name (occNameString, occName)
30+
import OccName (mkVarOcc)
2931
import Refinery.Tactic
3032
import Refinery.Tactic.Internal
3133
import TcType
3234
import Type hiding (Var)
35+
import TysPrim (betaTy, alphaTy, betaTyVar, alphaTyVar)
3336
import Wingman.CodeGen
3437
import Wingman.Context
3538
import Wingman.GHC
3639
import Wingman.Judgements
3740
import Wingman.Machinery
3841
import Wingman.Naming
42+
import Wingman.StaticPlugin (pattern MetaprogramSyntax)
3943
import Wingman.Types
40-
import OccName (mkVarOcc)
41-
import Wingman.StaticPlugin (pattern MetaprogramSyntax)
42-
import GHC.SourceGen ((@@))
43-
import TysPrim (betaTy, alphaTy, betaTyVar, alphaTyVar)
4444

4545

4646
------------------------------------------------------------------------------
@@ -440,6 +440,9 @@ applyByName name = do
440440
False -> empty
441441

442442

443+
------------------------------------------------------------------------------
444+
-- | Make a function application where the function being applied itself is
445+
-- a hole.
443446
applyByType :: Type -> TacticsM ()
444447
applyByType ty = tracing ("applyByType " <> show ty) $ do
445448
jdg <- goal
@@ -463,9 +466,14 @@ applyByType ty = tracing ("applyByType " <> show ty) $ do
463466
<*> fmap (fmap unLoc) ext
464467

465468

469+
------------------------------------------------------------------------------
470+
-- | Make an n-ary function call of the form
471+
-- @(_ :: forall a b. a -> a -> b) _ _@.
466472
nary :: Int -> TacticsM ()
467-
nary n = do
468-
applyByType $ mkInvForAllTys [alphaTyVar, betaTyVar] $ mkFunTys (replicate n alphaTy) betaTy
473+
nary n =
474+
applyByType $
475+
mkInvForAllTys [alphaTyVar, betaTyVar] $
476+
mkFunTys (replicate n alphaTy) betaTy
469477

470478

471479
self :: TacticsM ()

plugins/hls-tactics-plugin/src/Wingman/Types.hs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,6 @@ instance Show TyCon where
153153
instance Show ConLike where
154154
show = unsafeRender
155155

156-
instance Show (HsBindLR GhcTc GhcTc) where
157-
show = unsafeRender
158-
159-
instance Show (ABExport GhcTc) where
160-
show = unsafeRender
161-
162156

163157
------------------------------------------------------------------------------
164158
-- | The state that should be shared between subgoals. Extracts move towards

plugins/hls-tactics-plugin/test/CodeAction/RunMetaprogramSpec.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ spec = do
2828
metaTest 2 32 "MetaBindAll"
2929
metaTest 2 13 "MetaTry"
3030
metaTest 2 74 "MetaChoice"
31+
metaTest 5 40 "MetaUseImport"
32+
metaTest 6 31 "MetaUseLocal"
33+
metaTest 11 11 "MetaUseMethod"
3134
metaTest 9 38 "MetaCataCollapse"
3235
metaTest 7 16 "MetaCataCollapseUnary"
3336

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Data.Char
2+
3+
4+
result :: Char -> Bool
5+
result = isAlpha
6+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Data.Char
2+
3+
4+
result :: Char -> Bool
5+
result = [wingman| intro c, use isAlpha, assume c |]
6+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
test :: Int
2+
test = 0
3+
4+
5+
resolve :: Int
6+
resolve = test
7+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
test :: Int
2+
test = 0
3+
4+
5+
resolve :: Int
6+
resolve = [wingman| use test |]
7+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{-# LANGUAGE MultiParamTypeClasses #-}
2+
3+
class Test where
4+
test :: Int
5+
6+
instance Test where
7+
test = 10
8+
9+
10+
resolve :: Int
11+
resolve = test
12+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{-# LANGUAGE MultiParamTypeClasses #-}
2+
3+
class Test where
4+
test :: Int
5+
6+
instance Test where
7+
test = 10
8+
9+
10+
resolve :: Int
11+
resolve = [wingman| use test |]
12+

0 commit comments

Comments
 (0)