Skip to content

Commit 3bec234

Browse files
jinwooaherrmann-da
authored andcommitted
Support plugins (#192)
* Support plugins Call initializePlugins before running typecheck. * call initializePlugins only for GHC >= 8.6 initializePlugins doesn't exist in older GHC versions. * A separate function for initializing plugins * Add a test for plugins
1 parent 7a215d2 commit 3bec234

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

ghcide.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ test-suite ghcide-tests
187187
ghc,
188188
--------------------------------------------------------------
189189
ghcide,
190+
ghc-typelits-knownnat,
190191
haskell-lsp-types,
191192
lens,
192193
lsp-test >= 0.8,

src/Development/IDE/Core/Compile.hs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ import qualified GHC.LanguageExtensions.Type as GHC
2828
import Development.IDE.Types.Options
2929
import Development.IDE.Types.Location
3030

31+
#if MIN_GHC_API_VERSION(8,6,0)
32+
import DynamicLoading (initializePlugins)
33+
#endif
34+
3135
import GHC hiding (parseModule, typecheckModule)
3236
import qualified Parser
3337
import Lexer
@@ -95,11 +99,23 @@ typecheckModule (IdeDefer defer) packageState deps pm =
9599
runGhcEnv packageState $
96100
catchSrcErrors "typecheck" $ do
97101
setupEnv deps
102+
let modSummary = pm_mod_summary pm
103+
modSummary' <- initPlugins modSummary
98104
(warnings, tcm) <- withWarnings "typecheck" $ \tweak ->
99-
GHC.typecheckModule $ demoteIfDefer pm{pm_mod_summary = tweak $ pm_mod_summary pm}
105+
GHC.typecheckModule $ demoteIfDefer pm{pm_mod_summary = tweak modSummary'}
100106
tcm2 <- mkTcModuleResult tcm
101107
return (map unDefer warnings, tcm2)
102108

109+
initPlugins :: GhcMonad m => ModSummary -> m ModSummary
110+
initPlugins modSummary = do
111+
#if MIN_GHC_API_VERSION(8,6,0)
112+
session <- getSession
113+
dflags <- liftIO $ initializePlugins session (ms_hspp_opts modSummary)
114+
return modSummary{ms_hspp_opts = dflags}
115+
#else
116+
return modSummary
117+
#endif
118+
103119
-- | Compile a single type-checked module to a 'CoreModule' value, or
104120
-- provide errors.
105121
compileModule

test/exe/Main.hs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ main = defaultMain $ testGroup "HIE"
4040
, diagnosticTests
4141
, codeActionTests
4242
, findDefinitionAndHoverTests
43+
, pluginTests
4344
]
4445

4546
initializeResponseTests :: TestTree
@@ -810,6 +811,28 @@ findDefinitionAndHoverTests = let
810811
broken = Just . (`xfail` "known broken")
811812
-- no = const Nothing -- don't run this test at all
812813

814+
pluginTests :: TestTree
815+
pluginTests = testSessionWait "plugins" $ do
816+
let content =
817+
T.unlines
818+
[ "{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}"
819+
, "{-# LANGUAGE DataKinds, ScopedTypeVariables, TypeOperators #-}"
820+
, "module Testing where"
821+
, "import Data.Proxy"
822+
, "import GHC.TypeLits"
823+
-- This function fails without plugins being initialized.
824+
, "f :: forall n. KnownNat n => Proxy n -> Integer"
825+
, "f _ = natVal (Proxy :: Proxy n) + natVal (Proxy :: Proxy (n+2))"
826+
, "foo :: Int -> Int -> Int"
827+
, "foo a b = a + c"
828+
]
829+
_ <- openDoc' "Testing.hs" "haskell" content
830+
expectDiagnostics
831+
[ ( "Testing.hs",
832+
[(DsError, (8, 14), "Variable not in scope: c")]
833+
)
834+
]
835+
813836
xfail :: TestTree -> String -> TestTree
814837
xfail = flip expectFailBecause
815838

0 commit comments

Comments
 (0)