@@ -8,6 +8,7 @@
8module Development.IDE.Types.Diagnostics (
8module Development.IDE.Types.Diagnostics (
9 LSP.Diagnostic(..),
9 LSP.Diagnostic(..),
10 FileDiagnostics,
10 FileDiagnostics,
11 Location(..),
12 Location(..),
12 Range(..),
13 Range(..),
13 LSP.DiagnosticSeverity(..),
14 LSP.DiagnosticSeverity(..),
@@ -30,21 +31,17 @@ module Development.IDE.Types.Diagnostics (
30 defDiagnostic,
31 defDiagnostic,
31 addDiagnostics,
32 addDiagnostics,
32 filterSeriousErrors,
33 filterSeriousErrors,
35 filePathToUri,
34 filePathToUri,
36 getDiagnosticsFromStore
35 getDiagnosticsFromStore
39import Control.Exception
38import Control.Exception
40−import Control.Lens (Lens', lens, set, view)
41import Data.Either.Combinators
39import Data.Either.Combinators
42import Data.Maybe as Maybe
40import Data.Maybe as Maybe
43import Data.Foldable
41import Data.Foldable
44import qualified Data.Map as Map
42import qualified Data.Map as Map
45import qualified Data.Text as T
43import qualified Data.Text as T
46import Data.Text.Prettyprint.Doc.Syntax
44import Data.Text.Prettyprint.Doc.Syntax
47−import Data.String (IsString(..))
48import qualified Text.PrettyPrint.Annotated.HughesPJClass as Pretty
45import qualified Text.PrettyPrint.Annotated.HughesPJClass as Pretty
49import Language.Haskell.LSP.Types as LSP (
46import Language.Haskell.LSP.Types as LSP (
50 DiagnosticSeverity(..)
47 DiagnosticSeverity(..)
@@ -59,15 +56,15 @@ import Language.Haskell.LSP.Diagnostics
60import Development.IDE.Types.Location
57import Development.IDE.Types.Location
62−ideErrorText :: FilePath -> T.Text -> LSP.Diagnostic
59+ideErrorText :: FilePath -> T.Text -> FileDiagnostic
63ideErrorText fp = errorDiag fp "Ide Error"
60ideErrorText fp = errorDiag fp "Ide Error"
65−ideErrorPretty :: Pretty.Pretty e => FilePath -> e -> LSP.Diagnostic
62+ideErrorPretty :: Pretty.Pretty e => FilePath -> e -> FileDiagnostic
66ideErrorPretty fp = ideErrorText fp . T.pack . Pretty.prettyShow
63ideErrorPretty fp = ideErrorText fp . T.pack . Pretty.prettyShow
68−errorDiag :: FilePath -> T.Text -> T.Text -> LSP.Diagnostic
65+errorDiag :: FilePath -> T.Text -> T.Text -> FileDiagnostic
69−errorDiag fp src =
66+errorDiag fp src msg =
70− set dFilePath (Just fp) . diagnostic noRange LSP.DsError src
67+ (fp, diagnostic noRange LSP.DsError src msg)
72-- | This is for compatibility with our old diagnostic type
69-- | This is for compatibility with our old diagnostic type
73diagnostic :: Range
70diagnostic :: Range
@@ -99,33 +96,6 @@ defDiagnostic _range _message = LSP.Diagnostic {
99 , _relatedInformation = Nothing
96 , _relatedInformation = Nothing
102−-- | setLocation but with no range information
104− Lens' LSP.Diagnostic (Maybe FilePath)
105−dFilePath = lens g s where
106− g :: LSP.Diagnostic -> Maybe FilePath
107− g d = (uriToFilePath . _uri) =<< view dLocation d
108− s :: LSP.Diagnostic -> Maybe FilePath -> LSP.Diagnostic
109− s d@Diagnostic{..} fp = set dLocation
110− (Location <$> (filePathToUri <$> fp) <*> pure _range) d
112−-- | This adds location information to the diagnostics but this is only used in
113−-- the case of serious errors to give some context to what went wrong
115− Lens' LSP.Diagnostic (Maybe Location)
116−dLocation = lens g s where
117− s :: LSP.Diagnostic -> Maybe Location -> LSP.Diagnostic
120− d {LSP._range=(_range :: Location -> Range) loc
121− , LSP._relatedInformation = Just $ LSP.List [DiagnosticRelatedInformation loc "dLocation: Unknown error"]}
122− Nothing -> d {LSP._range = noRange, LSP._relatedInformation = Nothing}
123− g :: LSP.Diagnostic -> Maybe Location
124− g Diagnostic{..} = case _relatedInformation of
125− Just (List [DiagnosticRelatedInformation loc _]) -> Just loc
126− Just (List xs) -> error $ "Diagnostic created, expected 1 related information but got" <> show xs
129filterSeriousErrors ::
99filterSeriousErrors ::
130 FilePath ->
100 FilePath ->
131 [LSP.Diagnostic] ->
101 [LSP.Diagnostic] ->
@@ -148,7 +118,7 @@ addDiagnostics fp diags ds =
148 Nothing $
118 Nothing $
149 partitionBySource diags
119 partitionBySource diags
151−ideTryIOException :: FilePath -> IO a -> IO (Either LSP.Diagnostic a)
121+ideTryIOException :: FilePath -> IO a -> IO (Either FileDiagnostic a)
152ideTryIOException fp act =
122ideTryIOException fp act =
153 mapLeft (\(e :: IOException) -> ideErrorText fp $ T.pack $ show e) <$> try act
123 mapLeft (\(e :: IOException) -> ideErrorText fp $ T.pack $ show e) <$> try act
@@ -158,7 +128,8 @@ ideTryIOException fp act =
158-- along with the related source location so that we can display the error
128-- along with the related source location so that we can display the error
159-- on either the console or in the IDE at the right source location.
129-- on either the console or in the IDE at the right source location.
161−type FileDiagnostics = (Uri, [Diagnostic])
131+type FileDiagnostics = (FilePath, [Diagnostic])
132+type FileDiagnostic = (FilePath, Diagnostic)
163prettyRange :: Range -> Doc SyntaxClass
134prettyRange :: Range -> Doc SyntaxClass
164prettyRange Range{..} = f _start <> "-" <> f _end
135prettyRange Range{..} = f _start <> "-" <> f _end
@@ -167,20 +138,20 @@ prettyRange Range{..} = f _start <> "-" <> f _end
167stringParagraphs :: T.Text -> Doc a
138stringParagraphs :: T.Text -> Doc a
168stringParagraphs = vcat . map (fillSep . map pretty . T.words) . T.lines
139stringParagraphs = vcat . map (fillSep . map pretty . T.words) . T.lines
170−showDiagnostics :: [LSP.Diagnostic] -> T.Text
141+showDiagnostics :: [FileDiagnostic] -> T.Text
171showDiagnostics = srenderPlain . prettyDiagnostics
142showDiagnostics = srenderPlain . prettyDiagnostics
173−showDiagnosticsColored :: [LSP.Diagnostic] -> T.Text
144+showDiagnosticsColored :: [FileDiagnostic] -> T.Text
174showDiagnosticsColored = srenderColored . prettyDiagnostics
145showDiagnosticsColored = srenderColored . prettyDiagnostics
177−prettyDiagnostics :: [LSP.Diagnostic] -> Doc SyntaxClass
148+prettyDiagnostics :: [FileDiagnostic] -> Doc SyntaxClass
178prettyDiagnostics = vcat . map prettyDiagnostic
149prettyDiagnostics = vcat . map prettyDiagnostic
180−prettyDiagnostic :: LSP.Diagnostic -> Doc SyntaxClass
151+prettyDiagnostic :: FileDiagnostic -> Doc SyntaxClass
181−prettyDiagnostic d@LSP.Diagnostic{..} =
152+prettyDiagnostic (fp, LSP.Diagnostic{..}) =
183− [ slabel_ "File: " $ pretty $ view dFilePath d
154+ [ slabel_ "File: " $ pretty fp
184 , slabel_ "Range: " $ prettyRange _range
155 , slabel_ "Range: " $ prettyRange _range
185 , slabel_ "Source: " $ pretty _source
156 , slabel_ "Source: " $ pretty _source
186 , slabel_ "Severity:" $ pretty $ show sev
157 , slabel_ "Severity:" $ pretty $ show sev
@@ -199,38 +170,16 @@ prettyDiagnostic d@LSP.Diagnostic{..} =
199prettyDiagnosticStore :: DiagnosticStore -> Doc SyntaxClass
170prettyDiagnosticStore :: DiagnosticStore -> Doc SyntaxClass
200prettyDiagnosticStore ds =
171prettyDiagnosticStore ds =
202− map prettyFileDiagnostics $
173+ map (\(uri, diags) -> prettyFileDiagnostics (fromMaybe noFilePath $ uriToFilePath uri, diags)) $
203 Map.assocs $
174 Map.assocs $
204 Map.map getDiagnosticsFromStore ds
175 Map.map getDiagnosticsFromStore ds
206prettyFileDiagnostics :: FileDiagnostics -> Doc SyntaxClass
177prettyFileDiagnostics :: FileDiagnostics -> Doc SyntaxClass
207−prettyFileDiagnostics (uri, diags) =
178+prettyFileDiagnostics (filePath, diags) =
208 slabel_ "Compiler error in" $ vcat
179 slabel_ "Compiler error in" $ vcat
209 [ slabel_ "File:" $ pretty filePath
180 [ slabel_ "File:" $ pretty filePath
210− , slabel_ "Errors:" $ vcat $ map prettyDiagnostic diags
181+ , slabel_ "Errors:" $ vcat $ map (prettyDiagnostic . (filePath,)) diags
213− -- prettyFileDiags :: (FilePath, [(T.Text, [LSP.Diagnostic])]) -> Doc SyntaxClass
214− -- prettyFileDiags (fp,stages) =
215− -- slabel_ ("File: "<>fp) $ vcat $ map prettyStage stages
217− -- prettyStage :: (T.Text, [LSP.Diagnostic]) -> Doc SyntaxClass
218− -- prettyStage (stage,diags) =
219− -- slabel_ ("Stage: "<>T.unpack stage) $ vcat $ map prettyDiagnostic diags
221− filePath :: FilePath
222− filePath = fromMaybe dontKnow $ uriToFilePath uri
225− -- (FilePath, [(T.Text, [LSP.Diagnostic])])
226− -- -- ^ Source File, Stage Source, Diags
227− -- storeContents = (fromMaybe dontKnow $ uriToFilePath uri, getDiags diags)
229− dontKnow :: IsString s => s
230− dontKnow = "<unknown>"
232− -- getDiags :: DiagnosticsBySource -> [(T.Text, [LSP.Diagnostic])]
233− -- getDiags = map (\(ds, diag) -> (fromMaybe dontKnow ds, toList diag)) . Map.assocs
235getDiagnosticsFromStore :: StoreItem -> [Diagnostic]
184getDiagnosticsFromStore :: StoreItem -> [Diagnostic]
236getDiagnosticsFromStore (StoreItem _ diags) =
185getDiagnosticsFromStore (StoreItem _ diags) =