Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix broken pipe during test and gracefully exit the server #4701

New issue

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

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

Already on GitHub? Sign in to your account

Open
soulomoon wants to merge 64 commits into master
base: master
Choose a base branch
Loading
from 1875-tests-randomly-fail-with-exception-fd111-hputbuf-resource-vanished-broken-pipe---test-option-j1-workaround
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
ae3a5f1
Fix broken pip during test
soulomoon Aug 21, 2025
cd83664
Consolidate source-repository-package entries in cabal.project
soulomoon Aug 21, 2025
c7ad3a2
Add flakiness testing workflow
soulomoon Aug 21, 2025
4d56b39
Update flakiness workflow and fix exit codes in open-close loop script
soulomoon Aug 21, 2025
9272de3
Update lsp repository tag in cabal.project
soulomoon Aug 22, 2025
e1a7947
Update flakiness.yml
soulomoon Aug 22, 2025
ed85d9b
Add InitParameters data type and enhance shutdown handling in Languag...
soulomoon Aug 22, 2025
100b39e
Rename InitParameters to InitializationContext and update related fie...
soulomoon Aug 22, 2025
5835ad7
Increase default maximum iterations to 1000 in flakiness workflow
soulomoon Aug 22, 2025
d26ed7f
Update cabal.project and LanguageServer for improved logging and upda...
soulomoon Aug 22, 2025
c0f6a9b
Merge branch 'master' into 1875-tests-randomly-fail-with-exception-fd...
soulomoon Aug 22, 2025
1f9cb02
Update lsp repository tag to latest commit
soulomoon Aug 22, 2025
c72d2e7
Improve log message for server exit and simplify test failure detecti...
soulomoon Aug 22, 2025
569d766
Fix flakiness test
soulomoon Aug 22, 2025
cb67ec5
Set default max_iter value to 1000 in flakiness test workflow
soulomoon Aug 22, 2025
56bc03b
Refactor logging in open-close loop script to improve iteration outpu...
soulomoon Aug 22, 2025
9f24f2e
Fix exit codes for broken pipe and test failure detection in open-clo...
soulomoon Aug 22, 2025
8eb7bb5
Refactor flakiness testing workflow: replace open-close loop script w...
soulomoon Aug 23, 2025
d233023
Update lsp repository tag to a447a4f
soulomoon Aug 24, 2025
fe7421e
Update cabal.project
soulomoon Aug 24, 2025
7bf694a
update CI
soulomoon Aug 24, 2025
8c17daa
Update reactor shutdown logging, and improve shutdown handling
soulomoon Aug 24, 2025
6907be0
update flaky-test-loop script
soulomoon Aug 26, 2025
0851914
update lsp rev
soulomoon Aug 26, 2025
7900d71
Use a TMVar as a stop flag to coordinate graceful shutdown.
soulomoon Aug 26, 2025
8c50e74
restore
soulomoon Aug 26, 2025
54e334b
restore
soulomoon Aug 26, 2025
d1b6d55
update CI
soulomoon Aug 26, 2025
53a6162
update test
soulomoon Aug 26, 2025
a26922c
Remove comment markers from flaky test patterns for clarity
soulomoon Aug 26, 2025
d10cf47
Remove pattern_file input and use default pattern file for flakiness ...
soulomoon Aug 26, 2025
b36f8a6
Replace writeFile and writeFileUTF8 with atomicFileWriteString and at...
soulomoon Aug 26, 2025
15cd44a
Refactor flaky test loop script for improved build handling and error...
soulomoon Aug 28, 2025
ed1c20c
Update lsp
soulomoon Aug 28, 2025
53c4536
format
soulomoon Aug 28, 2025
a9fa00d
Enhance testing workflow and progress reporting
soulomoon Aug 28, 2025
6e50414
Simplify build step in flakiness workflow to compile all tests
soulomoon Aug 28, 2025
1097ce6
Add HLS test executables to flakiness workflow environment
soulomoon Aug 28, 2025
afb4328
Update flakiness workflow to dynamically locate HLS executable
soulomoon Aug 28, 2025
5384ea7
Refactor flakiness workflow to streamline HLS test execution command
soulomoon Aug 28, 2025
bffdb6a
Replace waitForAllProgressDone with waitForKickDone in resolveRequest...
soulomoon Aug 28, 2025
d07c06f
always send progress
soulomoon Aug 29, 2025
7ad628e
update lsp
soulomoon Aug 29, 2025
b962e1f
increase timeout for flakiness
soulomoon Aug 29, 2025
c3758fa
update number of runs to 500 for flakiness
soulomoon Aug 29, 2025
b313fd0
update CI
soulomoon Aug 30, 2025
84f7d35
Add AsyncParentKill exception handling and improve database step retr...
soulomoon Aug 30, 2025
9788101
fix bench
soulomoon Aug 30, 2025
a87d1c2
fix import
soulomoon Aug 30, 2025
66dc235
fix compilation
soulomoon Aug 30, 2025
8483c7b
add event log
soulomoon Aug 31, 2025
969bce9
workaround hlint bug
soulomoon Sep 5, 2025
8f37e25
enforce build state changes
soulomoon Sep 5, 2025
08350aa
Merge remote-tracking branch 'upstream/master' into 1875-tests-random...
soulomoon Sep 5, 2025
773bfee
new hls-graph runtime
soulomoon Sep 5, 2025
b771ed2
update script
soulomoon Sep 6, 2025
f0ae0ee
Merge remote-tracking branch 'upstream/master' into 1875-tests-random...
soulomoon Sep 6, 2025
08e7a8a
Revert "new hls-graph runtime"
soulomoon Sep 6, 2025
075b742
revert hls-graph changes
soulomoon Sep 6, 2025
767ca29
fix build
soulomoon Sep 6, 2025
73ce412
revert test CI changes
soulomoon Sep 6, 2025
42bbfbe
Refactor flakiness workflow and CI
soulomoon Sep 7, 2025
81c46b6
clean up and revert other flakiness test changes
soulomoon Sep 18, 2025
405ea59
cleanup
soulomoon Sep 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions .github/workflows/flakiness.yml
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
name: flakiness

defaults:
run:
shell: bash

concurrency:
group: ${{ github.head_ref }}-${{ github.workflow }}
cancel-in-progress: true

on:
# Run on PRs that touch relevant areas and on manual dispatch
pull_request:
branches:
- '**'
paths:
- 'scripts/flaky-test-loop.sh'
- 'scripts/flaky-test-patterns.txt'
- 'ghcide/**'
- 'ghcide-test/**'
- 'hls-test-utils/**'
- 'src/**'
- 'exe/**'
- 'plugins/**'
- 'cabal.project'
- 'stack.yaml'
- 'haskell-language-server.cabal'
- '.github/workflows/flakiness.yml'
workflow_dispatch:
inputs:
max_iter:
description: 'Maximum iterations to attempt'
required: false
default: '1000'
sleep_secs:
description: 'Seconds to sleep between iterations'
required: false
default: '0'
test_patterns:
description: 'Comma-separated Tasty patterns to run each iteration (overrides default)'
required: false
default: ''

jobs:
loop:
name: Flakiness Test (broken pipe and test failures)
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
# - windows-latest

steps:
- uses: actions/checkout@v4

- name: Setup GHC and caching
uses: ./.github/actions/setup-build
with:
ghc: '9.12'
os: ${{ runner.os }}

- name: Show cabal and GHC versions
run: |
cabal --version
ghc --version
- name: Build
env:
PATTERN_FILE: 'scripts/flaky-test-patterns.txt'
RUN_MODE: 'build'
run: HLS_TEST_EXE="$(cabal exec which hls)" bash scripts/flaky-test-loop.sh

- name: Run flakiness loop
id: run-loop
# Let this run for a while; build is done once inside the script
timeout-minutes: 60
env:
# Use workflow_dispatch inputs when present, else defaults
SLEEP_SECS: ${{ github.event.inputs.sleep_secs || '0' }}
LOG_STDERR: '1'
TEST_PATTERNS: ${{ github.event.inputs.test_patterns }}
PATTERN_FILE: 'scripts/flaky-test-patterns.txt'
NO_BUILD_ONCE: '1'
RUN_MODE: 'run'
# HLS_TEST_EXE: 'hls' # HLS_WRAPPER_TEST_EXE: 'hls-wrapper'
run: |
# Run with a sensible default of 500 iterations on PRs;
max_iter="${{ github.event.inputs.max_iter }}"
max_iter="${max_iter:-500}"
# copy hls to current dir so the script can find it
HLS_TEST_EXE="$(cabal exec which hls)" bash scripts/flaky-test-loop.sh "${max_iter}"
ec=$?
# Interpret exit codes from flaky-test-loop.sh
# 0 => no issues reproduced within MAX_ITER -> pass job
# 1 => issue reproduced (broken pipe or test failure) -> fail job
# 2+ => setup/infra error -> fail job
if [[ $ec -eq 1 ]]; then
echo "Issue reproduced (broken pipe or test failure): failing job"
exit 1
elif [[ $ec -eq 0 ]]; then
echo "No issues reproduced within MAX_ITER=${max_iter}: passing"
exit 0
else
echo "Loop script error (exit $ec): failing"
exit $ec
fi

6 changes: 6 additions & 0 deletions cabal.project
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,9 @@ if impl(ghc >= 9.11)
allow-newer:
cabal-install-parsers:base,
cabal-install-parsers:time,

source-repository-package
type: git
location: https://github.com/soulomoon/lsp.git
tag: 640c7c755bf16128e3cb19c257688aa3305ff9f5
subdir: lsp lsp-types lsp-test
11 changes: 6 additions & 5 deletions ghcide/session-loader/Development/IDE/Session.hs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@
import qualified Data.Set as OS
import Database.SQLite.Simple
import Development.IDE.Core.Tracing (withTrace)
import Development.IDE.Core.WorkerThread (awaitRunInThread,
withWorkerQueue)
import Development.IDE.Core.WorkerThread
import qualified Development.IDE.GHC.Compat.Util as Compat
import Development.IDE.Session.Diagnostics (renderCradleError)
import Development.IDE.Types.Shake (WithHieDb,
Expand Down Expand Up @@ -149,10 +148,12 @@
| LogNewComponentCache !(([FileDiagnostic], Maybe HscEnvEq), DependencyInfo)
| LogHieBios HieBios.Log
| LogSessionLoadingChanged
| LogSessionWorkerThread LogWorkerThread
deriving instance Show Log

instance Pretty Log where
pretty = \case
LogSessionWorkerThread msg -> pretty msg
LogNoneCradleFound path ->
"None cradle found for" <+> pretty path <+> ", ignoring the file"
LogSettingInitialDynFlags ->
Expand Down Expand Up @@ -381,8 +382,8 @@
_ <- withWriteDbRetryable deleteMissingRealFiles
_ <- withWriteDbRetryable garbageCollectTypeNames

runContT (withWorkerQueue (writer withWriteDbRetryable)) $ \chan ->
withHieDb fp (\readDb -> k (WithHieDbShield $ makeWithHieDbRetryable recorder rng readDb, chan))
runContT (withWorkerQueue (cmapWithPrio LogSessionWorkerThread recorder) "hiedb thread" (writer withWriteDbRetryable))
$ \chan -> withHieDb fp (\readDb -> k (WithHieDbShield $ makeWithHieDbRetryable recorder rng readDb, chan))
where
writer withHieDbRetryable l = do
-- TODO: probably should let exceptions be caught/logged/handled by top level handler
Expand Down Expand Up @@ -415,7 +416,7 @@
-- components mapping to the same hie.yaml file are mapped to the same
-- HscEnv which is updated as new components are discovered.

loadSessionWithOptions :: Recorder (WithPriority Log) -> SessionLoadingOptions -> FilePath -> TQueue (IO ()) -> IO (Action IdeGhcSession)
loadSessionWithOptions :: Recorder (WithPriority Log) -> SessionLoadingOptions -> FilePath -> TaskQueue (IO ()) -> IO (Action IdeGhcSession)
loadSessionWithOptions recorder SessionLoadingOptions{..} rootDir que = do
let toAbsolutePath = toAbsolute rootDir -- see Note [Root Directory]
cradle_files <- newIORef []
Expand Down Expand Up @@ -629,7 +630,7 @@
[] -> error $ "GHC version could not be parsed: " <> version
((runTime, _):_)
| compileTime == runTime -> do
atomicModifyIORef' cradle_files (\xs -> (cfp:xs,()))

Check warning on line 633 in ghcide/session-loader/Development/IDE/Session.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Warning in loadSessionWithOptions in module Development.IDE.Session: Use atomicModifyIORef'_ ▫︎ Found: "atomicModifyIORef' cradle_files (\\ xs -> (cfp : xs, ()))" ▫︎ Perhaps: "atomicModifyIORef'_ cradle_files ((:) cfp)"
session (hieYaml, toNormalizedFilePath' cfp, opts, libDir)
| otherwise -> return (([renderPackageSetupException cfp GhcVersionMismatch{..}], Nothing),[])
-- Failure case, either a cradle error or the none cradle
Expand Down Expand Up @@ -896,7 +897,7 @@
x <- map errMsgDiagnostic closure_errs
DriverHomePackagesNotClosed us <- pure x
pure us
isBad ci = (homeUnitId_ (componentDynFlags ci)) `OS.member` bad_units

Check warning on line 900 in ghcide/session-loader/Development/IDE/Session.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Suggestion in newComponentCache in module Development.IDE.Session: Redundant bracket ▫︎ Found: "(homeUnitId_ (componentDynFlags ci)) `OS.member` bad_units" ▫︎ Perhaps: "homeUnitId_ (componentDynFlags ci) `OS.member` bad_units"
-- Whenever we spin up a session on Linux, dynamically load libm.so.6
-- in. We need this in case the binary is statically linked, in which
-- case the interactive session will fail when trying to load
Expand Down
3 changes: 2 additions & 1 deletion ghcide/src/Development/IDE/Core/Compile.hs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@
import Data.Time (UTCTime (..))
import Data.Tuple.Extra (dupe)
import Debug.Trace
import Development.IDE.Core.FileStore (resetInterfaceStore)

Check warning on line 73 in ghcide/src/Development/IDE/Core/Compile.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Warning in module Development.IDE.Core.Compile: Use fewer imports ▫︎ Found: "import Development.IDE.Core.FileStore ( resetInterfaceStore )\nimport Development.IDE.Core.FileStore ( shareFilePath )\n" ▫︎ Perhaps: "import Development.IDE.Core.FileStore\n ( resetInterfaceStore, shareFilePath )\n"
import Development.IDE.Core.Preprocessor
import Development.IDE.Core.ProgressReporting (progressUpdate)
import Development.IDE.Core.RuleTypes
import Development.IDE.Core.Shake
import Development.IDE.Core.WorkerThread (writeTaskQueue)
import Development.IDE.Core.Tracing (withTrace)
import qualified Development.IDE.GHC.Compat as Compat
import qualified Development.IDE.GHC.Compat as GHC
Expand Down Expand Up @@ -825,7 +826,7 @@
tcs = tcg_tcs ts :: [TyCon]
hie_asts = GHC.enrichHie all_binds (tmrRenamed tcm) top_ev_binds insts tcs

pure $ Just $

Check warning on line 829 in ghcide/src/Development/IDE/Core/Compile.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Suggestion in generateHieAsts in module Development.IDE.Core.Compile: Redundant $ ▫︎ Found: "Just $ hie_asts" ▫︎ Perhaps: "Just hie_asts"
#if MIN_VERSION_ghc(9,11,0)
hie_asts (tcg_type_env ts)
#else
Expand Down Expand Up @@ -882,7 +883,7 @@
-- hiedb doesn't use the Haskell src, so we clear it to avoid unnecessarily keeping it around
let !hf' = hf{hie_hs_src = mempty}
modifyTVar' indexPending $ HashMap.insert srcPath hash
writeTQueue indexQueue $ \withHieDb -> do
writeTaskQueue indexQueue $ \withHieDb -> do
-- We are now in the worker thread
-- Check if a newer index of this file has been scheduled, and if so skip this one
newerScheduled <- atomically $ do
Expand Down Expand Up @@ -1105,7 +1106,7 @@


convImport (L _ i) = (
(ideclPkgQual i)

Check warning on line 1109 in ghcide/src/Development/IDE/Core/Compile.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Suggestion in getModSummaryFromImports in module Development.IDE.Core.Compile: Redundant bracket ▫︎ Found: "((ideclPkgQual i), reLoc $ ideclName i)" ▫︎ Perhaps: "(ideclPkgQual i, reLoc $ ideclName i)"
, reLoc $ ideclName i)

msrImports = implicit_imports ++ imps
Expand Down
7 changes: 4 additions & 3 deletions ghcide/src/Development/IDE/Core/FileStore.hs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import Development.IDE.Core.IdeConfiguration (isWorkspaceFile)
import Development.IDE.Core.RuleTypes
import Development.IDE.Core.Shake hiding (Log)
import qualified Development.IDE.Core.Shake as Shake
import Development.IDE.Core.WorkerThread
import Development.IDE.GHC.Orphans ()
import Development.IDE.Graph
import Development.IDE.Import.DependencyInformation
Expand Down Expand Up @@ -252,8 +253,8 @@ getVersionedTextDoc doc = do
maybe (pure Nothing) getVirtualFile $
uriToNormalizedFilePath $ toNormalizedUri uri
let ver = case mvf of
Just (VirtualFile lspver _ _) -> lspver
Nothing -> 0
Just (VirtualFile lspver _ _ _) -> lspver
Nothing -> 0
return (VersionedTextDocumentIdentifier uri ver)

fileStoreRules :: Recorder (WithPriority Log) -> (NormalizedFilePath -> Action Bool) -> Rules ()
Expand Down Expand Up @@ -304,7 +305,7 @@ typecheckParentsAction recorder nfp = do
setSomethingModified :: VFSModified -> IdeState -> String -> IO [Key] -> IO ()
setSomethingModified vfs state reason actionBetweenSession = do
-- Update database to remove any files that might have been renamed/deleted
atomically $ writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) (\withHieDb -> withHieDb deleteMissingRealFiles)
atomically $ writeTaskQueue (indexQueue $ hiedbWriter $ shakeExtras state) (\withHieDb -> withHieDb deleteMissingRealFiles)
void $ restartShakeSession (shakeExtras state) vfs reason [] actionBetweenSession

registerFileWatches :: [String] -> LSP.LspT Config IO Bool
Expand Down
4 changes: 2 additions & 2 deletions ghcide/src/Development/IDE/Core/Rules.hs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -516,8 +516,8 @@
vfsRef <- asks vfsVar
vfsData <- liftIO $ _vfsMap <$> readTVarIO vfsRef
(currentSource, ver) <- liftIO $ case M.lookup (filePathToUri' file) vfsData of
Nothing -> (,Nothing) . T.decodeUtf8 <$> BS.readFile (fromNormalizedFilePath file)
Just vf -> pure (virtualFileText vf, Just $ virtualFileVersion vf)
Just (Open vf) -> pure (virtualFileText vf, Just $ virtualFileVersion vf)
_ -> (,Nothing) . T.decodeUtf8 <$> BS.readFile (fromNormalizedFilePath file)
let refmap = generateReferencesMap . getAsts . Compat.hie_asts $ res
del = deltaFromDiff (T.decodeUtf8 $ Compat.hie_hs_src res) currentSource
pure (HAR (Compat.hie_module res) (Compat.hie_asts res) refmap mempty (HieFromDisk res),del,ver)
Expand Down Expand Up @@ -809,7 +809,7 @@
{ source_version = ver
, old_value = m_old
, get_file_version = use GetModificationTime_{missingFileDiagnostics = False}
, get_linkable_hashes = \fs -> map (snd . fromJust . hirCoreFp) <$> uses_ GetModIface fs

Check warning on line 812 in ghcide/src/Development/IDE/Core/Rules.hs

View workflow job for this annotation

GitHub Actions / Hlint check run

Suggestion in getModIfaceFromDiskRule in module Development.IDE.Core.Rules: Use fmap ▫︎ Found: "\\ fs -> map (snd . fromJust . hirCoreFp) <$> uses_ GetModIface fs" ▫︎ Perhaps: "fmap (map (snd . fromJust . hirCoreFp)) . uses_ GetModIface"
, get_module_graph = useWithSeparateFingerprintRule_ GetModuleGraphTransDepsFingerprints GetModuleGraph f
, regenerate = regenerateHiFile session f ms
}
Expand Down
22 changes: 15 additions & 7 deletions ghcide/src/Development/IDE/Core/Shake.hs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module Development.IDE.Core.Shake(
IdeState, shakeSessionInit, shakeExtras, shakeDb, rootDir,
ShakeExtras(..), getShakeExtras, getShakeExtrasRules,
KnownTargets(..), Target(..), toKnownFiles, unionKnownTargets, mkKnownTargets,
IdeRule, IdeResult,
IdeRule, IdeResult, RestartQueue,
GetModificationTime(GetModificationTime, GetModificationTime_, missingFileDiagnostics),
shakeOpen, shakeShut,
shakeEnqueue,
Expand Down Expand Up @@ -254,12 +254,15 @@ data HieDbWriter
-- | Actions to queue up on the index worker thread
-- The inner `(HieDb -> IO ()) -> IO ()` wraps `HieDb -> IO ()`
-- with (currently) retry functionality
type IndexQueue = TQueue (((HieDb -> IO ()) -> IO ()) -> IO ())
type IndexQueue = TaskQueue (((HieDb -> IO ()) -> IO ()) -> IO ())
type RestartQueue = TaskQueue (IO ())
type LoaderQueue = TaskQueue (IO ())


data ThreadQueue = ThreadQueue {
tIndexQueue :: IndexQueue
, tRestartQueue :: TQueue (IO ())
, tLoaderQueue :: TQueue (IO ())
, tRestartQueue :: RestartQueue
, tLoaderQueue :: LoaderQueue
}

-- Note [Semantic Tokens Cache Location]
Expand Down Expand Up @@ -330,9 +333,9 @@ data ShakeExtras = ShakeExtras
-- ^ Default HLS config, only relevant if the client does not provide any Config
, dirtyKeys :: TVar KeySet
-- ^ Set of dirty rule keys since the last Shake run
, restartQueue :: TQueue (IO ())
, restartQueue :: RestartQueue
-- ^ Queue of restart actions to be run.
, loaderQueue :: TQueue (IO ())
, loaderQueue :: LoaderQueue
-- ^ Queue of loader actions to be run.
}

Expand Down Expand Up @@ -390,11 +393,16 @@ addPersistentRule k getVal = do

class Typeable a => IsIdeGlobal a where

-- data VirtualFileEntry = Open VirtualFile | Closed ClosedVirtualFile
getOpenFile :: VirtualFileEntry -> Maybe VirtualFile
getOpenFile (Open vf) = Just vf
getOpenFile _ = Nothing
-- | Read a virtual file from the current snapshot
getVirtualFile :: NormalizedFilePath -> Action (Maybe VirtualFile)
getVirtualFile nf = do
vfs <- fmap _vfsMap . liftIO . readTVarIO . vfsVar =<< getShakeExtras
pure $! Map.lookup (filePathToUri' nf) vfs -- Don't leak a reference to the entire map
let file = getOpenFile =<< Map.lookup (filePathToUri' nf) vfs
pure $! file -- Don't leak a reference to the entire map

-- Take a snapshot of the current LSP VFS
vfsSnapshot :: Maybe (LSP.LanguageContextEnv a) -> IO VFS
Expand Down
Loading
Loading

AltStyle によって変換されたページ (->オリジナル) /