Skip to content

Commit e00b5dd

Browse files
rm41339Sid1005
authored andcommitted
Add "autogen-" field completions and tests for cabal files
Adds completions 'autogen-incudes' and 'autogen-modules'. Co-authored-by: rm41339 <rachelma41339@gmail.com> Co-authored-by: Siddharth_Ceri10 <89704257+Sid1005@users.noreply.github.com>
1 parent 664931b commit e00b5dd

File tree

4 files changed

+95
-12
lines changed

4 files changed

+95
-12
lines changed

plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Paths.hs

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Distribution.PackageDescription (Benchmark (..),
77
BuildInfo (..),
88
CondTree (condTreeData),
99
Executable (..),
10+
ForeignLib (..),
1011
GenericPackageDescription (..),
1112
Library (..),
1213
UnqualComponentName,
@@ -118,6 +119,10 @@ sourceDirsExtractionTestSuite name gpd = extractRelativeDirsFromStanza name gpd
118119
sourceDirsExtractionBenchmark :: Maybe StanzaName -> GenericPackageDescription -> [FilePath]
119120
sourceDirsExtractionBenchmark name gpd = extractRelativeDirsFromStanza name gpd condBenchmarks benchmarkBuildInfo
120121

122+
-- | Extracts the source directories of foreign-lib stanza with the given name.
123+
sourceDirsExtractionForeignLib :: Maybe StanzaName -> GenericPackageDescription -> [FilePath]
124+
sourceDirsExtractionForeignLib name gpd = extractRelativeDirsFromStanza name gpd condForeignLibs foreignLibBuildInfo
125+
121126
{- | Takes a possible stanza name, a GenericPackageDescription,
122127
a function to access the stanza information we are interested in
123128
and a function to access the build info from the specific stanza.

plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs

+42-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
{-# LANGUAGE OverloadedStrings #-}
2-
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
3-
4-
{-# HLINT ignore "Redundant bracket" #-}
52

63
module Ide.Plugin.Cabal.Completion.Data where
74

@@ -19,6 +16,17 @@ import Ide.Plugin.Cabal.Completion.Completer.Types (Completer)
1916
import Ide.Plugin.Cabal.Completion.Types
2017
import Ide.Plugin.Cabal.LicenseSuggest (licenseNames)
2118

19+
-- | Ad-hoc data type for modelling the available top-level stanzas.
20+
-- Not intended right now for anything else but to avoid string
21+
-- comparisons in 'stanzaKeywordMap' and 'libExecTestBenchCommons'.
22+
data TopLevelStanza
23+
= Library
24+
| Executable
25+
| TestSuite
26+
| Benchmark
27+
| ForeignLib
28+
| Common
29+
2230
-- ----------------------------------------------------------------
2331
-- Completion Data
2432
-- ----------------------------------------------------------------
@@ -71,12 +79,13 @@ cabalKeywords =
7179
stanzaKeywordMap :: Map StanzaType (Map KeyWordName Completer)
7280
stanzaKeywordMap =
7381
Map.fromList
74-
[ ("library", libraryFields <> libExecTestBenchCommons),
75-
("executable", executableFields <> libExecTestBenchCommons),
76-
("test-suite", testSuiteFields <> libExecTestBenchCommons),
77-
("benchmark", benchmarkFields <> libExecTestBenchCommons),
78-
("foreign-library", foreignLibraryFields <> libExecTestBenchCommons),
79-
("common", libExecTestBenchCommons),
82+
[ ("library", libraryFields <> libExecTestBenchCommons Library),
83+
("executable", executableFields <> libExecTestBenchCommons Executable),
84+
("test-suite", testSuiteFields <> libExecTestBenchCommons TestSuite),
85+
("benchmark", benchmarkFields <> libExecTestBenchCommons Benchmark),
86+
("foreign-library", foreignLibraryFields <> libExecTestBenchCommons ForeignLib),
87+
("common", libExecTestBenchCommons Library),
88+
("common", libExecTestBenchCommons Common),
8089
("flag", flagFields),
8190
("source-repository", sourceRepositoryFields)
8291
]
@@ -162,8 +171,8 @@ flagFields =
162171
("lib-version-linux:", noopCompleter)
163172
]
164173

165-
libExecTestBenchCommons :: Map KeyWordName Completer
166-
libExecTestBenchCommons =
174+
libExecTestBenchCommons :: TopLevelStanza -> Map KeyWordName Completer
175+
libExecTestBenchCommons st =
167176
Map.fromList
168177
[ ("import:", importCompleter),
169178
("build-depends:", noopCompleter),
@@ -183,6 +192,8 @@ libExecTestBenchCommons =
183192
("includes:", filePathCompleter),
184193
("install-includes:", filePathCompleter),
185194
("include-dirs:", directoryCompleter),
195+
("autogen-includes:", filePathCompleter),
196+
("autogen-modules:", moduleCompleterByTopLevelStanza),
186197
("c-sources:", filePathCompleter),
187198
("cxx-sources:", filePathCompleter),
188199
("asm-sources:", filePathCompleter),
@@ -203,6 +214,26 @@ libExecTestBenchCommons =
203214
("extra-framework-dirs:", directoryCompleter),
204215
("mixins:", noopCompleter)
205216
]
217+
where
218+
--
219+
moduleCompleterByTopLevelStanza = case st of
220+
Library -> modulesCompleter sourceDirsExtractionLibrary
221+
Executable -> modulesCompleter sourceDirsExtractionExecutable
222+
TestSuite -> modulesCompleter sourceDirsExtractionTestSuite
223+
Benchmark -> modulesCompleter sourceDirsExtractionBenchmark
224+
ForeignLib -> modulesCompleter sourceDirsExtractionForeignLib
225+
Common ->
226+
-- TODO: We can't provide a module completer because we provide
227+
-- module completions based on the "hs-source-dirs" after parsing the file,
228+
-- i.e. based on the 'PackageDescription'.
229+
-- "common" stanzas are erased in the 'PackageDescription' representation,
230+
-- thus we can't provide accurate module completers right now, as we don't
231+
-- know what the 'hs-source-dirs' in the "common" stanza are.
232+
--
233+
-- A potential fix would be to introduce an intermediate representation that
234+
-- parses the '.cabal' file s.t. that we have access to the 'hs-source-dirs',
235+
-- but not have erased the "common" stanza.
236+
noopCompleter
206237

207238
-- | Contains a map of the most commonly used licenses, weighted by their popularity.
208239
--

plugins/hls-cabal-plugin/test/Completer.hs

+23-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module Completer where
77

88
import Control.Lens ((^.), (^?))
99
import Control.Lens.Prism
10+
import Control.Monad (forM_)
1011
import qualified Data.ByteString as ByteString
1112
import qualified Data.ByteString.Char8 as BS8
1213
import Data.Maybe (mapMaybe)
@@ -40,7 +41,8 @@ completerTests =
4041
completionHelperTests,
4142
filePathExposedModulesTests,
4243
exposedModuleCompleterTests,
43-
importCompleterTests
44+
importCompleterTests,
45+
autogenFieldCompletionTests
4446
]
4547

4648
basicCompleterTests :: TestTree
@@ -336,6 +338,26 @@ importCompleterTests =
336338
[Syntax.SecArgName (Syntax.Position row (col + 7)) (BS8.pack name)]
337339
[]
338340

341+
autogenFieldCompletionTests :: TestTree
342+
autogenFieldCompletionTests =
343+
testGroup "Autogen Field Completer Tests"
344+
[ testAutogenField "library" "completion/autogen-completion.cabal" (Position 6 9) ["autogen-modules:", "autogen-includes:"]
345+
, testAutogenField "executable" "completion/autogen-completion.cabal" (Position 11 9) ["autogen-modules:", "autogen-includes:"]
346+
, testAutogenField "test-suite" "completion/autogen-completion.cabal" (Position 16 9) ["autogen-modules:", "autogen-includes:"]
347+
, testAutogenField "benchmark" "completion/autogen-completion.cabal" (Position 21 9) ["autogen-modules:", "autogen-includes:"]
348+
, testAutogenField "common" "completion/autogen-completion.cabal" (Position 24 9) ["autogen-modules:", "autogen-includes:"]
349+
]
350+
351+
where
352+
testAutogenField :: String -> FilePath -> Position -> [T.Text] -> TestTree
353+
testAutogenField section file pos expected = runCabalTestCaseSession ("autogen-modules completion in " <> section) "" $ do
354+
doc <- openDoc file "cabal"
355+
items <- getCompletions doc pos
356+
let labels = map (^. L.label) items
357+
liftIO $ forM_ expected $ \expect ->
358+
assertBool (T.unpack expect <> " not found in " <> section) $
359+
any (expect `T.isInfixOf`) labels
360+
339361
simpleCompleterData :: Maybe StanzaName -> FilePath -> T.Text -> CompleterData
340362
simpleCompleterData sName dir pref = do
341363
CompleterData
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
cabal-version: 3.0
2+
name: autogen-completion
3+
version: 0.1.0.0
4+
5+
library
6+
hs-source-dirs: src
7+
autogen-
8+
9+
executable autoexe
10+
main-is: Main.hs
11+
hs-source-dirs: src
12+
autogen-
13+
14+
test-suite autotest
15+
type: exitcode-stdio-1.0
16+
hs-source-dirs: src
17+
autogen-
18+
19+
benchmark autobench
20+
type: exitcode-stdio-1.0
21+
hs-source-dirs: src
22+
autogen-
23+
24+
common defaults
25+
autogen-

0 commit comments

Comments
 (0)