diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs index d68f61639a..8202d7c1e0 100644 --- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs +++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs @@ -17,8 +17,10 @@ import qualified Data.ByteString as BS import Data.Hashable import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap +import qualified Data.List as List import qualified Data.List.NonEmpty as NE import qualified Data.Maybe as Maybe +import qualified Data.Text () import qualified Data.Text as T import qualified Data.Text.Encoding as Encoding import Data.Text.Utf16.Rope.Mixed as Rope @@ -33,17 +35,21 @@ import Development.IDE.Graph (Key, import Development.IDE.LSP.HoverDefinition (foundHover) import qualified Development.IDE.Plugin.Completions.Logic as Ghcide import Development.IDE.Types.Shake (toKey) +import qualified Distribution.CabalSpecVersion as Cabal import qualified Distribution.Fields as Syntax import Distribution.Package (Dependency) import Distribution.PackageDescription (allBuildDepends, depPkgName, unPackageName) import Distribution.PackageDescription.Configuration (flattenPackageDescription) +import Distribution.Parsec.Error import qualified Distribution.Parsec.Position as Syntax import GHC.Generics +import qualified Ide.Plugin.Cabal.CabalAdd as CabalAdd import Ide.Plugin.Cabal.Completion.CabalFields as CabalFields import qualified Ide.Plugin.Cabal.Completion.Completer.Types as CompleterTypes import qualified Ide.Plugin.Cabal.Completion.Completions as Completions +import qualified Ide.Plugin.Cabal.Completion.Data as Data import Ide.Plugin.Cabal.Completion.Types (ParseCabalCommonSections (ParseCabalCommonSections), ParseCabalFields (..), ParseCabalFile (..)) @@ -63,10 +69,6 @@ import Language.LSP.Protocol.Types import qualified Language.LSP.VFS as VFS import Text.Regex.TDFA - -import qualified Data.Text () -import qualified Ide.Plugin.Cabal.CabalAdd as CabalAdd - data Log = LogModificationTime NormalizedFilePath FileVersion | LogShake Shake.Log @@ -247,7 +249,31 @@ cabalRules recorder plId = do let warningDiags = fmap (Diagnostics.warningDiagnostic file) pWarnings case pm of Left (_cabalVersion, pErrorNE) -> do - let errorDiags = NE.toList $ NE.map (Diagnostics.errorDiagnostic file) pErrorNE + let regex :: T.Text + -- We don't support the cabal version, this should not be an error, as the + -- user did not do anything wrong. Instead we cast it to a warning + regex = "Unsupported cabal-version [0-9]+.[0-9]*" + unsupportedCabalHelpText = unlines + [ "The used cabal version is not fully supported by HLS. This means that some functionality might not work as expected." + , "If you face any issues try to downgrade to a supported cabal version." + , "" + , "Supported versions are: " <> + List.intercalate ", " + (fmap Cabal.showCabalSpecVersion Data.supportedCabalVersions) + ] + errorDiags = + NE.toList $ + NE.map + ( \pe@(PError pos text) -> + if text =~ regex + then Diagnostics.warningDiagnostic file (Syntax.PWarning Syntax.PWTOther pos $ + unlines + [ text + , unsupportedCabalHelpText + ]) + else Diagnostics.errorDiagnostic file pe + ) + pErrorNE allDiags = errorDiags <> warningDiags pure (allDiags, Nothing) Right gpd -> do diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs index 44535607ab..c27568d692 100644 --- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs +++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs @@ -23,6 +23,9 @@ import Ide.Plugin.Cabal.LicenseSuggest (licenseNames) -- Completion Data -- ---------------------------------------------------------------- +supportedCabalVersions :: [CabalSpecVersion] +supportedCabalVersions = [CabalSpecV2_2 .. maxBound] + -- | Keyword for cabal version; required to be the top line in a cabal file cabalVersionKeyword :: Map KeyWordName Completer cabalVersionKeyword = @@ -30,7 +33,7 @@ cabalVersionKeyword = constantCompleter $ -- We only suggest cabal versions newer than 2.2 -- since we don't recommend using older ones. - map (T.pack . showCabalSpecVersion) [CabalSpecV2_2 .. maxBound] + map (T.pack . showCabalSpecVersion) supportedCabalVersions -- | Top level keywords of a cabal file. -- diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Diagnostics.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Diagnostics.hs index 26156c5131..dc36a43482 100644 --- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Diagnostics.hs +++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Diagnostics.hs @@ -63,8 +63,9 @@ positionFromCabalPosition :: Syntax.Position -> Position positionFromCabalPosition (Syntax.Position line column) = Position (fromIntegral line') (fromIntegral col') where -- LSP is zero-based, Cabal is one-based - line' = line-1 - col' = column-1 + -- Cabal can return line 0 for errors in the first line + line' = if line <= 0 then 0 else line-1 + col' = if column <= 0 then 0 else column-1 -- | Create a 'FileDiagnostic' mkDiag diff --git a/plugins/hls-cabal-plugin/test/Main.hs b/plugins/hls-cabal-plugin/test/Main.hs index 499d4aa569..cec2d36a53 100644 --- a/plugins/hls-cabal-plugin/test/Main.hs +++ b/plugins/hls-cabal-plugin/test/Main.hs @@ -107,6 +107,14 @@ pluginTests = length diags @?= 1 unknownLicenseDiag ^. L.range @?= Range (Position 3 24) (Position 4 0) unknownLicenseDiag ^. L.severity @?= Just DiagnosticSeverity_Error + , runCabalTestCaseSession "Publishes Diagnostics on unsupported cabal version as Warning" "" $ do + _ <- openDoc "unsupportedVersion.cabal" "cabal" + diags <- cabalCaptureKick + unknownVersionDiag <- liftIO $ inspectDiagnostic diags ["Unsupported cabal-version 99999.0"] + liftIO $ do + length diags @?= 1 + unknownVersionDiag ^. L.range @?= Range (Position 0 0) (Position 1 0) + unknownVersionDiag ^. L.severity @?= Just DiagnosticSeverity_Warning , runCabalTestCaseSession "Clears diagnostics" "" $ do doc <- openDoc "invalid.cabal" "cabal" diags <- cabalCaptureKick diff --git a/plugins/hls-cabal-plugin/test/testdata/unsupportedVersion.cabal b/plugins/hls-cabal-plugin/test/testdata/unsupportedVersion.cabal new file mode 100644 index 0000000000..328d373cd8 --- /dev/null +++ b/plugins/hls-cabal-plugin/test/testdata/unsupportedVersion.cabal @@ -0,0 +1,3 @@ +cabal-version: 99999.0 +name: invalid +version: 0.1.0.0 \ No newline at end of file