Skip to content

Commit 094a883

Browse files
committed
support Agda 2.8.0 file management
1 parent 768f723 commit 094a883

File tree

6 files changed

+138
-47
lines changed

6 files changed

+138
-47
lines changed

agda-language-server.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ library
5050
Agda
5151
Agda.Convert
5252
Agda.Interaction.Imports.More
53+
Agda.Interaction.Imports.Virtual
5354
Agda.Interaction.Library.More
5455
Agda.IR
5556
Agda.Parser
@@ -198,6 +199,7 @@ test-suite als-test
198199
Agda
199200
Agda.Convert
200201
Agda.Interaction.Imports.More
202+
Agda.Interaction.Imports.Virtual
201203
Agda.Interaction.Library.More
202204
Agda.IR
203205
Agda.Parser

src/Agda/Interaction/Imports/More.hs

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
{-# LANGUAGE CPP #-}
22

33
module Agda.Interaction.Imports.More
4-
( parseVirtualSource,
5-
setOptionsFromSourcePragmas,
4+
( setOptionsFromSourcePragmas,
65
checkModuleName',
6+
runPMDropWarnings,
7+
moduleName,
8+
runPM,
9+
beginningOfFile,
710
)
811
where
912

@@ -93,38 +96,6 @@ import Agda.Utils.Singleton (singleton)
9396
import Agda.Syntax.Common.Pretty (pretty)
9497
#endif
9598

96-
-- | Parse a source file without talking to the filesystem
97-
parseVirtualSource ::
98-
-- | Logical path of the source file. Used in ranges, not filesystem access.
99-
SourceFile ->
100-
-- | Logical contents of the source file
101-
TL.Text ->
102-
TCM Imp.Source
103-
parseVirtualSource sourceFile source = Bench.billTo [Bench.Parsing] $ do
104-
f <- srcFilePath sourceFile
105-
let rf0 = mkRangeFile f Nothing
106-
setCurrentRange (beginningOfFile rf0) $ do
107-
parsedModName0 <- moduleName f . fst . fst =<< do
108-
runPMDropWarnings $ parseFile moduleParser rf0 $ TL.unpack source
109-
110-
let rf = mkRangeFile f $ Just parsedModName0
111-
((parsedMod, attrs), fileType) <- runPM $ parseFile moduleParser rf $ TL.unpack source
112-
parsedModName <- moduleName f parsedMod
113-
114-
-- TODO: handle libs properly
115-
let libs = []
116-
117-
return
118-
Source
119-
{ srcText = source,
120-
srcFileType = fileType,
121-
srcOrigin = sourceFile,
122-
srcModule = parsedMod,
123-
srcModuleName = parsedModName,
124-
srcProjectLibs = libs,
125-
srcAttributes = attrs
126-
}
127-
12899
srcFilePath :: SourceFile -> TCM AbsolutePath
129100
#if MIN_VERSION_Agda(2,8,0)
130101
srcFilePath = TCM.srcFilePath
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
{-# LANGUAGE CPP #-}
2+
{-# LANGUAGE FlexibleContexts #-}
3+
4+
module Agda.Interaction.Imports.Virtual
5+
( VSourceFile (..),
6+
vSrcFileId,
7+
vSrcFromUri,
8+
parseVSource,
9+
)
10+
where
11+
12+
#if MIN_VERSION_Agda(2,8,0)
13+
#else
14+
import Agda.Interaction.FindFile (SourceFile (SourceFile))
15+
#endif
16+
import qualified Agda.Interaction.Imports as Imp
17+
import qualified Agda.Interaction.Imports.More as Imp
18+
import Agda.Syntax.Parser (moduleParser, parseFile)
19+
import Agda.Syntax.Position (mkRangeFile)
20+
import qualified Agda.TypeChecking.Monad as TCM
21+
import Control.Monad.IO.Class (MonadIO)
22+
import Control.Monad.Trans (lift)
23+
import qualified Data.Strict as Strict
24+
import qualified Data.Text as Text
25+
import qualified Language.LSP.Protocol.Types as LSP
26+
import Language.LSP.Protocol.Types.Uri.More (uriToPossiblyInvalidAbsolutePath)
27+
import qualified Language.LSP.Server as LSP
28+
import qualified Language.LSP.VFS as VFS
29+
30+
data VSourceFile = VSourceFile
31+
{ vSrcFileSrcFile :: TCM.SourceFile,
32+
vSrcUri :: LSP.NormalizedUri,
33+
vSrcVFile :: VFS.VirtualFile
34+
}
35+
36+
vSrcFilePath :: (TCM.MonadFileId m) => VSourceFile -> m TCM.AbsolutePath
37+
vSrcFilePath = TCM.srcFilePath . vSrcFileSrcFile
38+
39+
vSrcFileId :: VSourceFile -> TCM.FileId
40+
vSrcFileId = TCM.srcFileId . vSrcFileSrcFile
41+
42+
#if MIN_VERSION_Agda(2,8,0)
43+
vSrcFromUri ::
44+
(TCM.MonadFileId m, MonadIO m) =>
45+
LSP.NormalizedUri ->
46+
VFS.VirtualFile ->
47+
m VSourceFile
48+
vSrcFromUri normUri file = do
49+
absPath <- uriToPossiblyInvalidAbsolutePath normUri
50+
src <- TCM.srcFromPath absPath
51+
return $ VSourceFile src normUri file
52+
#else
53+
vSrcFromUri ::
54+
(MonadIO m) =>
55+
LSP.NormalizedUri ->
56+
VFS.VirtualFile ->
57+
m VSourceFile
58+
vSrcFromUri normUri file = do
59+
absPath <- uriToPossiblyInvalidAbsolutePath normUri
60+
let src = SourceFile absPath
61+
return $ VSourceFile src normUri file
62+
#endif
63+
64+
-- | Based on @parseSource@
65+
parseVSource :: (TCM.MonadTCM m) => VSourceFile -> m Imp.Source
66+
parseVSource vSrcFile = TCM.liftTCM $ do
67+
let sourceFile = vSrcFileSrcFile vSrcFile
68+
f <- vSrcFilePath vSrcFile
69+
70+
let rf0 = mkRangeFile f Nothing
71+
TCM.setCurrentRange (Imp.beginningOfFile rf0) $ do
72+
let sourceStrict = VFS.virtualFileText $ vSrcVFile vSrcFile
73+
let source = Strict.toLazy sourceStrict
74+
let txt = Text.unpack sourceStrict
75+
76+
parsedModName0 <-
77+
Imp.moduleName f . fst . fst =<< do
78+
Imp.runPMDropWarnings $ parseFile moduleParser rf0 txt
79+
80+
let rf = mkRangeFile f $ Just parsedModName0
81+
((parsedMod, attrs), fileType) <- Imp.runPM $ parseFile moduleParser rf txt
82+
parsedModName <- Imp.moduleName f parsedMod
83+
84+
-- TODO: handle libs properly
85+
let libs = []
86+
87+
return
88+
Imp.Source
89+
{ Imp.srcText = source,
90+
Imp.srcFileType = fileType,
91+
Imp.srcOrigin = sourceFile,
92+
Imp.srcModule = parsedMod,
93+
Imp.srcModuleName = parsedModName,
94+
Imp.srcProjectLibs = libs,
95+
Imp.srcAttributes = attrs
96+
}

src/Agda/Syntax/Abstract/More.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ instance Pretty LetBinding where
170170
text "let" <+> pretty (unBind name) <+> text "=" <+> pretty expr
171171
LetPatBind _letInfo pat expr ->
172172
text "letPat" <+> pretty pat <+> text "=" <+> pretty expr
173-
LetDeclaredVariable name -> text "letDeclared" <+> pretty (unBind name)
174173
_ -> text "LetBinding"
175174

176175
instance Pretty Binder where

src/Server/Handler/TextDocument/FileManagement.hs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,44 @@ where
77

88
import Agda.Interaction.FindFile (SourceFile (SourceFile))
99
import qualified Agda.Interaction.Imports.More as Imp
10+
import Agda.Interaction.Imports.Virtual (parseVSource, vSrcFromUri)
1011
import Agda.TypeChecking.Monad (MonadTCM (liftTCM))
1112
import Agda.Utils.Lens ((^.))
1213
import Control.Monad.Trans (lift)
1314
import Data.Strict (Strict (toLazy))
1415
import Indexer (indexFile)
1516
import qualified Language.LSP.Protocol.Lens as LSP
1617
import qualified Language.LSP.Protocol.Message as LSP
18+
import qualified Language.LSP.Protocol.Types as LSP
1719
import Language.LSP.Protocol.Types.Uri.More (uriToPossiblyInvalidAbsolutePath)
1820
import qualified Language.LSP.Server as LSP
19-
import qualified Language.LSP.Server as VFS
2021
import qualified Language.LSP.VFS as VFS
2122
import Monad (ServerM, modifyModel)
2223
import qualified Server.Model as Model
2324
import Server.Model.Handler (notificationHandlerWithAgdaLib)
2425

2526
didOpenHandler :: LSP.Handlers ServerM
2627
didOpenHandler = notificationHandlerWithAgdaLib LSP.SMethod_TextDocumentDidOpen $ \uri notification -> do
27-
sourceFile <- SourceFile <$> uriToPossiblyInvalidAbsolutePath uri
28-
let sourceText = toLazy $ notification ^. LSP.params . LSP.textDocument . LSP.text
29-
src <- liftTCM $ Imp.parseVirtualSource sourceFile sourceText
30-
agdaFile <- indexFile src
31-
lift $ modifyModel $ Model.setAgdaFile uri agdaFile
28+
vfile <- lift $ LSP.getVirtualFile uri
29+
case vfile of
30+
Nothing -> return ()
31+
Just vfile -> do
32+
vSourceFile <- vSrcFromUri uri vfile
33+
src <- liftTCM $ parseVSource vSourceFile
34+
agdaFile <- indexFile src
35+
lift $ modifyModel $ Model.setAgdaFile uri agdaFile
3236

3337
didCloseHandler :: LSP.Handlers ServerM
3438
didCloseHandler = notificationHandlerWithAgdaLib LSP.SMethod_TextDocumentDidClose $ \uri notification -> do
3539
lift $ modifyModel $ Model.deleteAgdaFile uri
3640

3741
didSaveHandler :: LSP.Handlers ServerM
3842
didSaveHandler = notificationHandlerWithAgdaLib LSP.SMethod_TextDocumentDidSave $ \uri notification -> do
39-
sourceFile <- SourceFile <$> uriToPossiblyInvalidAbsolutePath uri
40-
virtualFile <- lift $ VFS.getVirtualFile uri
41-
case virtualFile of
43+
vfile <- lift $ LSP.getVirtualFile uri
44+
case vfile of
4245
Nothing -> return ()
43-
Just virtualFile -> do
44-
let sourceText = toLazy $ VFS.virtualFileText virtualFile
45-
src <- liftTCM $ Imp.parseVirtualSource sourceFile sourceText
46+
Just vfile -> do
47+
vSourceFile <- vSrcFromUri uri vfile
48+
src <- liftTCM $ parseVSource vSourceFile
4649
agdaFile <- indexFile src
4750
lift $ modifyModel $ Model.setAgdaFile uri agdaFile

src/Server/Model/Monad.hs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE CPP #-}
12
{-# LANGUAGE DataKinds #-}
23
{-# LANGUAGE FlexibleContexts #-}
34
{-# LANGUAGE FlexibleInstances #-}
@@ -45,6 +46,9 @@ import Options (Config)
4546
import qualified Server.Model as Model
4647
import Server.Model.AgdaFile (AgdaFile)
4748
import Server.Model.AgdaLib (AgdaLib, agdaLibTcEnv, agdaLibTcStateRef)
49+
#if MIN_VERSION_Agda(2,8,0)
50+
import Agda.Utils.FileId (File, getIdFile)
51+
#endif
4852

4953
--------------------------------------------------------------------------------
5054

@@ -110,6 +114,16 @@ defaultLiftTCM (TCM f) = do
110114
tcEnv <- useAgdaLib agdaLibTcEnv
111115
liftIO $ f tcStateRef tcEnv
112116

117+
#if MIN_VERSION_Agda(2,8,0)
118+
-- Taken from TCMT implementation
119+
defaultFileFromId :: (MonadAgdaLib m) => TCM.FileId -> m File
120+
defaultFileFromId fi = useTC TCM.stFileDict <&> (`getIdFile` fi)
121+
122+
-- Taken from TCMT implementation
123+
defaultIdFromFile :: (MonadAgdaLib m) => File -> m TCM.FileId
124+
defaultIdFromFile = TCM.stateTCLens TCM.stFileDict . TCM.registerFileIdWithBuiltin
125+
#endif
126+
113127
--------------------------------------------------------------------------------
114128

115129
newtype WithAgdaLibT m a = WithAgdaLibT {unWithAgdaLibT :: ReaderT AgdaLib m a}
@@ -151,6 +165,12 @@ instance (MonadIO m) => HasOptions (WithAgdaLibT m) where
151165
instance (MonadIO m) => MonadTCM (WithAgdaLibT m) where
152166
liftTCM = defaultLiftTCM
153167

168+
#if MIN_VERSION_Agda(2,8,0)
169+
instance (MonadIO m) => TCM.MonadFileId (WithAgdaLibT m) where
170+
fileFromId = defaultFileFromId
171+
idFromFile = defaultIdFromFile
172+
#endif
173+
154174
--------------------------------------------------------------------------------
155175

156176
data WithAgdaFileEnv = WithAgdaFileEnv

0 commit comments

Comments
 (0)