diff --git a/.github/actions/setup-build/action.yml b/.github/actions/setup-build/action.yml index 975fa90617..9237cadfbe 100644 --- a/.github/actions/setup-build/action.yml +++ b/.github/actions/setup-build/action.yml @@ -31,7 +31,7 @@ runs: sudo chown -R $USER /usr/local/.ghcup shell: bash - - uses: haskell-actions/setup@v2.7.9 + - uses: haskell-actions/setup@v2.7.10 id: HaskEnvSetup with: ghc-version : ${{ inputs.ghc }} diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index cb345c806e..0ac0ca68d0 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -127,7 +127,7 @@ jobs: example: ['cabal', 'lsp-types'] steps: - - uses: haskell-actions/setup@v2.7.9 + - uses: haskell-actions/setup@v2.7.10 with: ghc-version : ${{ matrix.ghc }} cabal-version: ${{ matrix.cabal }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fc3f98bcca..60c2cd8fc4 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -30,7 +30,7 @@ jobs: strategy: fail-fast: false matrix: - ghc: ["9.10.1", "9.8.2", "9.6.6", "9.4.8"] + ghc: ["9.12.2", "9.10.1", "9.8.2", "9.6.6", "9.4.8"] platform: [ { image: "debian:9" , installCmd: "sed -i s/deb.debian.org/archive.debian.org/g /etc/apt/sources.list && sed -i 's|security.debian.org|archive.debian.org/|g' /etc/apt/sources.list && sed -i /-updates/d /etc/apt/sources.list && apt-get update && apt-get install -y" , toolRequirements: "libnuma-dev zlib1g-dev libgmp-dev libgmp10 libssl-dev liblzma-dev libbz2-dev git wget lsb-release software-properties-common gnupg2 apt-transport-https gcc autoconf automake build-essential curl ghc gzip libffi-dev libncurses-dev libncurses5 libtinfo5 patchelf" @@ -213,7 +213,7 @@ jobs: strategy: fail-fast: true matrix: - ghc: ["9.10.1", "9.8.2", "9.6.6", "9.4.8"] + ghc: ["9.12.2", "9.10.1", "9.8.2", "9.6.6", "9.4.8"] steps: - uses: docker://arm64v8/ubuntu:focal name: Cleanup (aarch64 linux) @@ -273,7 +273,7 @@ jobs: strategy: fail-fast: false matrix: - ghc: ["9.10.1", "9.8.2", "9.6.6", "9.4.8"] + ghc: ["9.12.2", "9.10.1", "9.8.2", "9.6.6", "9.4.8"] steps: - name: Checkout code uses: actions/checkout@v3 @@ -318,7 +318,7 @@ jobs: strategy: fail-fast: false matrix: - ghc: ["9.10.1", "9.8.2", "9.6.6", "9.4.8"] + ghc: ["9.12.2", "9.10.1", "9.8.2", "9.6.6", "9.4.8"] steps: - name: Checkout code uses: actions/checkout@v3 @@ -363,7 +363,7 @@ jobs: strategy: fail-fast: false matrix: - ghc: ["9.10.1", "9.8.2", "9.6.6", "9.4.8"] + ghc: ["9.12.2", "9.10.1", "9.8.2", "9.6.6", "9.4.8"] steps: - name: install windows deps shell: pwsh diff --git a/.github/workflows/supported-ghc-versions.json b/.github/workflows/supported-ghc-versions.json index b530e284e0..2816bb4e77 100644 --- a/.github/workflows/supported-ghc-versions.json +++ b/.github/workflows/supported-ghc-versions.json @@ -1 +1 @@ -["9.10", "9.8", "9.6", "9.4"] +["9.12.2", "9.10", "9.8", "9.6", "9.4"] diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 544a9c6e78..714f7bc51b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -134,117 +134,117 @@ jobs: HLS_WRAPPER_TEST_EXE: hls-wrapper run: cabal test wrapper-test - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-refactor-plugin run: cabal test hls-refactor-plugin-tests || cabal test hls-refactor-plugin-tests # TODO enable when it supports 9.10 - - if: matrix.test && matrix.ghc != '9.10' + - if: matrix.test && matrix.ghc != '9.10' && matrix.ghc != '9.12.2' name: Test hls-floskell-plugin run: cabal test hls-floskell-plugin-tests || cabal test hls-floskell-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-class-plugin run: cabal test hls-class-plugin-tests || cabal test hls-class-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-pragmas-plugin run: cabal test hls-pragmas-plugin-tests || cabal test hls-pragmas-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-eval-plugin run: cabal test hls-eval-plugin-tests || cabal test hls-eval-plugin-tests # TODO enable when it supports 9.10 - - if: matrix.test && matrix.ghc != '9.10' + - if: matrix.test && matrix.ghc != '9.10' && matrix.ghc != '9.12.2' name: Test hls-splice-plugin run: cabal test hls-splice-plugin-tests || cabal test hls-splice-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-stan-plugin run: cabal test hls-stan-plugin-tests || cabal test hls-stan-plugin-tests # TODO enable when it supports 9.10 - - if: matrix.test && matrix.ghc != '9.10' + - if: matrix.test && matrix.ghc != '9.10' && matrix.ghc != '9.12.2' name: Test hls-stylish-haskell-plugin run: cabal test hls-stylish-haskell-plugin-tests || cabal test hls-stylish-haskell-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-ormolu-plugin run: cabal test hls-ormolu-plugin-tests || cabal test hls-ormolu-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-fourmolu-plugin run: cabal test hls-fourmolu-plugin-tests || cabal test hls-fourmolu-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-explicit-imports-plugin test suite run: cabal test hls-explicit-imports-plugin-tests || cabal test hls-explicit-imports-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-call-hierarchy-plugin test suite run: cabal test hls-call-hierarchy-plugin-tests || cabal test hls-call-hierarchy-plugin-tests - - if: matrix.test && matrix.os != 'windows-latest' + - if: matrix.test && matrix.os != 'windows-latest' && matrix.ghc != '9.12.2' name: Test hls-rename-plugin test suite run: cabal test hls-rename-plugin-tests || cabal test hls-rename-plugin-tests # TODO enable when it supports 9.10 - - if: matrix.test && matrix.ghc != '9.10' + - if: matrix.test && matrix.ghc != '9.10' && matrix.ghc != '9.12.2' name: Test hls-hlint-plugin test suite run: cabal test hls-hlint-plugin-tests || cabal test hls-hlint-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-module-name-plugin test suite run: cabal test hls-module-name-plugin-tests || cabal test hls-module-name-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-alternate-number-format-plugin test suite run: cabal test hls-alternate-number-format-plugin-tests || cabal test hls-alternate-number-format-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-qualify-imported-names-plugin test suite run: cabal test hls-qualify-imported-names-plugin-tests || cabal test hls-qualify-imported-names-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-code-range-plugin test suite run: cabal test hls-code-range-plugin-tests || cabal test hls-code-range-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-change-type-signature test suite run: cabal test hls-change-type-signature-plugin-tests || cabal test hls-change-type-signature-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-gadt-plugin test suit run: cabal test hls-gadt-plugin-tests || cabal test hls-gadt-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-explicit-fixity-plugin test suite run: cabal test hls-explicit-fixity-plugin-tests || cabal test hls-explicit-fixity-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-explicit-record-fields-plugin test suite run: cabal test hls-explicit-record-fields-plugin-tests || cabal test hls-explicit-record-fields-plugin-tests # versions need to be limited since the tests depend on cabal-fmt which only builds with ghc <9.10 - - if: matrix.test && matrix.ghc != '9.10' + - if: matrix.test && matrix.ghc != '9.10' && matrix.ghc != '9.12.2' name: Test hls-cabal-fmt-plugin test suite run: cabal test hls-cabal-fmt-plugin-tests --flag=isolateCabalfmtTests || cabal test hls-cabal-fmt-plugin-tests --flag=isolateCabalfmtTests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-cabal-gild-plugin test suite run: cabal test hls-cabal-gild-plugin-tests --flag=isolateCabalGildTests || cabal test hls-cabal-gild-plugin-tests --flag=isolateCabalGildTests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-cabal-plugin test suite run: cabal test hls-cabal-plugin-tests || cabal test hls-cabal-plugin-tests # TODO enable when it supports 9.10 - - if: matrix.test && matrix.ghc != '9.10' + - if: matrix.test && matrix.ghc != '9.10' && matrix.ghc != '9.12.2' name: Test hls-retrie-plugin test suite run: cabal test hls-retrie-plugin-tests || cabal test hls-retrie-plugin-tests - - if: matrix.test + - if: matrix.test && matrix.ghc != '9.12.2' name: Test hls-overloaded-record-dot-plugin test suite run: cabal test hls-overloaded-record-dot-plugin-tests || cabal test hls-overloaded-record-dot-plugin-tests diff --git a/cabal.project b/cabal.project index d63c47ff99..36f3c01b8f 100644 --- a/cabal.project +++ b/cabal.project @@ -7,8 +7,7 @@ packages: ./hls-plugin-api ./hls-test-utils - -index-state: 2024-12-02T00:00:00Z +index-state: 2025-03-17T11:03:01Z tests: True test-show-details: direct @@ -59,3 +58,22 @@ if impl(ghc >= 9.8.4) && impl(ghc < 9.8.5) ghc-lib-parser:filepath constraints: ghc-lib-parser==9.8.4.20241130 + +-- keep it here for easy debugging when trying to support new GHC versions +if impl(ghc >= 9.13.0) + allow-newer: + base + , ghc + +source-repository-package + type: git + location: https://github.com/soulomoon/HieDb.git + tag: 9111fd0f2e4d2d5186c4de7afb7ea9f3a2941105 +-- todo remove this once the PR is released +-- https://github.com/wz1000/HieDb/pull/80 + + +source-repository-package + type: git + location: https://github.com/maoe/ghc-trace-events.git + tag: f18107dec920564f7cbcde52e17d0b4b41add5a3 diff --git a/ghcide/cabal.project b/ghcide/cabal.project new file mode 100644 index 0000000000..06b0de6b87 --- /dev/null +++ b/ghcide/cabal.project @@ -0,0 +1,7 @@ +packages: + ./ + +if impl(ghc >= 9.11.0) + allow-newer: + base + , ghc diff --git a/ghcide/ghcide.cabal b/ghcide/ghcide.cabal index af9a191406..6e2d8ee5c8 100644 --- a/ghcide/ghcide.cabal +++ b/ghcide/ghcide.cabal @@ -92,6 +92,7 @@ library , mtl , opentelemetry >=0.6.1 , optparse-applicative + , os-string , parallel , prettyprinter >=1.7 , prettyprinter-ansi-terminal diff --git a/ghcide/session-loader/Development/IDE/Session.hs b/ghcide/session-loader/Development/IDE/Session.hs index a1768be564..4245b98cd9 100644 --- a/ghcide/session-loader/Development/IDE/Session.hs +++ b/ghcide/session-loader/Development/IDE/Session.hs @@ -124,6 +124,10 @@ import GHC.Types.Error (errMsgDiagnostic, singleMessage) import GHC.Unit.State +#if MIN_VERSION_ghc(9,13,0) +import GHC.Driver.Make (checkHomeUnitsClosed) +#endif + data Log = LogSettingInitialDynFlags | LogGetInitialGhcLibDirDefaultCradleFail !CradleError !FilePath !(Maybe FilePath) !(Cradle Void) @@ -782,6 +786,11 @@ toFlagsMap TargetDetails{..} = setNameCache :: NameCache -> HscEnv -> HscEnv setNameCache nc hsc = hsc { hsc_NC = nc } +#if MIN_VERSION_ghc(9,13,0) +-- Moved back to implementation in GHC. +checkHomeUnitsClosed' :: UnitEnv -> OS.Set UnitId -> [DriverMessages] +checkHomeUnitsClosed' ue _ = checkHomeUnitsClosed ue +#else -- This function checks the important property that if both p and q are home units -- then any dependency of p, which transitively depends on q is also a home unit. -- GHC had an implementation of this function, but it was horribly inefficient @@ -838,6 +847,7 @@ checkHomeUnitsClosed' ue home_id_set Just depends -> let todo'' = (depends OS.\\ done) `OS.union` todo' in DigraphNode uid uid (OS.toList depends) : go (OS.insert uid done) todo'' +#endif -- | Create a mapping from FilePaths to HscEnvEqs -- This combines all the components we know about into diff --git a/ghcide/src/Development/IDE/Core/Compile.hs b/ghcide/src/Development/IDE/Core/Compile.hs index 47872b9255..be5d7cdafd 100644 --- a/ghcide/src/Development/IDE/Core/Compile.hs +++ b/ghcide/src/Development/IDE/Core/Compile.hs @@ -62,11 +62,17 @@ import qualified Data.HashMap.Strict as HashMap import Data.IntMap (IntMap) import Data.IORef import Data.List.Extra +#if MIN_VERSION_ghc(9,11,0) +import qualified Data.List.NonEmpty as NE +#endif import qualified Data.Map.Strict as Map import Data.Maybe import Data.Proxy (Proxy (Proxy)) import qualified Data.Text as T import Data.Time (UTCTime (..)) +#if MIN_VERSION_ghc(9,11,0) +import Data.Time (getCurrentTime) +#endif import Data.Tuple.Extra (dupe) import Debug.Trace import Development.IDE.Core.FileStore (resetInterfaceStore) @@ -132,6 +138,20 @@ import Development.IDE.Core.FileStore (shareFilePath) #endif import Development.IDE.GHC.Compat.Driver (hscTypecheckRenameWithDiagnostics) +#if MIN_VERSION_ghc(9,11,0) +import GHC.Unit.Module.ModIface +import GHC.Unit.Finder (initFinderCache) +#endif + +#if MIN_VERSION_ghc(9,13,0) +import GHC.Unit.Home.Graph as HUG +import GHC.Unit.Home.PackageTable +import GHC.Driver.Env (hscInsertHPT) +#endif + +import Development.IDE.Import.DependencyInformation +import GHC.Driver.Env ( hsc_all_home_unit_ids ) +import Development.IDE.Import.FindImports --Simple constants to make sure the source is consistently named sourceTypecheck :: T.Text @@ -168,9 +188,10 @@ computePackageDeps env pkg = do ] Just pkgInfo -> return $ Right $ unitDepends pkgInfo -newtype TypecheckHelpers +data TypecheckHelpers = TypecheckHelpers { getLinkables :: [NormalizedFilePath] -> IO [LinkableResult] -- ^ hls-graph action to get linkables for files + , getModuleGraph :: IO DependencyInformation } typecheckModule :: IdeDefer @@ -207,6 +228,15 @@ typecheckModule (IdeDefer defer) hsc tc_helpers pm = do where demoteIfDefer = if defer then demoteTypeErrorsToWarnings else id +lookupCache :: HscEnv -> InstalledModule -> IO (Maybe InstalledFindResult) +lookupCache hsc_env installedMod = do +#if MIN_VERSION_ghc(9,11,0) + lookupFinderCache (hsc_FC hsc_env) (GWIB installedMod NotBoot) +#else + ; moduleLocs <- readIORef (fcModuleCache $ hsc_FC hsc_env) + ; return $ lookupInstalledModuleEnv moduleLocs installedMod +#endif + -- | Install hooks to capture the splices as well as the runtime module dependencies captureSplicesAndDeps :: TypecheckHelpers -> HscEnv -> (HscEnv -> IO a) -> IO (a, Splices, ModuleEnv BS.ByteString) captureSplicesAndDeps TypecheckHelpers{..} env k = do @@ -270,7 +300,11 @@ captureSplicesAndDeps TypecheckHelpers{..} env k = do ; bcos <- byteCodeGen hsc_env (icInteractiveModule ictxt) stg_expr - [] Nothing + [] + Nothing +#if MIN_VERSION_ghc(9,11,0) + [] +#endif -- Exclude wired-in names because we may not have read -- their interface files, so getLinkDeps will fail @@ -293,21 +327,40 @@ captureSplicesAndDeps TypecheckHelpers{..} env k = do -- If we don't support multiple home units, ModuleNames are sufficient because all the units will be the same mods_transitive_list = mapMaybe nodeKeyToInstalledModule $ Set.toList mods_transitive - +#if MIN_VERSION_ghc(9,11,0) + ; moduleLocs <- getModuleGraph +#else ; moduleLocs <- readIORef (fcModuleCache $ hsc_FC hsc_env) - ; lbs <- getLinkables [toNormalizedFilePath' file +#endif + ; lbs <- getLinkables [file | installedMod <- mods_transitive_list +#if MIN_VERSION_ghc(9,11,0) + , let file = fromJust $ lookupModuleFile (installedMod { moduleUnit = RealUnit (Definite $ moduleUnit installedMod) }) moduleLocs +#else , let ifr = fromJust $ lookupInstalledModuleEnv moduleLocs installedMod - file = case ifr of + file = toNormalizedFilePath' $ case ifr of InstalledFound loc _ -> fromJust $ ml_hs_file loc _ -> panic "hscCompileCoreExprHook: module not found" +#endif ] +#if MIN_VERSION_ghc(9,13,0) + ; loadModulesHome (map linkableHomeMod lbs) hsc_env +#else ; let hsc_env' = loadModulesHome (map linkableHomeMod lbs) hsc_env +#endif + {- load it -} +#if MIN_VERSION_ghc(9,11,0) + ; bco_time <- getCurrentTime + ; (fv_hvs, lbss, pkgs) <- loadDecls (hscInterp hsc_env') hsc_env' srcspan $ + Linkable bco_time (icInteractiveModule ictxt) $ NE.singleton $ BCOs bcos + ; let hval = ((expectJust "hscCompileCoreExpr'" $ lookup (idName binding_id) fv_hvs), lbss, pkgs) +#else {- load it -} ; (fv_hvs, lbss, pkgs) <- loadDecls (hscInterp hsc_env') hsc_env' srcspan bcos - ; let hval = (expectJust "hscCompileCoreExpr'" $ lookup (idName binding_id) fv_hvs, lbss, pkgs) + ; let hval = ((expectJust "hscCompileCoreExpr'" $ lookup (idName binding_id) fv_hvs), lbss, pkgs) +#endif ; modifyIORef' var (flip extendModuleEnvList [(mi_module $ hm_iface hm, linkableHash lb) | lb <- lbs, let hm = linkableHomeMod lb]) ; return hval } @@ -325,10 +378,19 @@ captureSplicesAndDeps TypecheckHelpers{..} env k = do -- Compute the transitive set of linkables required getTransitiveMods hsc_env needed_mods +#if MIN_VERSION_ghc(9,13,0) + = Set.unions (Set.fromList (map moduleToNodeKey mods) : [ Set.fromList $ map mkNodeKey dep + | m <- mods + , Just dep <- + [mgReachable (hsc_mod_graph hsc_env) (moduleToNodeKey m)] + ]) + where mods = nonDetEltsUniqSet needed_mods -- OK because we put them into a set immediately after +#else = Set.unions (Set.fromList (map moduleToNodeKey mods) : [ dep | m <- mods , Just dep <- [Map.lookup (moduleToNodeKey m) (mgTransDeps (hsc_mod_graph hsc_env))] ]) where mods = nonDetEltsUniqSet needed_mods -- OK because we put them into a set immediately after +#endif -- | Add a Hook to the DynFlags which captures and returns the -- typechecked splices before they are run. This information @@ -430,7 +492,14 @@ mkHiFileResultNoCompile session tcm = do details <- makeSimpleDetails hsc_env_tmp tcGblEnv sf <- finalSafeMode (ms_hspp_opts ms) tcGblEnv iface' <- mkIfaceTc hsc_env_tmp sf details ms Nothing tcGblEnv - let iface = iface' { mi_globals = Nothing, mi_usages = filterUsages (mi_usages iface') } -- See Note [Clearing mi_globals after generating an iface] + -- See Note [Clearing mi_globals after generating an iface] + let iface = iface' +#if MIN_VERSION_ghc(9,11,0) + & set_mi_top_env Nothing + & set_mi_usages (filterUsages (mi_usages iface')) +#else + { mi_globals = Nothing, mi_usages = filterUsages (mi_usages iface') } +#endif pure $! mkHiFileResult ms iface details (tmrRuntimeModules tcm) Nothing mkHiFileResultCompile @@ -450,19 +519,34 @@ mkHiFileResultCompile se session' tcm simplified_guts = catchErrs $ do (guts, details) <- tidyProgram tidy_opts simplified_guts pure (details, guts) + -- (tcg_import_decls tc_result) + let !partial_iface = force $ mkPartialIface session #if MIN_VERSION_ghc(9,5,0) (cg_binds guts) #endif details ms +#if MIN_VERSION_ghc(9,11,0) + (tcg_import_decls $ tmrTypechecked tcm) +#endif simplified_guts final_iface' <- mkFullIface session partial_iface Nothing #if MIN_VERSION_ghc(9,4,2) Nothing #endif - let final_iface = final_iface' {mi_globals = Nothing, mi_usages = filterUsages (mi_usages final_iface')} -- See Note [Clearing mi_globals after generating an iface] +#if MIN_VERSION_ghc(9,11,0) + NoStubs [] +#endif + -- See Note [Clearing mi_globals after generating an iface] + let final_iface = final_iface' +#if MIN_VERSION_ghc(9,11,0) + & set_mi_top_env Nothing + & set_mi_usages (filterUsages (mi_usages final_iface')) +#else + {mi_globals = Nothing, mi_usages = filterUsages (mi_usages final_iface')} +#endif -- Write the core file now core_file <- do @@ -470,7 +554,7 @@ mkHiFileResultCompile se session' tcm simplified_guts = catchErrs $ do core_file = codeGutsToCoreFile iface_hash guts iface_hash = getModuleHash final_iface core_hash1 <- atomicFileWrite se core_fp $ \fp -> - writeBinCoreFile fp core_file + writeBinCoreFile (hsc_dflags session) fp core_file -- We want to drop references to guts and read in a serialized, compact version -- of the core file from disk (as it is deserialised lazily) -- This is because we don't want to keep the guts in memory for every file in @@ -626,10 +710,14 @@ generateObjectCode session summary guts = do case obj of Nothing -> throwGhcExceptionIO $ Panic "compileFile didn't generate object code" Just x -> pure x +#if MIN_VERSION_ghc(9,11,0) + let unlinked = DotO dot_o_fp ModuleObject +#else let unlinked = DotO dot_o_fp +#endif -- Need time to be the modification time for recompilation checking t <- liftIO $ getModificationTime dot_o_fp - let linkable = LM t mod [unlinked] + let linkable = LM t mod (pure unlinked) pure (map snd warnings, linkable) @@ -639,15 +727,25 @@ generateByteCode :: CoreFileTime -> HscEnv -> ModSummary -> CgGuts -> IO (IdeRes generateByteCode (CoreFileTime time) hscEnv summary guts = do fmap (either (, Nothing) (second Just)) $ catchSrcErrors (hsc_dflags hscEnv) "bytecode" $ do +#if MIN_VERSION_ghc(9,11,0) + (warnings, (_, bytecode)) <- +#else (warnings, (_, bytecode, sptEntries)) <- +#endif withWarnings "bytecode" $ \_tweak -> do - let session = _tweak (hscSetFlags (ms_hspp_opts summary) hscEnv) - -- TODO: maybe settings ms_hspp_opts is unnecessary? - summary' = summary { ms_hspp_opts = hsc_dflags session } - hscInteractive session (mkCgInteractiveGuts guts) - (ms_location summary') + let session = _tweak (hscSetFlags (ms_hspp_opts summary) hscEnv) + -- TODO: maybe settings ms_hspp_opts is unnecessary? + summary' = summary {ms_hspp_opts = hsc_dflags session} + hscInteractive + session + (mkCgInteractiveGuts guts) + (ms_location summary') +#if MIN_VERSION_ghc(9,11,0) + let unlinked = BCOs bytecode +#else let unlinked = BCOs bytecode sptEntries - let linkable = LM time (ms_mod summary) [unlinked] +#endif + let linkable = LM time (ms_mod summary) $ pure unlinked pure (map snd warnings, linkable) demoteTypeErrorsToWarnings :: ParsedModule -> ParsedModule @@ -748,21 +846,37 @@ atomicFileWrite se targetPath write = do (write tempFilePath >>= \x -> renameFile tempFilePath targetPath >> atomically (resetInterfaceStore se (toNormalizedFilePath' targetPath)) >> pure x) `onException` cleanUp +#if !MIN_VERSION_ghc(9,11,0) generateHieAsts :: HscEnv -> TcModuleResult -> IO ([FileDiagnostic], Maybe (HieASTs Type)) +#else +generateHieAsts :: HscEnv -> TcModuleResult -> IO ([FileDiagnostic], Maybe ((HieASTs Type), NameEntityInfo)) +#endif generateHieAsts hscEnv tcm = handleGenerationErrors' dflags "extended interface generation" $ runHsc hscEnv $ do -- These varBinds use unitDataConId but it could be anything as the id name is not used -- during the hie file generation process. It's a workaround for the fact that the hie modules -- don't export an interface which allows for additional information to be added to hie files. - let fake_splice_binds = Util.listToBag (map (mkVarBind unitDataConId) (spliceExpressions $ tmrTopLevelSplices tcm)) + let fake_splice_binds = +#if !MIN_VERSION_ghc(9,11,0) + Util.listToBag $ +#endif + map (mkVarBind unitDataConId) (spliceExpressions $ tmrTopLevelSplices tcm) real_binds = tcg_binds $ tmrTypechecked tcm + all_binds = +#if MIN_VERSION_ghc(9,11,0) + fake_splice_binds ++ real_binds +#else + fake_splice_binds `Util.unionBags` real_binds +#endif ts = tmrTypechecked tcm :: TcGblEnv top_ev_binds = tcg_ev_binds ts :: Util.Bag EvBind insts = tcg_insts ts :: [ClsInst] tcs = tcg_tcs ts :: [TyCon] - - pure $ Just $ - GHC.enrichHie (fake_splice_binds `Util.unionBags` real_binds) (tmrRenamed tcm) top_ev_binds insts tcs + hie_asts = GHC.enrichHie all_binds (tmrRenamed tcm) top_ev_binds insts tcs +#if MIN_VERSION_ghc(9,11,0) + $ tcg_type_env ts +#endif + pure $ Just hie_asts where dflags = hsc_dflags hscEnv @@ -850,7 +964,13 @@ indexHieFile se mod_summary srcPath !hash hf = do toJSON $ fromNormalizedFilePath srcPath whenJust mdone $ \_ -> progressUpdate indexProgressReporting ProgressCompleted -writeAndIndexHieFile :: HscEnv -> ShakeExtras -> ModSummary -> NormalizedFilePath -> [GHC.AvailInfo] -> HieASTs Type -> BS.ByteString -> IO [FileDiagnostic] +writeAndIndexHieFile :: HscEnv -> ShakeExtras -> ModSummary -> NormalizedFilePath -> [GHC.AvailInfo] +#if MIN_VERSION_ghc(9,11,0) + -> (HieASTs Type, NameEntityInfo) +#else + -> HieASTs Type +#endif + -> BS.ByteString -> IO [FileDiagnostic] writeAndIndexHieFile hscEnv se mod_summary srcPath exports ast source = handleGenerationErrors dflags "extended interface write/compression" $ do hf <- runHsc hscEnv $ @@ -904,8 +1024,95 @@ handleGenerationErrors' dflags source action = -- Add the current ModSummary to the graph, along with the -- HomeModInfo's of all direct dependencies (by induction hypothesis all -- transitive dependencies will be contained in envs) -mergeEnvs :: HscEnv -> ModuleGraph -> ModSummary -> [HomeModInfo] -> [HscEnv] -> IO HscEnv -mergeEnvs env mg ms extraMods envs = do +mergeEnvs :: HscEnv + -> ModuleGraph + -> DependencyInformation + -> ModSummary + -> [HomeModInfo] + -> [HscEnv] + -> IO HscEnv +mergeEnvs env mg dep_info ms extraMods envs = do +#if MIN_VERSION_ghc(9,13,0) + newHug <- sequence $ foldl' mergeHUG (pure <$> hsc_HUG env) (map (fmap pure . hsc_HUG) envs) + let hsc_env' = (hscUpdateHUG (const newHug) env){ + hsc_mod_graph = mg, + hsc_FC = (hsc_FC env) + { addToFinderCache = \im val -> + if moduleUnit im `elem` hsc_all_home_unit_ids env + then pure () + else addToFinderCache (hsc_FC env) im val + , lookupFinderCache = \im -> + if moduleUnit im `elem` hsc_all_home_unit_ids env + then case lookupModuleFile (im { moduleUnit = RealUnit (Definite $ moduleUnit im) }) dep_info of + Nothing -> pure Nothing + Just fs -> let ml = fromJust $ do + id <- lookupPathToId (depPathIdMap dep_info) fs + artifactModLocation (idToModLocation (depPathIdMap dep_info) id) + in pure $ Just $ InstalledFound ml + else lookupFinderCache (hsc_FC env) im + {- + , lookupFileCache = \fp -> + case lookup fp dependentHashes of + Just res -> return res + Nothing -> lookupFileCache (hsc_FC env) fp + -} + } + } + loadModulesHome extraMods hsc_env' + return hsc_env' + + where + mergeHUG :: UnitEnvGraph (IO HomeUnitEnv) -> UnitEnvGraph (IO HomeUnitEnv) -> UnitEnvGraph (IO HomeUnitEnv) + mergeHUG (UnitEnvGraph a) (UnitEnvGraph b) = UnitEnvGraph $ Map.unionWith mergeHUE a b + mergeHUE a b = do + a_v <- a + hpt_b <- readIORef . hptInternalTableRef . homeUnitEnv_hpt =<< b + hpt_a <- readIORef . hptInternalTableRef . homeUnitEnv_hpt $ a_v + result <- hptInternalTableFromRef =<< (newIORef $! mergeUDFM hpt_a hpt_b) + return $! a_v { homeUnitEnv_hpt = result } + mergeUDFM = plusUDFM_C combineModules + combineModules a b + | HsSrcFile <- mi_hsc_src (hm_iface a) = a + | otherwise = b + +#elif MIN_VERSION_ghc(9,11,0) + return $! loadModulesHome extraMods $ + let newHug = foldl' mergeHUG (hsc_HUG env) (map hsc_HUG envs) in + (hscUpdateHUG (const newHug) env){ + hsc_mod_graph = mg, + hsc_FC = (hsc_FC env) + { addToFinderCache = \gwib@(GWIB im _) val -> + if moduleUnit im `elem` hsc_all_home_unit_ids env + then pure () + else addToFinderCache (hsc_FC env) gwib val + , lookupFinderCache = \gwib@(GWIB im _) -> + if moduleUnit im `elem` hsc_all_home_unit_ids env + then case lookupModuleFile (im { moduleUnit = RealUnit (Definite $ moduleUnit im) }) dep_info of + Nothing -> pure Nothing + Just fs -> let ml = fromJust $ do + id <- lookupPathToId (depPathIdMap dep_info) fs + artifactModLocation (idToModLocation (depPathIdMap dep_info) id) + in pure $ Just $ InstalledFound ml im + else lookupFinderCache (hsc_FC env) gwib + {- + , lookupFileCache = \fp -> + case lookup fp dependentHashes of + Just res -> return res + Nothing -> lookupFileCache (hsc_FC env) fp + -} + } + } + + where + mergeHUG (UnitEnvGraph a) (UnitEnvGraph b) = UnitEnvGraph $ Map.unionWith mergeHUE a b + mergeHUE a b = a { homeUnitEnv_hpt = mergeUDFM (homeUnitEnv_hpt a) (homeUnitEnv_hpt b) } + mergeUDFM = plusUDFM_C combineModules + + combineModules a b + | HsSrcFile <- mi_hsc_src (hm_iface a) = a + | otherwise = b + +#else let im = Compat.installedModule (toUnitId $ moduleUnit $ ms_mod ms) (moduleName (ms_mod ms)) ifr = InstalledFound (ms_location ms) im curFinderCache = Compat.extendInstalledModuleEnv Compat.emptyInstalledModuleEnv im ifr @@ -939,7 +1146,7 @@ mergeEnvs env mg ms extraMods envs = do fcModules' <- newIORef $! foldl' (plusInstalledModuleEnv combineModuleLocations) cur fcModules fcFiles' <- newIORef $! Map.unions fcFiles pure $ FinderCache fcModules' fcFiles' - +#endif withBootSuffix :: HscSource -> ModLocation -> ModLocation withBootSuffix HsBootFile = addBootSuffixLocnOut @@ -983,9 +1190,7 @@ getModSummaryFromImports env fp _modTime mContents = do implicit_prelude imps - convImport (L _ i) = ( - (ideclPkgQual i) - , reLoc $ ideclName i) + convImport (L _ i) = (ideclPkgQual i, reLoc $ ideclName i) msrImports = implicit_imports ++ imps @@ -1014,7 +1219,9 @@ getModSummaryFromImports env fp _modTime mContents = do { ms_mod = modl , ms_hie_date = Nothing , ms_dyn_obj_date = Nothing +#if !MIN_VERSION_ghc(9,13,0) , ms_ghc_prim_import = ghc_prim_import +#endif , ms_hs_hash = _src_hash , ms_hsc_src = sourceType @@ -1249,6 +1456,7 @@ data RecompilationInfo m , old_value :: Maybe (HiFileResult, FileVersion) , get_file_version :: NormalizedFilePath -> m (Maybe FileVersion) , get_linkable_hashes :: [NormalizedFilePath] -> m [BS.ByteString] + , get_module_graph :: m DependencyInformation , regenerate :: Maybe LinkableType -> m ([FileDiagnostic], Maybe HiFileResult) -- ^ Action to regenerate an interface } @@ -1305,7 +1513,7 @@ loadInterface session ms linkableNeeded RecompilationInfo{..} = do _read_dflags = hsc_dflags sessionWithMsDynFlags read_result <- liftIO $ readIface _read_dflags _ncu mod iface_file case read_result of - Util.Failed{} -> return Nothing + Util.Failed{} -> return Nothing -- important to call `shareUsages` here before checkOldIface -- consults `mi_usages` Util.Succeeded iface -> return $ Just (shareUsages iface) @@ -1331,7 +1539,7 @@ loadInterface session ms linkableNeeded RecompilationInfo{..} = do | not (mi_used_th iface) = emptyModuleEnv | otherwise = parseRuntimeDeps (md_anns details) -- Peform the fine grained recompilation check for TH - maybe_recomp <- checkLinkableDependencies session get_linkable_hashes runtime_deps + maybe_recomp <- checkLinkableDependencies session get_linkable_hashes get_module_graph runtime_deps case maybe_recomp of Just msg -> do_regenerate msg Nothing @@ -1368,8 +1576,12 @@ parseRuntimeDeps anns = mkModuleEnv $ mapMaybe go anns -- the runtime dependencies of the module, to check if any of them are out of date -- Hopefully 'runtime_deps' will be empty if the module didn't actually use TH -- See Note [Recompilation avoidance in the presence of TH] -checkLinkableDependencies :: MonadIO m => HscEnv -> ([NormalizedFilePath] -> m [BS.ByteString]) -> ModuleEnv BS.ByteString -> m (Maybe RecompileRequired) -checkLinkableDependencies hsc_env get_linkable_hashes runtime_deps = do +checkLinkableDependencies :: MonadIO m => HscEnv -> ([NormalizedFilePath] -> m [BS.ByteString]) -> m DependencyInformation -> ModuleEnv BS.ByteString -> m (Maybe RecompileRequired) +checkLinkableDependencies hsc_env get_linkable_hashes get_module_graph runtime_deps = do +#if MIN_VERSION_ghc(9,11,0) + graph <- get_module_graph + let go (mod, hash) = (,hash) <$> lookupModuleFile mod graph +#else moduleLocs <- liftIO $ readIORef (fcModuleCache $ hsc_FC hsc_env) let go (mod, hash) = do ifr <- lookupInstalledModuleEnv moduleLocs $ Compat.installedModule (toUnitId $ moduleUnit mod) (moduleName mod) @@ -1378,6 +1590,7 @@ checkLinkableDependencies hsc_env get_linkable_hashes runtime_deps = do hs <- ml_hs_file loc pure (toNormalizedFilePath' hs,hash) _ -> Nothing +#endif hs_files = mapM go (moduleEnvToList runtime_deps) case hs_files of Nothing -> error "invalid module graph" @@ -1419,12 +1632,14 @@ coreFileToCgGuts session iface details core_file = do }) core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckCoreFile this_mod types_var core_file -- Implicit binds aren't saved, so we need to regenerate them ourselves. - let _implicit_binds = concatMap getImplicitBinds tyCons -- only used if GHC < 9.6 - tyCons = typeEnvTyCons (md_types details) -#if MIN_VERSION_ghc(9,5,0) + let tyCons = typeEnvTyCons (md_types details) +#if MIN_VERSION_ghc(9,11,0) + pure $ CgGuts this_mod tyCons core_binds [] NoStubs [] mempty Nothing [] +#elif MIN_VERSION_ghc(9,5,0) -- In GHC 9.6, the implicit binds are tidied and part of core_binds pure $ CgGuts this_mod tyCons core_binds [] NoStubs [] mempty (emptyHpcInfo False) Nothing [] #else + let _implicit_binds = concatMap getImplicitBinds tyCons -- only used if GHC < 9.6 pure $ CgGuts this_mod tyCons (_implicit_binds ++ core_binds) [] NoStubs [] mempty (emptyHpcInfo False) Nothing [] #endif diff --git a/ghcide/src/Development/IDE/Core/PluginUtils.hs b/ghcide/src/Development/IDE/Core/PluginUtils.hs index 6ba633df26..25f7865e66 100644 --- a/ghcide/src/Development/IDE/Core/PluginUtils.hs +++ b/ghcide/src/Development/IDE/Core/PluginUtils.hs @@ -52,12 +52,18 @@ import qualified Development.IDE.Core.Shake as Shake import Development.IDE.GHC.Orphans () import Development.IDE.Graph hiding (ShakeValue) import Development.IDE.Types.Diagnostics -import Development.IDE.Types.Location (NormalizedFilePath) +import Development.IDE.Types.Location (NormalizedFilePath, + Range) import qualified Development.IDE.Types.Location as Location import qualified Ide.Logger as Logger import Ide.Plugin.Error import Ide.PluginUtils (rangesOverlap) -import Ide.Types +import Ide.Types (FormattingHandler, + FormattingMethod, + FormattingType (..), + PluginHandlers, + PluginMethodHandler, + mkPluginHandler) import qualified Language.LSP.Protocol.Lens as LSP import Language.LSP.Protocol.Message (SMethod (..)) import qualified Language.LSP.Protocol.Types as LSP @@ -180,6 +186,7 @@ fromCurrentRangeE mapping = maybeToExceptT (PluginInvalidUserState "fromCurrentR fromCurrentRangeMT :: Monad m => PositionMapping -> LSP.Range -> MaybeT m LSP.Range fromCurrentRangeMT mapping = MaybeT . pure . fromCurrentRange mapping + -- ---------------------------------------------------------------------------- -- Diagnostics -- ---------------------------------------------------------------------------- diff --git a/ghcide/src/Development/IDE/Core/RuleTypes.hs b/ghcide/src/Development/IDE/Core/RuleTypes.hs index fd6ef75cda..012912bc5f 100644 --- a/ghcide/src/Development/IDE/Core/RuleTypes.hs +++ b/ghcide/src/Development/IDE/Core/RuleTypes.hs @@ -282,6 +282,8 @@ type instance RuleResult GetFileContents = (FileVersion, Maybe Rope) type instance RuleResult GetFileExists = Bool +type instance RuleResult GetFileHash = Fingerprint + type instance RuleResult AddWatchedFile = Bool @@ -337,6 +339,12 @@ data GetFileExists = GetFileExists instance NFData GetFileExists instance Hashable GetFileExists +data GetFileHash = GetFileHash + deriving (Eq, Show, Typeable, Generic) + +instance NFData GetFileHash +instance Hashable GetFileHash + data FileOfInterestStatus = OnDisk | Modified { firstOpen :: !Bool -- ^ was this file just opened diff --git a/ghcide/src/Development/IDE/Core/Rules.hs b/ghcide/src/Development/IDE/Core/Rules.hs index 5650300a4c..2da64235f5 100644 --- a/ghcide/src/Development/IDE/Core/Rules.hs +++ b/ghcide/src/Development/IDE/Core/Rules.hs @@ -519,7 +519,12 @@ persistentHieFileRule recorder = addPersistentRule GetHieAst $ \file -> runMaybe getHieAstRuleDefinition :: NormalizedFilePath -> HscEnv -> TcModuleResult -> Action (IdeResult HieAstResult) getHieAstRuleDefinition f hsc tmr = do - (diags, masts) <- liftIO $ generateHieAsts hsc tmr +#if MIN_VERSION_ghc(9,11,0) + (diags, mastsFull) <- liftIO $ generateHieAsts hsc tmr + let masts = fst <$> mastsFull +#else + (diags, mastsFull@masts) <- liftIO $ generateHieAsts hsc tmr +#endif se <- getShakeExtras isFoi <- use_ IsFileOfInterest f @@ -529,7 +534,7 @@ getHieAstRuleDefinition f hsc tmr = do LSP.sendNotification (SMethod_CustomMethod (Proxy @"ghcide/reference/ready")) $ toJSON $ fromNormalizedFilePath f pure [] - _ | Just asts <- masts -> do + _ | Just asts <- mastsFull -> do source <- getSourceFileSource f let exports = tcg_exports $ tmrTypechecked tmr modSummary = tmrModSummary tmr @@ -610,6 +615,13 @@ knownFilesRule recorder = defineEarlyCutOffNoFile (cmapWithPrio LogShake recorde fs <- knownTargets pure (LBS.toStrict $ B.encode $ hash fs, unhashed fs) +getFileHashRule :: Recorder (WithPriority Log) -> Rules () +getFileHashRule recorder = + defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetFileHash file -> do + void $ use_ GetModificationTime file + fileHash <- liftIO $ Util.getFileHash (fromNormalizedFilePath file) + return (Just (fingerprintToBS fileHash), ([], Just fileHash)) + getModuleGraphRule :: Recorder (WithPriority Log) -> Rules () getModuleGraphRule recorder = defineEarlyCutOffNoFile (cmapWithPrio LogShake recorder) $ \GetModuleGraph -> do fs <- toKnownFiles <$> useNoFile_ GetKnownTargets @@ -646,6 +658,7 @@ typeCheckRuleDefinition hsc pm = do unlift <- askUnliftIO let dets = TypecheckHelpers { getLinkables = unliftIO unlift . uses_ GetLinkable + , getModuleGraph = unliftIO unlift $ useNoFile_ GetModuleGraph } addUsageDependencies $ liftIO $ typecheckModule defer hsc dets pm @@ -757,7 +770,8 @@ ghcSessionDepsDefinition fullModSummary GhcSessionDepsConfig{..} env file = do nubOrdOn mkNodeKey (ModuleNode final_deps ms : concatMap mgModSummaries' mgs) liftIO $ evaluate $ liftRnf rwhnf module_graph_nodes return $ mkModuleGraph module_graph_nodes - session' <- liftIO $ mergeEnvs hsc mg ms inLoadOrder depSessions + de <- useNoFile_ GetModuleGraph + session' <- liftIO $ mergeEnvs hsc mg de ms inLoadOrder depSessions -- Here we avoid a call to to `newHscEnvEqWithImportPaths`, which creates a new -- ExportsMap when it is called. We only need to create the ExportsMap once per @@ -786,9 +800,11 @@ getModIfaceFromDiskRule recorder = defineEarlyCutoff (cmapWithPrio LogShake reco , old_value = m_old , get_file_version = use GetModificationTime_{missingFileDiagnostics = False} , get_linkable_hashes = \fs -> map (snd . fromJust . hirCoreFp) <$> uses_ GetModIface fs + , get_module_graph = useNoFile_ GetModuleGraph , regenerate = regenerateHiFile session f ms } - r <- loadInterface (hscEnv session) ms linkableType recompInfo + hsc_env' <- setFileCacheHook (hscEnv session) + r <- loadInterface hsc_env' ms linkableType recompInfo case r of (diags, Nothing) -> return (Nothing, (diags, Nothing)) (diags, Just x) -> do @@ -887,8 +903,9 @@ getModSummaryRule displayTHWarning recorder = do generateCore :: RunSimplifier -> NormalizedFilePath -> Action (IdeResult ModGuts) generateCore runSimplifier file = do packageState <- hscEnv <$> use_ GhcSessionDeps file + hsc' <- setFileCacheHook packageState tm <- use_ TypeCheck file - liftIO $ compileModule runSimplifier packageState (tmrModSummary tm) (tmrTypechecked tm) + liftIO $ compileModule runSimplifier hsc' (tmrModSummary tm) (tmrTypechecked tm) generateCoreRule :: Recorder (WithPriority Log) -> Rules () generateCoreRule recorder = @@ -903,14 +920,15 @@ getModIfaceRule recorder = defineEarlyCutoff (cmapWithPrio LogShake recorder) $ tmr <- use_ TypeCheck f linkableType <- getLinkableType f hsc <- hscEnv <$> use_ GhcSessionDeps f + hsc' <- setFileCacheHook hsc let compile = fmap ([],) $ use GenerateCore f se <- getShakeExtras - (diags, !mbHiFile) <- writeCoreFileIfNeeded se hsc linkableType compile tmr + (diags, !mbHiFile) <- writeCoreFileIfNeeded se hsc' linkableType compile tmr let fp = hiFileFingerPrint <$> mbHiFile hiDiags <- case mbHiFile of Just hiFile | OnDisk <- status - , not (tmrDeferredError tmr) -> liftIO $ writeHiFile se hsc hiFile + , not (tmrDeferredError tmr) -> liftIO $ writeHiFile se hsc' hiFile _ -> pure [] return (fp, (diags++hiDiags, mbHiFile)) NotFOI -> do @@ -934,12 +952,21 @@ incrementRebuildCount = do count <- getRebuildCountVar <$> getIdeGlobalAction liftIO $ atomically $ modifyTVar' count (+1) +setFileCacheHook :: HscEnv -> Action HscEnv +setFileCacheHook old_hsc_env = do +#if MIN_VERSION_ghc(9,11,0) + unlift <- askUnliftIO + return $ old_hsc_env { hsc_FC = (hsc_FC old_hsc_env) { lookupFileCache = unliftIO unlift . use_ GetFileHash . toNormalizedFilePath' } } +#else + return old_hsc_env +#endif + -- | Also generates and indexes the `.hie` file, along with the `.o` file if needed -- Invariant maintained is that if the `.hi` file was successfully written, then the -- `.hie` and `.o` file (if needed) were also successfully written regenerateHiFile :: HscEnvEq -> NormalizedFilePath -> ModSummary -> Maybe LinkableType -> Action ([FileDiagnostic], Maybe HiFileResult) regenerateHiFile sess f ms compNeeded = do - let hsc = hscEnv sess + hsc <- setFileCacheHook (hscEnv sess) opt <- getIdeOptions -- Embed haddocks in the interface file @@ -1035,9 +1062,17 @@ usePropertyByPathAction path plId p = do getLinkableRule :: Recorder (WithPriority Log) -> Rules () getLinkableRule recorder = defineEarlyCutoff (cmapWithPrio LogShake recorder) $ Rule $ \GetLinkable f -> do - HiFileResult{hirModSummary, hirModIface, hirModDetails, hirCoreFp} <- use_ GetModIface f - let obj_file = ml_obj_file (ms_location hirModSummary) - core_file = ml_core_file (ms_location hirModSummary) + ModSummaryResult{msrModSummary = ms} <- use_ GetModSummary f + HiFileResult{hirModIface, hirModDetails, hirCoreFp} <- use_ GetModIface f + let obj_file = ml_obj_file (ms_location ms) + core_file = ml_core_file (ms_location ms) +#if MIN_VERSION_ghc(9,11,0) + mkLinkable t mod l = Linkable t mod (pure l) + dotO o = DotO o ModuleObject +#else + mkLinkable t mod l = LM t mod [l] + dotO = DotO +#endif case hirCoreFp of Nothing -> error $ "called GetLinkable for a file without a linkable: " ++ show f Just (bin_core, fileHash) -> do @@ -1050,7 +1085,7 @@ getLinkableRule recorder = core_t <- liftIO $ getModTime core_file (warns, hmi) <- case linkableType of -- Bytecode needs to be regenerated from the core file - BCOLinkable -> liftIO $ coreFileToLinkable linkableType (hscEnv session) hirModSummary hirModIface hirModDetails bin_core (posixSecondsToUTCTime core_t) + BCOLinkable -> liftIO $ coreFileToLinkable linkableType (hscEnv session) ms hirModIface hirModDetails bin_core (posixSecondsToUTCTime core_t) -- Object code can be read from the disk ObjectLinkable -> do -- object file is up to date if it is newer than the core file @@ -1063,10 +1098,15 @@ getLinkableRule recorder = else pure Nothing case mobj_time of Just obj_t - | obj_t >= core_t -> pure ([], Just $ HomeModInfo hirModIface hirModDetails (justObjects $ LM (posixSecondsToUTCTime obj_t) (ms_mod hirModSummary) [DotO obj_file])) - _ -> liftIO $ coreFileToLinkable linkableType (hscEnv session) hirModSummary hirModIface hirModDetails bin_core (error "object doesn't have time") + | obj_t >= core_t -> pure ([], Just $ HomeModInfo hirModIface hirModDetails (justObjects $ mkLinkable (posixSecondsToUTCTime obj_t) (ms_mod ms) (dotO obj_file))) + _ -> liftIO $ coreFileToLinkable linkableType (hscEnv session) ms hirModIface hirModDetails bin_core (error "object doesn't have time") -- Record the linkable so we know not to unload it, and unload old versions - whenJust ((homeModInfoByteCode =<< hmi) <|> (homeModInfoObject =<< hmi)) $ \(LM time mod _) -> do + whenJust ((homeModInfoByteCode =<< hmi) <|> (homeModInfoObject =<< hmi)) +#if MIN_VERSION_ghc(9,11,0) + $ \(Linkable time mod _) -> do +#else + $ \(LM time mod _) -> do +#endif compiledLinkables <- getCompiledLinkables <$> getIdeGlobalAction liftIO $ modifyVar compiledLinkables $ \old -> do let !to_keep = extendModuleEnv old mod time @@ -1080,7 +1120,9 @@ getLinkableRule recorder = --just before returning it to be loaded. This has a substantial effect on recompile --times as the number of loaded modules and splices increases. -- - unload (hscEnv session) (map (\(mod', time') -> LM time' mod' []) $ moduleEnvToList to_keep) + --We use a dummy DotA linkable part to fake a NativeCode linkable. + --The unload function doesn't care about the exact linkable parts. + unload (hscEnv session) (map (\(mod', time') -> mkLinkable time' mod' (DotA "dummy")) $ moduleEnvToList to_keep) return (to_keep, ()) return (fileHash <$ hmi, (warns, LinkableResult <$> hmi <*> pure fileHash)) @@ -1184,6 +1226,7 @@ mainRule recorder RulesConfig{..} = do getModIfaceRule recorder getModSummaryRule templateHaskellWarning recorder getModuleGraphRule recorder + getFileHashRule recorder knownFilesRule recorder getClientSettingsRule recorder getHieAstsRule recorder diff --git a/ghcide/src/Development/IDE/GHC/Compat.hs b/ghcide/src/Development/IDE/GHC/Compat.hs index 5f66625ee5..cc0d29b3fa 100644 --- a/ghcide/src/Development/IDE/GHC/Compat.hs +++ b/ghcide/src/Development/IDE/GHC/Compat.hs @@ -125,7 +125,9 @@ import Compat.HieUtils import Control.Applicative ((<|>)) import qualified Data.ByteString as BS import Data.Coerce (coerce) +#if !MIN_VERSION_ghc(9,9,0) import Data.List (foldl') +#endif import qualified Data.Map as Map import qualified Data.Set as S import Data.String (IsString (fromString)) @@ -180,14 +182,17 @@ import GHC.StgToByteCode import GHC.Types.CostCentre import GHC.Types.IPE import GHC.Types.SrcLoc (combineRealSrcSpans) +#if !MIN_VERSION_ghc(9,13,0) import GHC.Unit.Home.ModInfo (HomePackageTable, lookupHpt) -import GHC.Unit.Module.Deps (Dependencies (dep_direct_mods), - Usage (..)) +#endif import GHC.Unit.Module.ModIface -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] +import GHC.Unit.Module.Deps (Dependencies (dep_direct_mods), + Usage (..)) + #if !MIN_VERSION_ghc(9,5,0) import GHC.Core.Lint (lintInteractiveExpr) #endif @@ -204,6 +209,13 @@ import GHC.Driver.Config.CoreToStg.Prep (initCorePrepConfig) import GHC.Tc.Zonk.TcType (tcInitTidyEnv) #endif +#if MIN_VERSION_ghc(9,13,0) +import GHC.Unit.Home.PackageTable (lookupHpt, HomePackageTable) +import GHC.Unit.Home.Graph +import Control.Monad (forM_) +#endif + + #if !MIN_VERSION_ghc(9,7,0) liftZonkM :: a -> a liftZonkM = id @@ -338,10 +350,20 @@ type NameCacheUpdater = NameCache mkHieFile' :: ModSummary -> [Avail.AvailInfo] +#if MIN_VERSION_ghc(9,11,0) + -> (HieASTs Type, NameEntityInfo) +#else -> HieASTs Type +#endif -> BS.ByteString -> Hsc HieFile -mkHieFile' ms exports asts src = do +mkHieFile' ms exports +#if MIN_VERSION_ghc(9,11,0) + (asts, entityInfo) +#else + asts +#endif + src = do let Just src_file = ml_hs_file $ ms_location ms (asts',arr) = compressTypes asts return $ HieFile @@ -352,6 +374,9 @@ mkHieFile' ms exports asts src = do -- mkIfaceExports sorts the AvailInfos for stability , hie_exports = mkIfaceExports exports , hie_hs_src = src +#if MIN_VERSION_ghc(9,11,0) + , hie_entity_infos = entityInfo +#endif } addIncludePathsQuote :: FilePath -> DynFlags -> DynFlags @@ -444,13 +469,16 @@ data GhcVersion | GHC96 | GHC98 | GHC910 + | GHC912 deriving (Eq, Ord, Show, Enum) ghcVersionStr :: String ghcVersionStr = VERSION_ghc ghcVersion :: GhcVersion -#if MIN_VERSION_GLASGOW_HASKELL(9,10,0,0) +#if MIN_VERSION_GLASGOW_HASKELL(9,12,0,0) +ghcVersion = GHC912 +#elif MIN_VERSION_GLASGOW_HASKELL(9,10,0,0) ghcVersion = GHC910 #elif MIN_VERSION_GLASGOW_HASKELL(9,8,0,0) ghcVersion = GHC98 @@ -488,9 +516,18 @@ mkAstNode n = Node (SourcedNodeInfo $ Map.singleton GeneratedInfo n) loadModulesHome :: [HomeModInfo] -> HscEnv +#if MIN_VERSION_ghc(9,13,0) + -> IO () +#else -> HscEnv +#endif loadModulesHome mod_infos e = +#if MIN_VERSION_ghc(9,13,0) + forM_ mod_infos $ + flip hscInsertHPT (e { hsc_type_env_vars = emptyKnotVars }) +#else hscUpdateHUG (\hug -> foldl' (flip addHomeModInfoToHug) hug mod_infos) (e { hsc_type_env_vars = emptyKnotVars }) +#endif recDotDot :: HsRecFields (GhcPass p) arg -> Maybe Int recDotDot x = diff --git a/ghcide/src/Development/IDE/GHC/Compat/Core.hs b/ghcide/src/Development/IDE/GHC/Compat/Core.hs index 301aa980bd..90c80e47bd 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Core.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Core.hs @@ -69,6 +69,11 @@ module Development.IDE.GHC.Compat.Core ( IfaceTyCon(..), ModIface, ModIface_(..), +#if MIN_VERSION_ghc(9,11,0) + pattern ModIface, + set_mi_top_env, + set_mi_usages, +#endif HscSource(..), WhereFrom(..), loadInterface, @@ -166,6 +171,7 @@ module Development.IDE.GHC.Compat.Core ( Development.IDE.GHC.Compat.Core.initTidyOpts, driverNoStop, tidyProgram, + tidyOpenType, ImportedModsVal(..), importedByUser, GHC.TypecheckedSource, @@ -230,7 +236,12 @@ module Development.IDE.GHC.Compat.Core ( ModuleOrigin(..), PackageName(..), -- * Linker +#if !MIN_VERSION_ghc(9,11,0) Unlinked(..), +#else + LinkablePart(..), + Unlinked, +#endif Linkable(..), unload, -- * Hooks @@ -360,6 +371,10 @@ module Development.IDE.GHC.Compat.Core ( getKey, module GHC.Driver.Env.KnotVars, module GHC.Linker.Types, +#if MIN_VERSION_ghc(9,11,0) + pattern LM, +#endif + module GHC.Types.Unique.Map, module GHC.Utils.TmpFs, module GHC.Unit.Finder.Types, @@ -417,7 +432,8 @@ import GHC.Core.Predicate import GHC.Core.TyCo.Ppr import qualified GHC.Core.TyCo.Rep as TyCoRep import GHC.Core.TyCon -import GHC.Core.Type +import GHC.Core.Type hiding (tidyOpenType) +import qualified GHC.Core.Type as GHC.Core.Type import GHC.Core.Unify import GHC.Core.Utils import GHC.Driver.CmdLine (Warn (..)) @@ -521,6 +537,7 @@ import GHC.Types.TyThing import GHC.Types.TyThing.Ppr import GHC.Types.Unique import GHC.Types.Unique.Map +import GHC.Types.Var.Env (TidyEnv) import GHC.Unit.Env import GHC.Unit.Finder hiding (mkHomeModLocation) import qualified GHC.Unit.Finder as GHC @@ -531,7 +548,13 @@ import GHC.Unit.Module.Imported import GHC.Unit.Module.ModDetails import GHC.Unit.Module.ModGuts import GHC.Unit.Module.ModIface (IfaceExport, ModIface, - ModIface_ (..), mi_fix) + ModIface_ (..), mi_fix +#if MIN_VERSION_ghc(9,11,0) + , pattern ModIface + , set_mi_top_env + , set_mi_usages +#endif + ) import GHC.Unit.Module.ModSummary (ModSummary (..)) import GHC.Utils.Error (mkPlainErrorMsgEnvelope) import GHC.Utils.Panic @@ -539,8 +562,6 @@ import GHC.Utils.TmpFs import Language.Haskell.Syntax hiding (FunDep) -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] - - #if !MIN_VERSION_ghc(9,7,0) import GHC.Types.Avail (greNamePrintableName) #endif @@ -549,8 +570,27 @@ import GHC.Types.Avail (greNamePrintableName) import GHC.Hs (SrcSpanAnn') #endif +#if MIN_VERSION_ghc(9,12,0) +import System.OsString +import System.FilePath (splitExtension) +#endif + +#if MIN_VERSION_ghc(9,13,0) +import GHC.Unit.Home.PackageTable +#endif + mkHomeModLocation :: DynFlags -> ModuleName -> FilePath -> IO Module.ModLocation +#if MIN_VERSION_ghc(9,13,0) +mkHomeModLocation df mn f = pure $ GHC.mkHomeModLocation (GHC.initFinderOpts df) mn (unsafeEncodeUtf basename) (unsafeEncodeUtf ext) HsSrcFile + where + (basename, ext) = splitExtension f +#elif MIN_VERSION_ghc(9,11,0) +mkHomeModLocation df mn f = + pure $ GHC.mkHomeModLocation (GHC.initFinderOpts df) mn (unsafeEncodeUtf f) +#else mkHomeModLocation df mn f = pure $ GHC.mkHomeModLocation (GHC.initFinderOpts df) mn f +#endif + pattern RealSrcSpan :: SrcLoc.RealSrcSpan -> Maybe BufSpan -> SrcLoc.SrcSpan @@ -709,7 +749,7 @@ pattern GRE{gre_name, gre_par, gre_lcl, gre_imp} <- RdrName.GRE #endif ,gre_par, gre_lcl, gre_imp = (toList -> gre_imp)} -collectHsBindsBinders :: CollectPass p => Bag (XRec p (HsBindLR p idR)) -> [IdP p] +collectHsBindsBinders :: CollectPass p => LHsBinds p -> [IdP p] collectHsBindsBinders x = GHC.collectHsBindsBinders CollNoDictBinders x @@ -790,3 +830,20 @@ mkSimpleTarget df fp = Target (TargetFile fp Nothing) True (homeUnitId_ df) Noth #if MIN_VERSION_ghc(9,7,0) lookupGlobalRdrEnv gre_env occ = lookupGRE gre_env (LookupOccName occ AllRelevantGREs) #endif + + +#if MIN_VERSION_ghc(9,11,0) +type Unlinked = LinkablePart +pattern LM a b c = Linkable a b c +{-# COMPLETE LM #-} +-- state that it is complete +#endif +-- pattern LM :: Linkable -> [Linkable] -> [Linkable] -> Linkable + + +tidyOpenType :: TidyEnv -> Type -> Type +#if !MIN_VERSION_ghc(9,11,0) +tidyOpenType x = snd . GHC.Core.Type.tidyOpenType x +#else +tidyOpenType = GHC.Core.Type.tidyOpenType +#endif diff --git a/ghcide/src/Development/IDE/GHC/Compat/Driver.hs b/ghcide/src/Development/IDE/GHC/Compat/Driver.hs index c88d0963d6..2e934d71bd 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Driver.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Driver.hs @@ -40,10 +40,12 @@ import GHC.Utils.Logger import GHC.Utils.Outputable import GHC.Utils.Panic.Plain +#if !MIN_VERSION_ghc(9,11,0) hscTypecheckRenameWithDiagnostics :: HscEnv -> ModSummary -> HsParsedModule -> IO ((TcGblEnv, RenamedStuff), Messages GhcMessage) hscTypecheckRenameWithDiagnostics hsc_env mod_summary rdr_module = runHsc' hsc_env $ hsc_typecheck True mod_summary (Just rdr_module) +#endif -- ============================================================================ -- DO NOT EDIT - Refer to top of file diff --git a/ghcide/src/Development/IDE/GHC/Compat/Iface.hs b/ghcide/src/Development/IDE/GHC/Compat/Iface.hs index e76de880d5..39cf9e0d45 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Iface.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Iface.hs @@ -21,7 +21,11 @@ import GHC.Iface.Errors.Types (IfaceMessage) #endif writeIfaceFile :: HscEnv -> FilePath -> ModIface -> IO () +#if MIN_VERSION_ghc(9,11,0) +writeIfaceFile env fp iface = Iface.writeIface (hsc_logger env) (targetProfile $ hsc_dflags env) (Iface.flagsToIfCompression $ hsc_dflags env) fp iface +#else writeIfaceFile env fp iface = Iface.writeIface (hsc_logger env) (targetProfile $ hsc_dflags env) fp iface +#endif cannotFindModule :: HscEnv -> ModuleName -> FindResult -> SDoc cannotFindModule env modname fr = diff --git a/ghcide/src/Development/IDE/GHC/Compat/Parser.hs b/ghcide/src/Development/IDE/GHC/Compat/Parser.hs index 25d23bcad4..bfa519b5e0 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Parser.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Parser.hs @@ -16,14 +16,18 @@ module Development.IDE.GHC.Compat.Parser ( Development.IDE.GHC.Compat.Parser.pm_mod_summary, Development.IDE.GHC.Compat.Parser.pm_extra_src_files, -- * API Annotations +#if !MIN_VERSION_ghc(9,11,0) Anno.AnnKeywordId(..), +#endif pattern EpaLineComment, pattern EpaBlockComment ) where import Development.IDE.GHC.Compat.Core import Development.IDE.GHC.Compat.Util +#if !MIN_VERSION_ghc(9,11,0) import qualified GHC.Parser.Annotation as Anno +#endif import qualified GHC.Parser.Lexer as Lexer import GHC.Types.SrcLoc (PsSpan (..)) diff --git a/ghcide/src/Development/IDE/GHC/Compat/Units.hs b/ghcide/src/Development/IDE/GHC/Compat/Units.hs index f7f634e448..b2423c10ed 100644 --- a/ghcide/src/Development/IDE/GHC/Compat/Units.hs +++ b/ghcide/src/Development/IDE/GHC/Compat/Units.hs @@ -81,6 +81,48 @@ type PreloadUnitClosure = UniqSet UnitId unitState :: HscEnv -> UnitState unitState = ue_units . hsc_unit_env +#if MIN_VERSION_ghc(9,13,0) +createUnitEnvFromFlags :: NE.NonEmpty DynFlags -> IO HomeUnitGraph +createUnitEnvFromFlags unitDflags = do + emptyHpt <- emptyHomePackageTable + let + newInternalUnitEnv dflags = mkHomeUnitEnv emptyUnitState Nothing dflags emptyHpt Nothing + unitEnvList = NE.map (\dflags -> (homeUnitId_ dflags, newInternalUnitEnv dflags)) unitDflags + return $ + unitEnv_new (Map.fromList (NE.toList (unitEnvList))) + +initUnits :: [DynFlags] -> HscEnv -> IO HscEnv +initUnits unitDflags env = do + let dflags0 = hsc_dflags env + -- additionally, set checked dflags so we don't lose fixes + initial_home_graph <- createUnitEnvFromFlags (dflags0 NE.:| unitDflags) + let home_units = unitEnv_keys initial_home_graph + home_unit_graph <- forM initial_home_graph $ \homeUnitEnv -> do + let cached_unit_dbs = homeUnitEnv_unit_dbs homeUnitEnv + dflags = homeUnitEnv_dflags homeUnitEnv + old_hpt = homeUnitEnv_hpt homeUnitEnv + + (dbs,unit_state,home_unit,mconstants) <- State.initUnits (hsc_logger env) dflags cached_unit_dbs home_units + + updated_dflags <- DynFlags.updatePlatformConstants dflags mconstants + pure HomeUnitEnv + { homeUnitEnv_units = unit_state + , homeUnitEnv_unit_dbs = Just dbs + , homeUnitEnv_dflags = updated_dflags + , homeUnitEnv_hpt = old_hpt + , homeUnitEnv_home_unit = Just home_unit + } + + let dflags1 = homeUnitEnv_dflags $ unitEnv_lookup (homeUnitId_ dflags0) home_unit_graph + let unit_env = UnitEnv + { ue_platform = targetPlatform dflags1 + , ue_namever = GHC.ghcNameVersion dflags1 + , ue_home_unit_graph = home_unit_graph + , ue_current_unit = homeUnitId_ dflags0 + , ue_eps = ue_eps (hsc_unit_env env) + } + pure $ hscSetFlags dflags1 $ hscSetUnitEnv unit_env env +#else createUnitEnvFromFlags :: NE.NonEmpty DynFlags -> HomeUnitGraph createUnitEnvFromFlags unitDflags = let @@ -120,7 +162,7 @@ initUnits unitDflags env = do , ue_eps = ue_eps (hsc_unit_env env) } pure $ hscSetFlags dflags1 $ hscSetUnitEnv unit_env env - +#endif explicitUnits :: UnitState -> [Unit] explicitUnits ue = diff --git a/ghcide/src/Development/IDE/GHC/CoreFile.hs b/ghcide/src/Development/IDE/GHC/CoreFile.hs index f2b58ee02e..015c5e3aff 100644 --- a/ghcide/src/Development/IDE/GHC/CoreFile.hs +++ b/ghcide/src/Development/IDE/GHC/CoreFile.hs @@ -26,6 +26,9 @@ import GHC.CoreToIface import GHC.Fingerprint import GHC.Iface.Binary import GHC.Iface.Env +#if MIN_VERSION_ghc(9,11,0) +import qualified GHC.Iface.Load as Iface +#endif import GHC.Iface.Recomp.Binary (fingerprintBinMem) import GHC.IfaceToCore import GHC.Types.Id.Make @@ -87,14 +90,20 @@ readBinCoreFile name_cache fat_hi_path = do return (file, fp) -- | Write a core file -writeBinCoreFile :: FilePath -> CoreFile -> IO Fingerprint -writeBinCoreFile core_path fat_iface = do +writeBinCoreFile :: DynFlags -> FilePath -> CoreFile -> IO Fingerprint +writeBinCoreFile _dflags core_path fat_iface = do bh <- openBinMem initBinMemSize let quietTrace = QuietBinIFace - putWithUserData quietTrace bh fat_iface + putWithUserData + quietTrace +#if MIN_VERSION_ghc(9,11,0) + (Iface.flagsToIfCompression _dflags) +#endif + bh + fat_iface -- And send the result to the file writeBinMem bh core_path @@ -141,7 +150,11 @@ getClassImplicitBinds cls | (op, val_index) <- classAllSelIds cls `zip` [0..] ] get_defn :: Id -> CoreBind -get_defn identifier = NonRec identifier (unfoldingTemplate (realIdUnfolding identifier)) +get_defn identifier = NonRec identifier templ + where + templ = case maybeUnfoldingTemplate (realIdUnfolding identifier) of + Nothing -> error "get_dfn: no unfolding template" + Just x -> x toIfaceTopBndr1 :: Module -> Id -> IfaceId toIfaceTopBndr1 mod identifier diff --git a/ghcide/src/Development/IDE/GHC/Orphans.hs b/ghcide/src/Development/IDE/GHC/Orphans.hs index 2ee19beeb2..e3facf41bf 100644 --- a/ghcide/src/Development/IDE/GHC/Orphans.hs +++ b/ghcide/src/Development/IDE/GHC/Orphans.hs @@ -25,8 +25,10 @@ import GHC.Data.Bag import GHC.Data.FastString import qualified GHC.Data.StringBuffer as SB import GHC.Parser.Annotation +#if !MIN_VERSION_ghc(9,5,0) import GHC.Types.FieldLabel (DuplicateRecordFields (DuplicateRecordFields, NoDuplicateRecordFields), FieldSelectors (FieldSelectors, NoFieldSelectors)) +#endif import GHC.Types.PkgQual import GHC.Types.SrcLoc @@ -51,22 +53,44 @@ instance Show ModDetails where show = const "" instance NFData ModDetails where rnf = rwhnf instance NFData SafeHaskellMode where rnf = rwhnf instance Show Linkable where show = unpack . printOutputable +#if MIN_VERSION_ghc(9,11,0) +instance NFData LinkableObjectSort where rnf = rwhnf instance NFData Linkable where rnf (LM a b c) = rnf a `seq` rnf b `seq` rnf c +#else +instance NFData Linkable where rnf (LM a b c) = rnf a `seq` rnf b `seq` rnf c +#endif instance NFData Unlinked where +#if MIN_VERSION_ghc(9,11,0) + rnf (DotO f l) = rnf f `seq` rnf l + rnf (LazyBCOs a b) = seqCompiledByteCode a `seq` liftRnf rwhnf b + rnf (BCOs a) = seqCompiledByteCode a +#else rnf (DotO f) = rnf f + rnf (BCOs a b) = seqCompiledByteCode a `seq` liftRnf rwhnf b +#endif rnf (DotA f) = rnf f rnf (DotDLL f) = rnf f - rnf (BCOs a b) = seqCompiledByteCode a `seq` liftRnf rwhnf b #if MIN_VERSION_ghc(9,5,0) rnf (CoreBindings wcb) = rnf wcb +#endif +#if MIN_VERSION_ghc(9,5,0) && !MIN_VERSION_ghc(9,11,0) rnf (LoadedBCOs us) = rnf us +#endif +#if MIN_VERSION_ghc(9,5,0) instance NFData WholeCoreBindings where +#if MIN_VERSION_ghc(9,11,0) + rnf (WholeCoreBindings bs m ml f) = rnf bs `seq` rnf m `seq` rnf ml `seq` rnf f +#else rnf (WholeCoreBindings bs m ml) = rnf bs `seq` rnf m `seq` rnf ml +#endif instance NFData ModLocation where +#if MIN_VERSION_ghc(9,11,0) + rnf (OsPathModLocation mf f1 f2 f3 f4 f5) = rnf mf `seq` rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` rnf f5 +#else rnf (ModLocation mf f1 f2 f3 f4 f5) = rnf mf `seq` rnf f1 `seq` rnf f2 `seq` rnf f3 `seq` rnf f4 `seq` rnf f5 - +#endif #endif instance Show PackageFlag where show = unpack . printOutputable diff --git a/ghcide/src/Development/IDE/Import/DependencyInformation.hs b/ghcide/src/Development/IDE/Import/DependencyInformation.hs index 5372a1364a..d6e0f5614c 100644 --- a/ghcide/src/Development/IDE/Import/DependencyInformation.hs +++ b/ghcide/src/Development/IDE/Import/DependencyInformation.hs @@ -20,6 +20,7 @@ module Development.IDE.Import.DependencyInformation , insertImport , pathToId , idToPath + , idToModLocation , reachableModules , processDependencyInformation , transitiveDeps diff --git a/ghcide/src/Development/IDE/Import/FindImports.hs b/ghcide/src/Development/IDE/Import/FindImports.hs index 7fa287836b..ee9e632073 100644 --- a/ghcide/src/Development/IDE/Import/FindImports.hs +++ b/ghcide/src/Development/IDE/Import/FindImports.hs @@ -26,6 +26,9 @@ import Development.IDE.Types.Diagnostics import Development.IDE.Types.Location import GHC.Types.PkgQual import GHC.Unit.State +#if MIN_VERSION_ghc(9,11,0) +import GHC.Driver.DynFlags +#endif import System.FilePath @@ -91,12 +94,23 @@ locateModuleFile import_dirss exts targetFor isSource modName = do | isSource = ext ++ "-boot" | otherwise = ext +reexportedModulesFrom :: DynFlags -> S.Set ModuleName +reexportedModulesFrom flag = +#if MIN_VERSION_ghc(9,11,0) + S.fromList $ reexportFrom <$> +#endif + reexportedModules flag + -- | This function is used to map a package name to a set of import paths. -- It only returns Just for unit-ids which are possible to import into the -- current module. In particular, it will return Nothing for 'main' components -- as they can never be imported into another package. mkImportDirs :: HscEnv -> (UnitId, DynFlags) -> Maybe (UnitId, ([FilePath], S.Set ModuleName)) +#if MIN_VERSION_ghc(9,11,0) +mkImportDirs _env (i, flags) = Just (i, (importPaths flags, S.fromList $ map reexportTo $ reexportedModules flags)) +#else mkImportDirs _env (i, flags) = Just (i, (importPaths flags, reexportedModules flags)) +#endif -- | locate a module in either the file system or the package database. Where we go from *daml to -- Haskell @@ -146,7 +160,7 @@ locateModule env comp_info exts targetFor modName mbPkgName isSource = do -- about which module unit a imports. -- Without multi-component support it is hard to recontruct the dependency environment so -- unit a will have both unit b and unit c in scope. - map (\uid -> let this_df = homeUnitEnv_dflags (ue_findHomeUnitEnv uid ue) in (uid, importPaths this_df, reexportedModules this_df)) hpt_deps + map (\uid -> let this_df = homeUnitEnv_dflags (ue_findHomeUnitEnv uid ue) in (uid, importPaths this_df, reexportedModulesFrom this_df)) hpt_deps ue = hsc_unit_env env units = homeUnitEnv_units $ ue_findHomeUnitEnv (homeUnitId_ dflags) ue hpt_deps :: [UnitId] diff --git a/ghcide/src/Development/IDE/Plugin/TypeLenses.hs b/ghcide/src/Development/IDE/Plugin/TypeLenses.hs index a1aa237de8..5c281eb4f8 100644 --- a/ghcide/src/Development/IDE/Plugin/TypeLenses.hs +++ b/ghcide/src/Development/IDE/Plugin/TypeLenses.hs @@ -321,7 +321,7 @@ gblBindingType (Just hsc) (Just gblEnv) = do let name = idName identifier hasSig name $ do env <- tcInitTidyEnv - let (_, ty) = tidyOpenType env (idType identifier) + let ty = tidyOpenType env (idType identifier) pure $ GlobalBindingTypeSig name (printName name <> " :: " <> showDoc (pprSigmaType ty)) (name `elemNameSet` exports) patToSig p = do let name = patSynName p diff --git a/ghcide/test/exe/ExceptionTests.hs b/ghcide/test/exe/ExceptionTests.hs index 756e7e0547..a95f91e97c 100644 --- a/ghcide/test/exe/ExceptionTests.hs +++ b/ghcide/test/exe/ExceptionTests.hs @@ -8,7 +8,7 @@ import Control.Monad.Error.Class (MonadError (throwError)) import Control.Monad.IO.Class (liftIO) import qualified Data.Aeson as A import Data.Default (Default (..)) -import Data.Text as T +import qualified Data.Text as T import Development.IDE.Core.Shake (IdeState (..)) import qualified Development.IDE.LSP.Notifications as Notifications import Development.IDE.Plugin.HLS (toResponseError) diff --git a/ghcide/test/exe/UnitTests.hs b/ghcide/test/exe/UnitTests.hs index b2940ab27f..23d866660a 100644 --- a/ghcide/test/exe/UnitTests.hs +++ b/ghcide/test/exe/UnitTests.hs @@ -28,7 +28,9 @@ import Network.URI import qualified Progress import System.IO.Extra hiding (withTempDir) import System.Mem (performGC) -import Test.Hls (IdeState, def, +import Test.Hls (GhcVersion (GHC912), + IdeState, def, + ignoreForGhcVersions, runSessionWithServerInTmpDir, waitForProgressDone) import Test.Tasty @@ -97,7 +99,7 @@ tests = do let msg = printf "Timestamps do not have millisecond resolution: %dus" resolution_us assertBool msg (resolution_us <= 1000) , Progress.tests - , FuzzySearch.tests + , ignoreForGhcVersions [GHC912] "Fuzzy search: ignore since referenceImplementation get stuck for ghc912" $ FuzzySearch.tests ] findResolution_us :: Int -> IO Int diff --git a/haskell-language-server.cabal b/haskell-language-server.cabal index 5f011472fb..eede5ec4ed 100644 --- a/haskell-language-server.cabal +++ b/haskell-language-server.cabal @@ -109,7 +109,7 @@ flag cabalfmt manual: True common cabalfmt - if flag(cabalfmt) + if flag(cabalfmt) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-cabal-fmt-plugin cpp-options: -Dhls_cabalfmt @@ -121,7 +121,7 @@ flag isolateCabalfmtTests library hls-cabal-fmt-plugin import: defaults, pedantic, warnings - if !flag(cabalfmt) + if !flag(cabalfmt) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.CabalFmt hs-source-dirs: plugins/hls-cabal-fmt-plugin/src @@ -140,7 +140,7 @@ library hls-cabal-fmt-plugin -- The `hls-cabal-plugin` is needed for tests, as we need to install notification handlers test-suite hls-cabal-fmt-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(cabalfmt) + if !flag(cabalfmt) || !flag(cabal) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-cabal-fmt-plugin/test @@ -168,7 +168,7 @@ flag cabalgild manual: True common cabalgild - if flag(cabalgild) + if flag(cabalgild) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-cabal-gild-plugin cpp-options: -Dhls_cabalgild @@ -180,7 +180,7 @@ flag isolateCabalGildTests library hls-cabal-gild-plugin import: defaults, pedantic, warnings - if !flag(cabalgild) + if !flag(cabalgild) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.CabalGild hs-source-dirs: plugins/hls-cabal-gild-plugin/src @@ -198,7 +198,7 @@ library hls-cabal-gild-plugin -- The `hls-cabal-plugin` is needed for tests, as we need to install notification handlers test-suite hls-cabal-gild-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(cabalgild) + if !flag(cabalgild) || !flag(cabal) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-cabal-gild-plugin/test @@ -227,13 +227,13 @@ flag cabal manual: True common cabal - if flag(cabal) + if flag(cabal) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-cabal-plugin cpp-options: -Dhls_cabal library hls-cabal-plugin import: defaults, pedantic, warnings - if !flag(cabal) + if !flag(cabal) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.Cabal @@ -289,7 +289,7 @@ library hls-cabal-plugin test-suite hls-cabal-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(cabal) + if !flag(cabal) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-cabal-plugin/test @@ -325,13 +325,13 @@ flag class manual: True common class - if flag(class) + if flag(class) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-class-plugin cpp-options: -Dhls_class library hls-class-plugin import: defaults, pedantic, warnings - if !flag(class) + if !flag(class) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.Class other-modules: Ide.Plugin.Class.CodeAction @@ -363,7 +363,7 @@ library hls-class-plugin test-suite hls-class-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(class) + if !flag(class) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-class-plugin/test @@ -387,13 +387,13 @@ flag callHierarchy manual: True common callHierarchy - if flag(callHierarchy) + if flag(callHierarchy) && impl(ghc < 9.13) build-depends: haskell-language-server:hls-call-hierarchy-plugin cpp-options: -Dhls_callHierarchy library hls-call-hierarchy-plugin import: defaults, pedantic, warnings - if !flag(callHierarchy) + if !flag(callHierarchy) || impl(ghc > 9.13) buildable: False exposed-modules: Ide.Plugin.CallHierarchy other-modules: @@ -419,7 +419,7 @@ library hls-call-hierarchy-plugin test-suite hls-call-hierarchy-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(callHierarchy) + if !flag(callHierarchy) || impl(ghc > 9.13) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-call-hierarchy-plugin/test @@ -447,13 +447,13 @@ flag eval manual: True common eval - if flag(eval) + if flag(eval) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-eval-plugin cpp-options: -Dhls_eval library hls-eval-plugin import: defaults, pedantic, warnings - if !flag(eval) + if !flag(eval) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.Eval @@ -502,7 +502,7 @@ library hls-eval-plugin test-suite hls-eval-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(eval) + if !flag(eval) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-eval-plugin/test @@ -525,19 +525,20 @@ test-suite hls-eval-plugin-tests -- import lens plugin ----------------------------- -common importLens - if flag(importLens) - build-depends: haskell-language-server:hls-explicit-imports-plugin - cpp-options: -Dhls_importLens - flag importLens description: Enable importLens plugin default: True manual: True +common importLens + if flag(importLens) && impl(ghc < 9.11) + build-depends: haskell-language-server:hls-explicit-imports-plugin + cpp-options: -Dhls_importLens + + library hls-explicit-imports-plugin import: defaults, pedantic, warnings - if !flag(importlens) + if !flag(importlens) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.ExplicitImports hs-source-dirs: plugins/hls-explicit-imports-plugin/src @@ -561,7 +562,7 @@ library hls-explicit-imports-plugin test-suite hls-explicit-imports-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(importlens) + if !flag(importlens) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-explicit-imports-plugin/test @@ -586,13 +587,13 @@ flag rename manual: True common rename - if flag(rename) + if flag(rename) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-rename-plugin cpp-options: -Dhls_rename library hls-rename-plugin import: defaults, pedantic, warnings - if !flag(rename) + if !flag(rename) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.Rename hs-source-dirs: plugins/hls-rename-plugin/src @@ -617,7 +618,7 @@ library hls-rename-plugin test-suite hls-rename-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(rename) + if !flag(rename) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-rename-plugin/test @@ -720,7 +721,7 @@ common hlint library hls-hlint-plugin import: defaults, pedantic, warnings -- https://github.com/ndmitchell/hlint/pull/1594 - if !(flag(hlint) && impl(ghc < 9.10)) + if !(flag(hlint)) || impl(ghc > 9.10) buildable: False exposed-modules: Ide.Plugin.Hlint hs-source-dirs: plugins/hls-hlint-plugin/src @@ -764,7 +765,7 @@ library hls-hlint-plugin test-suite hls-hlint-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !(flag(hlint) && impl(ghc < 9.10)) + if (!flag(hlint)) || impl(ghc > 9.10) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-hlint-plugin/test @@ -794,15 +795,13 @@ flag stan manual: True common stan - if flag(stan) + if flag(stan) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-stan-plugin cpp-options: -Dhls_stan library hls-stan-plugin import: defaults, pedantic, warnings - if flag(stan) - buildable: True - else + if !flag(stan) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.Stan hs-source-dirs: plugins/hls-stan-plugin/src @@ -828,9 +827,7 @@ library hls-stan-plugin test-suite hls-stan-plugin-tests import: defaults, pedantic, test-defaults, warnings - if flag(stan) - buildable: True - else + if !flag(stan) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-stan-plugin/test @@ -857,13 +854,13 @@ flag moduleName manual: True common moduleName - if flag(moduleName) + if flag(moduleName) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-module-name-plugin cpp-options: -Dhls_moduleName library hls-module-name-plugin import: defaults, pedantic, warnings - if !flag(modulename) + if !flag(modulename) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.ModuleName hs-source-dirs: plugins/hls-module-name-plugin/src @@ -882,7 +879,7 @@ library hls-module-name-plugin test-suite hls-module-name-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(modulename) + if !flag(modulename) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-module-name-plugin/test @@ -903,13 +900,13 @@ flag pragmas manual: True common pragmas - if flag(pragmas) + if flag(pragmas) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-pragmas-plugin cpp-options: -Dhls_pragmas library hls-pragmas-plugin import: defaults, pedantic, warnings - if !flag(pragmas) + if !flag(pragmas) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.Pragmas hs-source-dirs: plugins/hls-pragmas-plugin/src @@ -929,7 +926,7 @@ library hls-pragmas-plugin test-suite hls-pragmas-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(pragmas) + if !flag(pragmas) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-pragmas-plugin/test @@ -1011,13 +1008,13 @@ flag alternateNumberFormat manual: True common alternateNumberFormat - if flag(alternateNumberFormat) + if flag(alternateNumberFormat) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-alternate-number-format-plugin cpp-options: -Dhls_alternateNumberFormat library hls-alternate-number-format-plugin import: defaults, pedantic, warnings - if !flag(alternateNumberFormat) + if !flag(alternateNumberFormat) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.AlternateNumberFormat, Ide.Plugin.Conversion other-modules: Ide.Plugin.Literals @@ -1044,7 +1041,7 @@ library hls-alternate-number-format-plugin test-suite hls-alternate-number-format-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(alternateNumberFormat) + if !flag(alternateNumberFormat) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-alternate-number-format-plugin/test @@ -1075,13 +1072,13 @@ flag qualifyImportedNames manual: True common qualifyImportedNames - if flag(qualifyImportedNames) + if flag(qualifyImportedNames) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-qualify-imported-names-plugin cpp-options: -Dhls_qualifyImportedNames library hls-qualify-imported-names-plugin import: defaults, pedantic, warnings - if !flag(qualifyImportedNames) + if !flag(qualifyImportedNames) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.QualifyImportedNames hs-source-dirs: plugins/hls-qualify-imported-names-plugin/src @@ -1102,7 +1099,7 @@ library hls-qualify-imported-names-plugin test-suite hls-qualify-imported-names-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(qualifyImportedNames) + if !flag(qualifyImportedNames) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-qualify-imported-names-plugin/test @@ -1124,13 +1121,13 @@ flag codeRange manual: True common codeRange - if flag(codeRange) + if flag(codeRange) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-code-range-plugin cpp-options: -Dhls_codeRange library hls-code-range-plugin import: defaults, pedantic, warnings - if !flag(codeRange) + if !flag(codeRange) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.CodeRange @@ -1155,7 +1152,7 @@ library hls-code-range-plugin test-suite hls-code-range-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(codeRange) + if !flag(codeRange) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-code-range-plugin/test @@ -1185,13 +1182,13 @@ flag changeTypeSignature manual: True common changeTypeSignature - if flag(changeTypeSignature) + if flag(changeTypeSignature) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-change-type-signature-plugin cpp-options: -Dhls_changeTypeSignature library hls-change-type-signature-plugin import: defaults, pedantic, warnings - if !flag(changeTypeSignature) + if !flag(changeTypeSignature) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.ChangeTypeSignature hs-source-dirs: plugins/hls-change-type-signature-plugin/src @@ -1214,7 +1211,7 @@ library hls-change-type-signature-plugin test-suite hls-change-type-signature-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(changeTypeSignature) + if !flag(changeTypeSignature) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-change-type-signature-plugin/test @@ -1240,13 +1237,13 @@ flag gadt manual: True common gadt - if flag(gadt) + if flag(gadt) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-gadt-plugin cpp-options: -Dhls_gadt library hls-gadt-plugin import: defaults, pedantic, warnings - if !flag(gadt) + if !flag(gadt) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.GADT other-modules: Ide.Plugin.GHC @@ -1271,7 +1268,7 @@ library hls-gadt-plugin test-suite hls-gadt-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(gadt) + if !flag(gadt) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-gadt-plugin/test @@ -1293,13 +1290,13 @@ flag explicitFixity manual: True common explicitFixity - if flag(explicitFixity) + if flag(explicitFixity) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-explicit-fixity-plugin cpp-options: -DexplicitFixity library hls-explicit-fixity-plugin import: defaults, pedantic, warnings - if !flag(explicitFixity) + if !flag(explicitFixity) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.ExplicitFixity hs-source-dirs: plugins/hls-explicit-fixity-plugin/src @@ -1318,7 +1315,7 @@ library hls-explicit-fixity-plugin test-suite hls-explicit-fixity-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(explicitFixity) + if !flag(explicitFixity) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-explicit-fixity-plugin/test @@ -1340,13 +1337,13 @@ flag explicitFields manual: True common explicitFields - if flag(explicitFields) + if flag(explicitFields) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-explicit-record-fields-plugin cpp-options: -DexplicitFields library hls-explicit-record-fields-plugin import: defaults, pedantic, warnings - if !flag(explicitFields) + if !flag(explicitFields) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.ExplicitFields build-depends: @@ -1368,7 +1365,7 @@ library hls-explicit-record-fields-plugin test-suite hls-explicit-record-fields-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(explicitFields) + if !flag(explicitFields) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-explicit-record-fields-plugin/test @@ -1391,13 +1388,13 @@ flag overloadedRecordDot manual: True common overloadedRecordDot - if flag(overloadedRecordDot) + if flag(overloadedRecordDot) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-overloaded-record-dot-plugin cpp-options: -Dhls_overloaded_record_dot library hls-overloaded-record-dot-plugin import: defaults, pedantic, warnings - if !flag(overloadedRecordDot) + if !flag(overloadedRecordDot) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.OverloadedRecordDot build-depends: @@ -1417,7 +1414,7 @@ library hls-overloaded-record-dot-plugin test-suite hls-overloaded-record-dot-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(overloadedRecordDot) + if !flag(overloadedRecordDot) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-overloaded-record-dot-plugin/test @@ -1484,13 +1481,13 @@ flag fourmolu manual: True common fourmolu - if flag(fourmolu) + if flag(fourmolu) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-fourmolu-plugin cpp-options: -Dhls_fourmolu library hls-fourmolu-plugin import: defaults, pedantic, warnings - if !flag(fourmolu) + if !flag(fourmolu) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.Fourmolu hs-source-dirs: plugins/hls-fourmolu-plugin/src @@ -1511,7 +1508,7 @@ library hls-fourmolu-plugin test-suite hls-fourmolu-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(fourmolu) + if !flag(fourmolu) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-fourmolu-plugin/test @@ -1540,13 +1537,13 @@ flag ormolu manual: True common ormolu - if flag(ormolu) + if flag(ormolu) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-ormolu-plugin cpp-options: -Dhls_ormolu library hls-ormolu-plugin import: defaults, pedantic, warnings - if !flag(ormolu) + if !flag(ormolu) || impl(ghc > 9.11) buildable: False exposed-modules: Ide.Plugin.Ormolu hs-source-dirs: plugins/hls-ormolu-plugin/src @@ -1567,7 +1564,7 @@ library hls-ormolu-plugin test-suite hls-ormolu-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(ormolu) + if !flag(ormolu) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-ormolu-plugin/test @@ -1644,13 +1641,13 @@ flag refactor manual: True common refactor - if flag(refactor) + if flag(refactor) && impl(ghc < 9.11) build-depends: haskell-language-server:hls-refactor-plugin cpp-options: -Dhls_refactor library hls-refactor-plugin import: defaults, pedantic, warnings - if !flag(refactor) + if !flag(refactor) || impl(ghc > 9.11) buildable: False exposed-modules: Development.IDE.GHC.ExactPrint Development.IDE.GHC.Compat.ExactPrint @@ -1710,7 +1707,7 @@ library hls-refactor-plugin test-suite hls-refactor-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(refactor) + if !flag(refactor) || impl(ghc > 9.11) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-refactor-plugin/test @@ -1747,13 +1744,13 @@ flag semanticTokens manual: True common semanticTokens - if flag(semanticTokens) + if flag(semanticTokens) && impl(ghc < 9.13) build-depends: haskell-language-server:hls-semantic-tokens-plugin cpp-options: -Dhls_semanticTokens library hls-semantic-tokens-plugin import: defaults, pedantic, warnings - if !flag(semanticTokens) + if !flag(semanticTokens) || impl(ghc > 9.13) buildable: False exposed-modules: Ide.Plugin.SemanticTokens @@ -1781,6 +1778,7 @@ library hls-semantic-tokens-plugin , transformers , bytestring , syb + , time , array , deepseq , dlist @@ -1794,7 +1792,7 @@ library hls-semantic-tokens-plugin test-suite hls-semantic-tokens-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(semanticTokens) + if !flag(semanticTokens) || impl(ghc > 9.13) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-semantic-tokens-plugin/test @@ -1826,13 +1824,13 @@ flag notes manual: True common notes - if flag(notes) + if flag(notes) && impl(ghc < 9.13) build-depends: haskell-language-server:hls-notes-plugin cpp-options: -Dhls_notes library hls-notes-plugin import: defaults, pedantic, warnings - if !flag(notes) + if !flag(notes) || impl(ghc > 9.13) buildable: False exposed-modules: Ide.Plugin.Notes @@ -1860,7 +1858,7 @@ library hls-notes-plugin test-suite hls-notes-plugin-tests import: defaults, pedantic, test-defaults, warnings - if !flag(notes) + if !flag(notes) || impl(ghc > 9.13) buildable: False type: exitcode-stdio-1.0 hs-source-dirs: plugins/hls-notes-plugin/test @@ -2063,14 +2061,14 @@ test-suite func-test default-extensions: OverloadedStrings -- Duplicating inclusion plugin conditions until tests are moved to their own packages - if flag(eval) + if flag(eval) && impl(ghc < 9.11) cpp-options: -Dhls_eval -- formatters if flag(floskell) && impl(ghc < 9.10) cpp-options: -Dhls_floskell - if flag(fourmolu) + if flag(fourmolu) && impl(ghc < 9.11) cpp-options: -Dhls_fourmolu - if flag(ormolu) + if flag(ormolu) && impl(ghc < 9.11) cpp-options: -Dhls_ormolu test-suite wrapper-test @@ -2093,6 +2091,8 @@ test-suite wrapper-test benchmark benchmark import: defaults, warnings + if impl(ghc > 9.11) + buildable: False -- Depends on shake-bench which is unbuildable after this point type: exitcode-stdio-1.0 ghc-options: -threaded diff --git a/hie-compat/hie-compat.cabal b/hie-compat/hie-compat.cabal index bb96ab88fb..2b361df887 100644 --- a/hie-compat/hie-compat.cabal +++ b/hie-compat/hie-compat.cabal @@ -24,7 +24,7 @@ source-repository head library default-language: GHC2021 build-depends: - base < 4.21, array, bytestring, containers, directory, filepath, transformers + base < 4.22, array, bytestring, containers, directory, filepath, transformers build-depends: ghc >= 8.10, ghc-boot ghc-options: -Wall -Wno-name-shadowing diff --git a/plugins/hls-call-hierarchy-plugin/test/Main.hs b/plugins/hls-call-hierarchy-plugin/test/Main.hs index f356a0e278..5eed229c98 100644 --- a/plugins/hls-call-hierarchy-plugin/test/Main.hs +++ b/plugins/hls-call-hierarchy-plugin/test/Main.hs @@ -114,13 +114,13 @@ prepareCallHierarchyTests = [ testCase "1" $ do let contents = T.unlines ["{-# LANGUAGE TypeFamilies #-}", "data family A"] -- Since GHC 9.10 the range also includes the family name (and its parameters if any) - range = mkRange 1 0 1 (if ghcVersion == GHC910 then 13 else 11) + range = mkRange 1 0 1 (if ghcVersion `elem` [GHC912, GHC910] then 13 else 11) selRange = mkRange 1 12 1 13 expected = mkCallHierarchyItemT "A" SymbolKind_Function range selRange oneCaseWithCreate contents 1 12 expected , testCase "2" $ do let contents = T.unlines [ "{-# LANGUAGE TypeFamilies #-}" , "data family A a"] - range = mkRange 1 0 1 (if ghcVersion == GHC910 then 15 else 11) + range = mkRange 1 0 1 (if ghcVersion `elem` [GHC912, GHC910] then 15 else 11) selRange = mkRange 1 12 1 13 expected = mkCallHierarchyItemT "A" SymbolKind_Function range selRange oneCaseWithCreate contents 1 12 expected diff --git a/plugins/hls-class-plugin/src/Ide/Plugin/Class/Types.hs b/plugins/hls-class-plugin/src/Ide/Plugin/Class/Types.hs index 18c9dbae26..62fbe62a19 100644 --- a/plugins/hls-class-plugin/src/Ide/Plugin/Class/Types.hs +++ b/plugins/hls-class-plugin/src/Ide/Plugin/Class/Types.hs @@ -221,5 +221,5 @@ getInstanceBindTypeSigsRule recorder = do let name = idName id whenMaybe (isBindingName name) $ do env <- tcInitTidyEnv - let (_, ty) = tidyOpenType env (idType id) + let ty = tidyOpenType env (idType id) pure $ InstanceBindTypeSig name ty diff --git a/plugins/hls-semantic-tokens-plugin/src/Ide/Plugin/SemanticTokens/Tokenize.hs b/plugins/hls-semantic-tokens-plugin/src/Ide/Plugin/SemanticTokens/Tokenize.hs index 2ed11be333..15f3930b08 100644 --- a/plugins/hls-semantic-tokens-plugin/src/Ide/Plugin/SemanticTokens/Tokenize.hs +++ b/plugins/hls-semantic-tokens-plugin/src/Ide/Plugin/SemanticTokens/Tokenize.hs @@ -20,7 +20,17 @@ import qualified Data.Text.Rope as Char import qualified Data.Text.Utf16.Rope as Utf16 import Data.Text.Utf16.Rope.Mixed (Rope) import qualified Data.Text.Utf16.Rope.Mixed as Rope -import Development.IDE.GHC.Compat +import Development.IDE.GHC.Compat (HieAST (nodeChildren, nodeSpan, sourcedNodeInfo), + Identifier, + NodeInfo (NodeInfo), + NodeOrigin (SourceInfo), + RealSrcLoc, RealSrcSpan, + SourcedNodeInfo (getSourcedNodeInfo), + nameOccName, occNameString, + realSrcSpanEnd, + realSrcSpanStart, srcLocCol, + srcLocLine, srcSpanEndLine, + srcSpanStartLine) import Development.IDE.GHC.Error (realSrcSpanToCodePointRange) import Ide.Plugin.SemanticTokens.Types (HsSemanticTokenType (TModule), RangeHsSemanticTokenTypes (..)) diff --git a/plugins/hls-semantic-tokens-plugin/test/SemanticTokensTest.hs b/plugins/hls-semantic-tokens-plugin/test/SemanticTokensTest.hs index eacd47e2d2..3a2e553b44 100644 --- a/plugins/hls-semantic-tokens-plugin/test/SemanticTokensTest.hs +++ b/plugins/hls-semantic-tokens-plugin/test/SemanticTokensTest.hs @@ -10,7 +10,7 @@ import Data.Functor (void) import qualified Data.List as T import Data.Map.Strict as Map hiding (map) import Data.String (fromString) -import Data.Text hiding (length, map, +import Data.Text hiding (length, map, show, unlines) import qualified Data.Text as Text import qualified Data.Text.Utf16.Rope.Mixed as Rope diff --git a/shake-bench/shake-bench.cabal b/shake-bench/shake-bench.cabal index eccd84edeb..c381089aba 100644 --- a/shake-bench/shake-bench.cabal +++ b/shake-bench/shake-bench.cabal @@ -16,6 +16,8 @@ source-repository head location: https://github.com/haskell/haskell-language-server.git library + if impl(ghc > 9.11) + buildable: False exposed-modules: Development.Benchmark.Rules hs-source-dirs: src build-depends: