Skip to content

Commit 6a6e38a

Browse files
committed
Introduce config options for the main rules
Surfacing the performance tradeoffs in the core build rules
1 parent 5b350fb commit 6a6e38a

File tree

5 files changed

+44
-19
lines changed

5 files changed

+44
-19
lines changed

Diff for: ghcide/exe/Main.hs

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Main(main) where
88
import Arguments (Arguments (..),
99
getArguments)
1010
import Control.Monad.Extra (unless, whenJust)
11+
import Data.Default (def)
1112
import Data.Version (showVersion)
1213
import Development.GitRev (gitHash)
1314
import Development.IDE (Priority (Debug, Info),
@@ -60,7 +61,7 @@ main = withTelemetryLogger $ \telemetryLogger -> do
6061

6162
,Main.argsRules = do
6263
-- install the main and ghcide-plugin rules
63-
mainRule
64+
mainRule def
6465
-- install the kick action, which triggers a typecheck on every
6566
-- Shake database restart, i.e. on every user edit.
6667
unless argsDisableKick $

Diff for: ghcide/src/Development/IDE/Core/Rules.hs

+37-14
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module Development.IDE.Core.Rules(
2222
defineNoFile,
2323
defineEarlyCutOffNoFile,
2424
mainRule,
25+
RulesConfig(..),
2526
getDependencies,
2627
getParsedModule,
2728
getParsedModuleWithComments,
@@ -56,6 +57,7 @@ module Development.IDE.Core.Rules(
5657
ghcSessionDepsDefinition,
5758
getParsedModuleDefinition,
5859
typeCheckRuleDefinition,
60+
GhcSessionDepsConfig(..),
5961
) where
6062

6163
#if !MIN_VERSION_ghc(8,8,0)
@@ -138,7 +140,7 @@ import qualified Language.LSP.Server as LSP
138140
import Language.LSP.Types (SMethod (SCustomMethod))
139141
import Language.LSP.VFS
140142
import System.Directory (canonicalizePath, makeAbsolute)
141-
import Data.Default (def)
143+
import Data.Default (def, Default)
142144
import Ide.Plugin.Properties (HasProperty,
143145
KeyNameProxy,
144146
Properties,
@@ -640,8 +642,8 @@ currentLinkables = do
640642
where
641643
go (mod, time) = LM time mod []
642644

643-
loadGhcSession :: Rules ()
644-
loadGhcSession = do
645+
loadGhcSession :: GhcSessionDepsConfig -> Rules ()
646+
loadGhcSession ghcSessionDepsConfig = do
645647
-- This function should always be rerun because it tracks changes
646648
-- to the version of the collection of HscEnv's.
647649
defineEarlyCutOffNoFile $ \GhcSessionIO -> do
@@ -679,24 +681,34 @@ loadGhcSession = do
679681

680682
defineNoDiagnostics $ \GhcSessionDeps file -> do
681683
env <- use_ GhcSession file
682-
ghcSessionDepsDefinition False env file
683-
684-
ghcSessionDepsDefinition :: Bool -> HscEnvEq -> NormalizedFilePath -> Action (Maybe HscEnvEq)
685-
ghcSessionDepsDefinition forceLinkable env file = do
684+
ghcSessionDepsDefinition ghcSessionDepsConfig env file
685+
686+
data GhcSessionDepsConfig = GhcSessionDepsConfig
687+
{ checkForImportCycles :: Bool
688+
, forceLinkables :: Bool
689+
}
690+
instance Default GhcSessionDepsConfig where
691+
def = GhcSessionDepsConfig
692+
{ checkForImportCycles = True
693+
, forceLinkables = False
694+
}
695+
696+
ghcSessionDepsDefinition :: GhcSessionDepsConfig -> HscEnvEq -> NormalizedFilePath -> Action (Maybe HscEnvEq)
697+
ghcSessionDepsDefinition GhcSessionDepsConfig{..} env file = do
686698
let hsc = hscEnv env
687699

688700
mbdeps <- mapM(fmap artifactFilePath . snd) <$> use_ GetLocatedImports file
689701
case mbdeps of
690702
Nothing -> return Nothing
691703
Just deps -> do
692-
_ <- uses_ ReportImportCycles deps
704+
when checkForImportCycles $ void $ uses_ ReportImportCycles deps
693705
ms:mss <- map msrModSummary <$> uses_ GetModSummaryWithoutTimestamps (file:deps)
694706

695707
depSessions <- map hscEnv <$> uses_ GhcSessionDeps deps
696708
let uses_th_qq =
697709
xopt LangExt.TemplateHaskell dflags || xopt LangExt.QuasiQuotes dflags
698710
dflags = ms_hspp_opts ms
699-
ifaces <- if uses_th_qq || forceLinkable
711+
ifaces <- if uses_th_qq || forceLinkables
700712
then uses_ GetModIface deps
701713
else uses_ GetModIfaceWithoutLinkable deps
702714

@@ -1043,9 +1055,18 @@ writeHiFileAction hsc hiFile = do
10431055
resetInterfaceStore extras $ toNormalizedFilePath' targetPath
10441056
writeHiFile hsc hiFile
10451057

1058+
data RulesConfig = RulesConfig
1059+
{ -- | Disable import cycle checking for improved performance in large codebases
1060+
checkForImportCycles :: Bool
1061+
-- | Disable TH for improved performance in large codebases
1062+
, enableTemplateHaskell :: Bool
1063+
}
1064+
1065+
instance Default RulesConfig where def = RulesConfig True True
1066+
10461067
-- | A rule that wires per-file rules together
1047-
mainRule :: Rules ()
1048-
mainRule = do
1068+
mainRule :: RulesConfig -> Rules ()
1069+
mainRule RulesConfig{..} = do
10491070
linkables <- liftIO $ newVar emptyModuleEnv
10501071
addIdeGlobal $ CompiledLinkables linkables
10511072
getParsedModuleRule
@@ -1055,7 +1076,7 @@ mainRule = do
10551076
reportImportCyclesRule
10561077
typeCheckRule
10571078
getDocMapRule
1058-
loadGhcSession
1079+
loadGhcSession def{checkForImportCycles}
10591080
getModIfaceFromDiskRule
10601081
getModIfaceFromDiskAndIndexRule
10611082
getModIfaceRule
@@ -1073,8 +1094,10 @@ mainRule = do
10731094
-- * ObjectLinkable -> BCOLinkable : the prev linkable can be reused, signal "no change"
10741095
-- * Object/BCO -> NoLinkable : the prev linkable can be ignored, signal "no change"
10751096
-- * otherwise : the prev linkable cannot be reused, signal "value has changed"
1076-
defineEarlyCutoff $ RuleWithCustomNewnessCheck (<=) $ \NeedsCompilation file ->
1077-
needsCompilationRule file
1097+
if enableTemplateHaskell
1098+
then defineEarlyCutoff $ RuleWithCustomNewnessCheck (<=) $ \NeedsCompilation file ->
1099+
needsCompilationRule file
1100+
else defineNoDiagnostics $ \NeedsCompilation _ -> return $ Just Nothing
10781101
generateCoreRule
10791102
getImportMapRule
10801103
getAnnotatedParsedSourceRule

Diff for: ghcide/src/Development/IDE/Main.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ defaultArguments priority = Arguments
187187
{ argsOTMemoryProfiling = False
188188
, argCommand = LSP
189189
, argsLogger = stderrLogger priority
190-
, argsRules = mainRule >> action kick
190+
, argsRules = mainRule def >> action kick
191191
, argsGhcidePlugin = mempty
192192
, argsHlsPlugins = pluginDescToIdePlugins Ghcide.descriptors
193193
, argsSessionLoadingOptions = def

Diff for: ghcide/test/exe/Main.hs

-1
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,6 @@ cancellationTestGroup name edits dependsOutcome sessionDepsOutcome parseOutcome
723723
, cancellationTemplate edits $ Just ("GetModSummaryWithoutTimestamps", True)
724724
-- getLocatedImports never fails
725725
, cancellationTemplate edits $ Just ("GetLocatedImports", True)
726-
, cancellationTemplate edits $ Just ("GetDependencies", dependsOutcome)
727726
, cancellationTemplate edits $ Just ("GhcSessionDeps", sessionDepsOutcome)
728727
, cancellationTemplate edits $ Just ("GetParsedModule", parseOutcome)
729728
, cancellationTemplate edits $ Just ("TypeCheck", tcOutcome)

Diff for: plugins/hls-eval-plugin/src/Ide/Plugin/Eval/CodeLens.hs

+4-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ import Development.IDE (GetModSummary (..),
5454
toNormalizedFilePath',
5555
uriToFilePath', useNoFile_,
5656
useWithStale_, use_)
57-
import Development.IDE.Core.Rules (ghcSessionDepsDefinition)
57+
import Development.IDE.Core.Rules (GhcSessionDepsConfig (..),
58+
ghcSessionDepsDefinition)
5859
import Development.IDE.GHC.Compat hiding (typeKind, unitState)
5960
import qualified Development.IDE.GHC.Compat as Compat
6061
import qualified Development.IDE.GHC.Compat as SrcLoc
@@ -536,7 +537,8 @@ runGetSession st nfp = liftIO $ runAction "eval" st $ do
536537
let fp = fromNormalizedFilePath nfp
537538
((_, res),_) <- liftIO $ loadSessionFun fp
538539
let env = fromMaybe (error $ "Unknown file: " <> fp) res
539-
res <- fmap hscEnv <$> ghcSessionDepsDefinition False env nfp
540+
ghcSessionDepsConfig = dep{forceLinkables = True, checkForImportCycles = False}
541+
res <- fmap hscEnv <$> ghcSessionDepsDefinition ghcSessionDepsConfig env nfp
540542
return $ fromMaybe (error $ "Unable to load file: " <> fp) res
541543

542544
needsQuickCheck :: [(Section, Test)] -> Bool

0 commit comments

Comments
 (0)