Skip to content

Add Wingman support for GHC 9.2 #3382

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
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
4 changes: 2 additions & 2 deletions ghcide/src/Development/IDE/Core/Rules.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ import Ide.Plugin.Properties (HasProperty,
ToHsType,
useProperty)
import Ide.PluginUtils (configForPlugin)
import Ide.Types (DynFlagsModifications (dynFlagsModifyGlobal, dynFlagsModifyParser),
import Ide.Types (GhcOptsModifications (dynFlagsModifyGlobal, dynFlagsModifyParser),
PluginId)
import Control.Concurrent.STM.Stats (atomically)
import Language.LSP.Server (LspT)
Expand Down Expand Up @@ -338,7 +338,7 @@ getParsedModuleWithCommentsRule recorder =

liftIO $ fmap (fmap reset_ms) $ snd <$> getParsedModuleDefinition (hscEnv sess) opt file ms

getModifyDynFlags :: (DynFlagsModifications -> a) -> Action a
getModifyDynFlags :: (GhcOptsModifications -> a) -> Action a
getModifyDynFlags f = do
opts <- getIdeOptions
cfg <- getClientConfigAction def
Expand Down
4 changes: 2 additions & 2 deletions ghcide/src/Development/IDE/Plugin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import Data.Default
import Development.IDE.Graph

import Development.IDE.LSP.Server
import Ide.Types (DynFlagsModifications)
import Ide.Types (GhcOptsModifications)
import qualified Language.LSP.Server as LSP

data Plugin c = Plugin
{pluginRules :: Rules ()
,pluginHandlers :: LSP.Handlers (ServerM c)
,pluginModifyDynflags :: c -> DynFlagsModifications
,pluginModifyDynflags :: c -> GhcOptsModifications
}

instance Default (Plugin c) where
Expand Down
2 changes: 1 addition & 1 deletion ghcide/src/Development/IDE/Plugin/HLS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ rulesPlugins rs = mempty { P.pluginRules = rules }
where
rules = foldMap snd rs

dynFlagsPlugins :: [(PluginId, DynFlagsModifications)] -> Plugin Config
dynFlagsPlugins :: [(PluginId, GhcOptsModifications)] -> Plugin Config
dynFlagsPlugins rs = mempty
{ P.pluginModifyDynflags =
flip foldMap rs $ \(plId, dflag_mods) cfg ->
Expand Down
4 changes: 2 additions & 2 deletions ghcide/src/Development/IDE/Types/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import Development.IDE.GHC.Compat as GHC
import Development.IDE.Graph
import Development.IDE.Types.Diagnostics
import Ide.Plugin.Config
import Ide.Types (DynFlagsModifications)
import Ide.Types (GhcOptsModifications)
import qualified Language.LSP.Types.Capabilities as LSP

data IdeOptions = IdeOptions
Expand Down Expand Up @@ -71,7 +71,7 @@ data IdeOptions = IdeOptions
-- Otherwise, return the result of parsing without Opt_Haddock, so
-- that the parsed module contains the result of Opt_KeepRawTokenStream,
-- which might be necessary for hlint.
, optModifyDynFlags :: Config -> DynFlagsModifications
, optModifyDynFlags :: Config -> GhcOptsModifications
-- ^ Will be called right after setting up a new cradle,
-- allowing to customize the Ghc options used
, optShakeOptions :: ShakeOptions
Expand Down
28 changes: 27 additions & 1 deletion ghcide/src/Generics/SYB/GHC.hs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE CPP #-}

-- | Custom SYB traversals explicitly designed for operating over the GHC AST.
module Generics.SYB.GHC
( genericIsSubspan,
mkBindListT,
everywhereM',
smallestM,
largestM
largestM,
#if MIN_VERSION_ghc(9,2,1)
genericIsSubspanL
#endif
) where

import Control.Monad
Expand All @@ -16,6 +20,10 @@ import Data.Monoid (Any (Any))
import Development.IDE.GHC.Compat
import Development.IDE.Graph.Classes
import Generics.SYB
#if MIN_VERSION_ghc(9,2,1)
import GHC (LocatedL)
import GHC.Hs (SrcSpanAnn' (..))
#endif


-- | A generic query intended to be used for calling 'smallestM' and
Expand All @@ -33,6 +41,24 @@ genericIsSubspan ::
genericIsSubspan _ dst = mkQ Nothing $ \case
(L span ast :: Located ast) -> Just (dst `isSubspanOf` span, ast)

#if MIN_VERSION_ghc(9,2,1)
-- | A generic query intended to be used for calling 'smallestM' and
-- 'largestM'. If the current node is a 'Located', returns whether or not the
-- given 'SrcSpan' is a subspan. For all other nodes, returns 'Nothing', which
-- indicates uncertainty. The search strategy in 'smallestM' et al. will
-- continue searching uncertain nodes.
genericIsSubspanL ::
forall ast.
Typeable ast =>
-- | The type of nodes we'd like to consider.
Proxy (LocatedL ast) ->
SrcSpan ->
GenericQ (Maybe (Bool, ast))
genericIsSubspanL _ dst = mkQ Nothing $ \case
(L (SrcSpanAnn _ span) ast :: LocatedL ast) -> Just (dst `isSubspanOf` span, ast)
#endif



-- | Lift a function that replaces a value with several values into a generic
-- function. The result doesn't perform any searching, so should be driven via
Expand Down
57 changes: 37 additions & 20 deletions hls-plugin-api/src/Ide/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ module Ide.Types
, IdeCommand(..)
, IdeMethod(..)
, IdeNotification(..)
, GhcOptsModifications(..)
, IdePlugins(IdePlugins, ipMap)
, DynFlagsModifications(..)
, ConfigDescriptor(..), defaultConfigDescriptor, configForPlugin, pluginEnabledConfig
, CustomConfig(..), mkCustomConfig
, FallbackCodeActionParams(..)
Expand Down Expand Up @@ -109,6 +109,11 @@ import System.FilePath
import System.IO.Unsafe
import Text.Regex.TDFA.Text ()

#if MIN_VERSION_ghc(9,2,0)
import GHC.Plugins (StaticPlugin)
#endif


-- ---------------------------------------------------------------------

data IdePlugins ideState = IdePlugins_
Expand Down Expand Up @@ -137,28 +142,40 @@ lookupPluginId ls cmd = pluginId <$> find go ls
where
go desc = cmd `elem` map commandId (pluginCommands desc)

-- | Hooks for modifying the 'DynFlags' at different times of the compilation
-- process. Plugins can install a 'DynFlagsModifications' via
-- 'pluginModifyDynflags' in their 'PluginDescriptor'.
data DynFlagsModifications =
DynFlagsModifications
{ -- | Invoked immediately at the package level. Changes to the 'DynFlags'
-- made in 'dynFlagsModifyGlobal' are guaranteed to be seen everywhere in
-- the compilation pipeline.
dynFlagsModifyGlobal :: DynFlags -> DynFlags
-- | Invoked just before the parsing step, and reset immediately
-- afterwards. 'dynFlagsModifyParser' allows plugins to enable language
-- extensions only during parsing. for example, to let them enable
-- certain pieces of syntax.
{- | Hooks for modifying the 'DynFlags' at different times of the compilation
process. Plugins can install a 'GhcOptsModifications' via
'pluginModifyDynflags' in their 'PluginDescriptor'.
-}
data GhcOptsModifications = GhcOptsModifications
{ dynFlagsModifyGlobal :: DynFlags -> DynFlags
-- ^ Invoked immediately at the package level. Changes to the 'DynFlags'
-- made in 'dynFlagsModifyGlobal' are guaranteed to be seen everywhere in
-- the compilation pipeline.
, dynFlagsModifyParser :: DynFlags -> DynFlags
-- ^ Invoked just before the parsing step, and reset immediately
-- afterwards. 'dynFlagsModifyParser' allows plugins to enable language
-- extensions only during parsing. for example, to let them enable
-- certain pieces of syntax.
#if MIN_VERSION_ghc(9,2,0)
, staticPlugins :: [StaticPlugin]
#endif
}

instance Semigroup DynFlagsModifications where
DynFlagsModifications g1 p1 <> DynFlagsModifications g2 p2 =
DynFlagsModifications (g2 . g1) (p2 . p1)
#if MIN_VERSION_ghc(9,2,0)
instance Semigroup GhcOptsModifications where
GhcOptsModifications g1 p1 plugins1 <> GhcOptsModifications g2 p2 plugins2 =
GhcOptsModifications (g2 . g1) (p2 . p1) (plugins1 <> plugins2)

instance Monoid DynFlagsModifications where
mempty = DynFlagsModifications id id
instance Monoid GhcOptsModifications where
mempty = GhcOptsModifications id id []
#else
instance Semigroup GhcOptsModifications where
GhcOptsModifications g1 p1 <> GhcOptsModifications g2 p2 =
GhcOptsModifications (g2 . g1) (p2 . p1)

instance Monoid GhcOptsModifications where
mempty = GhcOptsModifications id id
#endif

-- ---------------------------------------------------------------------

Expand All @@ -177,7 +194,7 @@ data PluginDescriptor (ideState :: *) =
, pluginHandlers :: PluginHandlers ideState
, pluginConfigDescriptor :: ConfigDescriptor
, pluginNotificationHandlers :: PluginNotificationHandlers ideState
, pluginModifyDynflags :: DynFlagsModifications
, pluginModifyDynflags :: GhcOptsModifications
, pluginCli :: Maybe (ParserInfo (IdeCommand ideState))
, pluginFileType :: [T.Text]
-- ^ File extension of the files the plugin is responsible for.
Expand Down
Loading