1
1
{-# LANGUAGE ConstraintKinds #-}
2
+ {-# LANGUAGE GADTs #-}
2
3
{-# LANGUAGE ExistentialQuantification #-}
3
4
{-# LANGUAGE ImplicitParams #-}
4
5
{-# LANGUAGE ImpredicativeTypes #-}
6
+ {-# OPTIONS_GHC -Wno-deprecations -Wno-unticked-promoted-constructors #-}
5
7
6
8
module Experiments
7
9
( Bench (.. )
@@ -20,19 +22,19 @@ module Experiments
20
22
, exampleToOptions
21
23
) where
22
24
import Control.Applicative.Combinators (skipManyTill )
23
- import Control.Exception.Safe
25
+ import Control.Exception.Safe ( IOException , handleAny , try )
24
26
import Control.Monad.Extra
25
27
import Control.Monad.IO.Class
26
- import Data.Aeson (Value (Null ))
28
+ import Data.Aeson (Value (Null ), toJSON )
27
29
import Data.List
28
30
import Data.Maybe
29
31
import qualified Data.Text as T
30
32
import Data.Version
31
33
import Development.IDE.Plugin.Test
32
34
import Experiments.Types
33
- import Language.Haskell. LSP.Test
34
- import Language.Haskell. LSP.Types
35
- import Language.Haskell. LSP.Types.Capabilities
35
+ import Language.LSP.Test
36
+ import Language.LSP.Types
37
+ import Language.LSP.Types.Capabilities
36
38
import Numeric.Natural
37
39
import Options.Applicative
38
40
import System.Directory
@@ -41,6 +43,7 @@ import System.FilePath ((</>), (<.>))
41
43
import System.Process
42
44
import System.Time.Extra
43
45
import Text.ParserCombinators.ReadP (readP_to_S )
46
+ import Development.Shake (cmd_ , CmdOption (Cwd , FileStdout ))
44
47
45
48
charEdit :: Position -> TextDocumentContentChangeEvent
46
49
charEdit p =
@@ -78,13 +81,13 @@ experiments =
78
81
isJust <$> getHover doc (fromJust identifierP),
79
82
---------------------------------------------------------------------------------------
80
83
bench " getDefinition" $ allWithIdentifierPos $ \ DocumentPositions {.. } ->
81
- not . null <$> getDefinitions doc (fromJust identifierP),
84
+ either ( not . null ) ( not . null ) . toEither <$> getDefinitions doc (fromJust identifierP),
82
85
---------------------------------------------------------------------------------------
83
86
bench " getDefinition after edit" $ \ docs -> do
84
87
forM_ docs $ \ DocumentPositions {.. } ->
85
88
changeDoc doc [charEdit stringLiteralP]
86
89
flip allWithIdentifierPos docs $ \ DocumentPositions {.. } ->
87
- not . null <$> getDefinitions doc (fromJust identifierP),
90
+ either ( not . null ) ( not . null ) . toEither <$> getDefinitions doc (fromJust identifierP),
88
91
---------------------------------------------------------------------------------------
89
92
bench " documentSymbols" $ allM $ \ DocumentPositions {.. } -> do
90
93
fmap (either (not . null ) (not . null )) . getDocumentSymbols $ doc,
@@ -147,7 +150,7 @@ experiments =
147
150
( \ docs -> do
148
151
Just hieYaml <- uriToFilePath <$> getDocUri " hie.yaml"
149
152
liftIO $ appendFile hieYaml " ##\n "
150
- sendNotification WorkspaceDidChangeWatchedFiles $ DidChangeWatchedFilesParams $
153
+ sendNotification SWorkspaceDidChangeWatchedFiles $ DidChangeWatchedFilesParams $
151
154
List [ FileEvent (filePathToUri " hie.yaml" ) FcChanged ]
152
155
forM_ docs $ \ DocumentPositions {.. } ->
153
156
changeDoc doc [charEdit stringLiteralP]
@@ -162,7 +165,7 @@ experiments =
162
165
(\ docs -> do
163
166
Just hieYaml <- uriToFilePath <$> getDocUri " hie.yaml"
164
167
liftIO $ appendFile hieYaml " ##\n "
165
- sendNotification WorkspaceDidChangeWatchedFiles $ DidChangeWatchedFilesParams $
168
+ sendNotification SWorkspaceDidChangeWatchedFiles $ DidChangeWatchedFilesParams $
166
169
List [ FileEvent (filePathToUri " hie.yaml" ) FcChanged ]
167
170
flip allWithIdentifierPos docs $ \ DocumentPositions {.. } -> isJust <$> getHover doc (fromJust identifierP)
168
171
)
@@ -358,7 +361,9 @@ waitForProgressDone :: Session ()
358
361
waitForProgressDone = loop
359
362
where
360
363
loop = do
361
- void (skipManyTill anyMessage message :: Session WorkDoneProgressEndNotification )
364
+ ~ () <- skipManyTill anyMessage $ satisfyMaybe $ \ case
365
+ FromServerMess SProgress (NotificationMessage _ _ (ProgressParams _ (End _))) -> Just ()
366
+ _ -> Nothing
362
367
done <- null <$> getIncompleteProgressSessions
363
368
unless done loop
364
369
@@ -392,8 +397,9 @@ runBench runSess b = handleAny (\e -> print e >> return badRun)
392
397
else do
393
398
output (showDuration t)
394
399
-- Wait for the delayed actions to finish
395
- waitId <- sendRequest (CustomClientMethod " test" ) WaitForShakeQueue
396
- (td, resp) <- duration $ skipManyTill anyMessage $ responseForId waitId
400
+ let m = SCustomMethod " test"
401
+ waitId <- sendRequest m (toJSON WaitForShakeQueue )
402
+ (td, resp) <- duration $ skipManyTill anyMessage $ responseForId m waitId
397
403
case resp of
398
404
ResponseMessage {_result= Right Null } -> do
399
405
loop (userWaits+ t) (delayedWork+ td) (n - 1 )
@@ -423,19 +429,24 @@ setup :: HasConfig => IO SetupResult
423
429
setup = do
424
430
-- when alreadyExists $ removeDirectoryRecursive examplesPath
425
431
benchDir <- case example ? config of
426
- UsePackage {.. } -> return examplePath
432
+ UsePackage {.. } -> do
433
+ let hieYamlPath = examplePath </> " hie.yaml"
434
+ alreadyExists <- doesFileExist hieYamlPath
435
+ unless alreadyExists $
436
+ cmd_ (Cwd examplePath) (FileStdout hieYamlPath) (" gen-hie" :: String )
437
+ return examplePath
427
438
GetPackage {.. } -> do
428
439
let path = examplesPath </> package
429
440
package = exampleName <> " -" <> showVersion exampleVersion
441
+ hieYamlPath = path </> " hie.yaml"
430
442
alreadySetup <- doesDirectoryExist path
431
443
unless alreadySetup $
432
444
case buildTool ? config of
433
445
Cabal -> do
434
446
let cabalVerbosity = " -v" ++ show (fromEnum (verbose ? config))
435
447
callCommandLogging $ " cabal get " <> cabalVerbosity <> " " <> package <> " -d " <> examplesPath
436
- writeFile
437
- (path </> " hie.yaml" )
438
- (" cradle: {cabal: {component: " <> exampleName <> " }}" )
448
+ let hieYamlPath = path </> " hie.yaml"
449
+ cmd_ (Cwd path) (FileStdout hieYamlPath) (" gen-hie" :: String )
439
450
-- Need this in case there is a parent cabal.project somewhere
440
451
writeFile
441
452
(path </> " cabal.project" )
@@ -464,9 +475,7 @@ setup = do
464
475
]
465
476
)
466
477
467
- writeFile
468
- (path </> " hie.yaml" )
469
- (" cradle: {stack: {component: " <> show (exampleName <> " :lib" ) <> " }}" )
478
+ cmd_ (Cwd path) (FileStdout hieYamlPath) (" gen-hie" :: String ) [" --stack" :: String ]
470
479
return path
471
480
472
481
whenJust (shakeProfiling ? config) $ createDirectoryIfMissing True
@@ -498,22 +507,21 @@ setupDocumentContents config =
498
507
499
508
-- Find an identifier defined in another file in this project
500
509
symbols <- getDocumentSymbols doc
501
- case symbols of
502
- Left [DocumentSymbol {_children = Just (List symbols)}] -> do
503
- let endOfImports = case symbols of
504
- DocumentSymbol {_kind = SkModule , _name = " imports" , _range } : _ ->
505
- Position (succ $ _line $ _end _range) 4
506
- DocumentSymbol {_range} : _ -> _start _range
507
- [] -> error " Module has no symbols"
508
- contents <- documentContents doc
509
-
510
- identifierP <- searchSymbol doc contents endOfImports
511
-
512
- return $ DocumentPositions {.. }
513
- other ->
514
- error $ " symbols: " <> show other
515
-
516
-
510
+ let endOfImports = case symbols of
511
+ Left symbols | Just x <- findEndOfImports symbols -> x
512
+ _ -> error $ " symbols: " <> show symbols
513
+ contents <- documentContents doc
514
+ identifierP <- searchSymbol doc contents endOfImports
515
+ return $ DocumentPositions {.. }
516
+
517
+ findEndOfImports :: [DocumentSymbol ] -> Maybe Position
518
+ findEndOfImports (DocumentSymbol {_kind = SkModule , _name = " imports" , _range} : _) =
519
+ Just $ Position (succ $ _line $ _end _range) 4
520
+ findEndOfImports [DocumentSymbol {_kind = SkFile , _children = Just (List cc)}] =
521
+ findEndOfImports cc
522
+ findEndOfImports (DocumentSymbol {_range} : _) =
523
+ Just $ _start _range
524
+ findEndOfImports _ = Nothing
517
525
518
526
--------------------------------------------------------------------------------------------
519
527
@@ -559,7 +567,7 @@ searchSymbol doc@TextDocumentIdentifier{_uri} fileContents pos = do
559
567
checkDefinitions pos = do
560
568
defs <- getDefinitions doc pos
561
569
case defs of
562
- [Location uri _] -> return $ uri /= _uri
570
+ ( InL [Location uri _]) -> return $ uri /= _uri
563
571
_ -> return False
564
572
checkCompletions pos =
565
573
not . null <$> getCompletions doc pos
0 commit comments