From 97c9f51251160e47a1aa75f3ccb96cd9fc008a81 Mon Sep 17 00:00:00 2001 From: Lin Jian Date: Thu, 3 Apr 2025 01:34:36 +0800 Subject: [PATCH 1/2] Support PackageImports in hiddenPackageSuggestion Fix: #4479 --- .../src/Ide/Plugin/Cabal/CabalAdd.hs | 15 +++++++++++++-- plugins/hls-cabal-plugin/test/CabalAdd.hs | 19 +++++++++++++++++++ .../cabal-add-tests/cabal-add-tests.cabal | 8 ++++++++ .../test/MainPackageImports.hs | 8 ++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/MainPackageImports.hs diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs index ed43099998..d63c8fdea5 100644 --- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs +++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs @@ -190,6 +190,12 @@ addDependencySuggestCodeAction plId verTxtDocId suggestions haskellFilePath caba -- > It is a member of the hidden package ‘split-0.2.5’. -- > Perhaps you need to add ‘split’ to the build-depends in your .cabal file." -- +-- or this if PackageImports extension is used: +-- +-- > "Could not find module ‘Data.List.Split’ +-- > Perhaps you meant +-- > Data.List.Split (needs flag -package-id split-0.2.5)" +-- -- It extracts mentioned package names and version numbers. -- In this example, it will be @[("split", "0.2.5")]@ -- @@ -204,12 +210,17 @@ hiddenPackageSuggestion diag = getMatch (msg =~ regex) msg :: T.Text msg = _message diag regex :: T.Text -- TODO: Support multiple packages suggestion - regex = "It is a member of the hidden package [\8216']([a-zA-Z0-9-]*[a-zA-Z0-9])(-([0-9\\.]*))?[\8217']" + regex = + let regex' = "([a-zA-Z0-9-]*[a-zA-Z0-9])(-([0-9\\.]*))?" + in "It is a member of the hidden package [\8216']" <> regex' <> "[\8217']" + <> "|" + <> "needs flag -package-id " <> regex' -- Have to do this matching because `Regex.TDFA` doesn't(?) support -- not-capturing groups like (?:message) getMatch :: (T.Text, T.Text, T.Text, [T.Text]) -> [(T.Text, T.Text)] getMatch (_, _, _, []) = [] - getMatch (_, _, _, [dependency, _, cleanVersion]) = [(dependency, cleanVersion)] + getMatch (_, _, _, [dependency, _, cleanVersion, "", "", ""]) = [(dependency, cleanVersion)] + getMatch (_, _, _, ["", "", "", dependency, _, cleanVersion]) = [(dependency, cleanVersion)] getMatch (_, _, _, _) = error "Impossible pattern matching case" command :: Recorder (WithPriority Log) -> CommandFunction IdeState CabalAddCommandParams diff --git a/plugins/hls-cabal-plugin/test/CabalAdd.hs b/plugins/hls-cabal-plugin/test/CabalAdd.hs index 3b36f82bc2..6517c811fe 100644 --- a/plugins/hls-cabal-plugin/test/CabalAdd.hs +++ b/plugins/hls-cabal-plugin/test/CabalAdd.hs @@ -33,6 +33,8 @@ cabalAddTests = (generateAddDependencyTestSession "cabal-add-lib.cabal" ("src" "MyLib.hs") "split" [348]) , runHaskellTestCaseSession "Code Actions - Can add hidden package to a test" ("cabal-add-testdata" "cabal-add-tests") (generateAddDependencyTestSession "cabal-add-tests.cabal" ("test" "Main.hs") "split" [478]) + , runHaskellTestCaseSession "Code Actions - Can add hidden package to a test with PackageImports" ("cabal-add-testdata" "cabal-add-tests") + (generateAddDependencyTestSession "cabal-add-tests.cabal" ("test" "MainPackageImports.hs") "split" [731]) , runHaskellTestCaseSession "Code Actions - Can add hidden package to a benchmark" ("cabal-add-testdata" "cabal-add-bench") (generateAddDependencyTestSession "cabal-add-bench.cabal" ("bench" "Main.hs") "split" [403]) @@ -122,6 +124,23 @@ cabalAddTests = [ ("3d-graphics-examples", T.empty) , ("3d-graphics-examples", "1.1.6") ] + , testHiddenPackageSuggestions "Check CabalAdd's parser, with version, with PackageImports" + [ "(needs flag -package-id base-0.1.0.0)" + , "(needs flag -package-id Blammo-wai-0.11.0)" + , "(needs flag -package-id BlastHTTP-2.6.4.3)" + , "(needs flag -package-id CC-delcont-ref-tf-0.0.0.2)" + , "(needs flag -package-id 3d-graphics-examples-1.1.6)" + , "(needs flag -package-id AAI-0.1)" + , "(needs flag -package-id AWin32Console-1.19.1)" + ] + [ ("base","0.1.0.0") + , ("Blammo-wai", "0.11.0") + , ("BlastHTTP", "2.6.4.3") + , ("CC-delcont-ref-tf", "0.0.0.2") + , ("3d-graphics-examples", "1.1.6") + , ("AAI", "0.1") + , ("AWin32Console", "1.19.1") + ] ] where generateAddDependencyTestSession :: FilePath -> FilePath -> T.Text -> [Int] -> Session () diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/cabal-add-tests.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/cabal-add-tests.cabal index d217f8c4d5..9adc498231 100644 --- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/cabal-add-tests.cabal +++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/cabal-add-tests.cabal @@ -16,3 +16,11 @@ test-suite cabal-add-tests-test hs-source-dirs: test main-is: Main.hs build-depends: base + +test-suite cabal-add-tests-test-package-imports + import: warnings + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: MainPackageImports.hs + build-depends: base diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/MainPackageImports.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/MainPackageImports.hs new file mode 100644 index 0000000000..753dd165dd --- /dev/null +++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/MainPackageImports.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE PackageImports #-} + +module Main (main) where + +import "split" Data.List.Split + +main :: IO () +main = putStrLn "Test suite not yet implemented." From 4efa5d761d8cf708d8b12823ca76a66d6bf6407b Mon Sep 17 00:00:00 2001 From: Lin Jian Date: Fri, 4 Apr 2025 00:32:48 +0800 Subject: [PATCH 2/2] Stop using error in hiddenPackageSuggestion --- plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs index d63c8fdea5..3b46eec128 100644 --- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs +++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs @@ -221,7 +221,7 @@ hiddenPackageSuggestion diag = getMatch (msg =~ regex) getMatch (_, _, _, []) = [] getMatch (_, _, _, [dependency, _, cleanVersion, "", "", ""]) = [(dependency, cleanVersion)] getMatch (_, _, _, ["", "", "", dependency, _, cleanVersion]) = [(dependency, cleanVersion)] - getMatch (_, _, _, _) = error "Impossible pattern matching case" + getMatch (_, _, _, _) = [] command :: Recorder (WithPriority Log) -> CommandFunction IdeState CabalAddCommandParams command recorder state _ params@(CabalAddCommandParams {cabalPath = path, verTxtDocId = verTxtDocId, buildTarget = target, dependency = dep, version = mbVer}) = do