Skip to content

Commit 1d46cb4

Browse files
committed
Work in progress
1 parent c18ff7f commit 1d46cb4

File tree

8 files changed

+46
-76
lines changed

8 files changed

+46
-76
lines changed

.github/workflows/build.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ jobs:
2525
os:
2626
- ubuntu-latest
2727
ghc:
28-
- '9.4'
2928
- '9.6'
3029
- '9.8'
3130
- '9.10'

package.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ default-extensions:
2222
- DerivingVia
2323

2424
dependencies:
25-
- base >= 4.11 && < 5
25+
- base >= 4.18 && < 5
2626
- pretty
2727
- process
2828
- fsnotify == 0.4.*

sensei.cabal

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/GHC/Diagnostic.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module GHC.Diagnostic (
1919

2020
import Imports hiding (stripPrefix)
2121
import Builder (Builder, Color(..))
22-
import qualified Builder as Builder
22+
import qualified Builder
2323

2424
import System.IO
2525
import Data.Text (stripPrefix, stripSuffix)
@@ -39,10 +39,10 @@ formatAnnotated annotated = Builder.toText $
3939
fromString (format annotated.diagnostic) <> formatSolutions annotated.solutions
4040

4141
formatSolutions :: [Solution] -> Builder
42-
formatSolutions = Builder.unlines . map formatNumbered . zip [1..]
42+
formatSolutions = Builder.unlines . zipWith formatNumbered [1..]
4343
where
44-
formatNumbered :: (Int, Solution) -> Builder
45-
formatNumbered (n, solution) = formatNumber n <> formatSolution solution
44+
formatNumbered :: Int -> Solution -> Builder
45+
formatNumbered n solution = formatNumber n <> formatSolution solution
4646

4747
formatNumber :: Int -> Builder
4848
formatNumber n = Builder.withColor Cyan $ " " <> "[" <> Builder.show n <> "] "

test/GHC/Diagnostic/UtilSpec.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import GHC.Diagnostic.Annotated
88
import GHC.Diagnostic.Util
99

1010
spec :: Spec
11-
spec = focus do
11+
spec = do
1212
describe "joinMessageLines" do
1313
context "when a line starts with whitespace" do
1414
it "joins that line with the previous line" do

test/GHC/DiagnosticSpec.hs

Lines changed: 34 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
{-# LANGUAGE QuasiQuotes #-}
33
module GHC.DiagnosticSpec (spec) where
44

5-
import Data.ByteString qualified as B
65
import Helper hiding (diagnostic)
76
import Test.Hspec.Expectations.Contrib qualified as Hspec
87
import Text.RawString.QQ (r, rQ)
@@ -11,11 +10,12 @@ import System.Process
1110
import System.Environment
1211
import qualified Data.Text as T
1312
import qualified Data.Text.Encoding as T
13+
import Data.ByteString qualified as B
14+
import qualified Data.Map as Map
1415

1516
import Language.Haskell.GhciWrapper (lookupGhc)
1617
import GHC.Diagnostic
1718
import GHC.Diagnostic.Annotated
18-
import qualified Data.Map as Map
1919

2020
data Requirement = NoRequirement | RequireGhc912
2121

@@ -33,15 +33,8 @@ _ignore = let _ = (ftest, xtest) in ()
3333
normalizeGhcVersion :: String -> String
3434
normalizeGhcVersion = T.unpack . T.replace __GLASGOW_HASKELL_FULL_VERSION__ "9.10.0" . T.pack
3535

36-
availableImports :: AvailableImports
37-
availableImports = Map.fromList [
38-
("c2w", ["Data.ByteString.Internal"])
39-
, ("fromList", ["Data.Map"])
40-
]
41-
42-
4336
testWith :: HasCallStack => FilePath -> Requirement -> [String] -> String -> Maybe Annotation -> [Solution] -> Spec
44-
testWith name requirement extraArgs (unindent -> code) action solutions = it name $ do
37+
testWith name requirement extraArgs (unindent -> code) annotation solutions = it name do
4538
unless (T.null code) do
4639
ensureFile src $ T.encodeUtf8 code
4740
err <- translate <$> ghc ["-fno-diagnostics-show-caret"]
@@ -50,9 +43,9 @@ testWith name requirement extraArgs (unindent -> code) action solutions = it nam
5043
ensureFile (dir </> "err.json") (encodeUtf8 $ normalizeGhcVersion json)
5144
Hspec.annotate (separator <> err <> separator) do
5245
Just annotated <- return . parseAnnotated availableImports $ encodeUtf8 json
53-
when shouldRun $ do
46+
when shouldRun do
5447
format annotated.diagnostic `shouldBe` err
55-
annotated.annotation `shouldBe` action
48+
annotated.annotation `shouldBe` annotation
5649
annotated.solutions `shouldBe` solutions
5750
where
5851
separator :: String
@@ -90,6 +83,12 @@ testWith name requirement extraArgs (unindent -> code) action solutions = it nam
9083
True
9184
#endif
9285

86+
availableImports :: AvailableImports
87+
availableImports = Map.fromList [
88+
("c2w", ["Data.ByteString.Internal"])
89+
, ("fromList", ["Data.Map"])
90+
]
91+
9392
unindent :: String -> Text
9493
unindent (T.pack >>> T.dropWhileEnd isSpace >>> T.lines -> input) = go input
9594
where
@@ -102,58 +101,38 @@ unindent (T.pack >>> T.dropWhileEnd isSpace >>> T.lines -> input) = go input
102101
dropEmptyLines :: [Text] -> [Text]
103102
dropEmptyLines = filter (not . T.all isSpace)
104103

105-
variableNotInScope :: RequiredVariable -> Maybe Annotation
106-
variableNotInScope name = Just $ NotInScope name
107-
108104
redundantImport :: Maybe Annotation
109105
redundantImport = Just RedundantImport
110106

111-
suggestImport :: Module -> Text -> Solution
112-
suggestImport module_ name = ImportName module_ Unqualified name
107+
notInScope :: RequiredVariable -> Maybe Annotation
108+
notInScope = Just . NotInScope
109+
110+
importName :: Module -> Text -> Solution
111+
importName module_ = ImportName module_ Unqualified
113112

114113
spec :: Spec
115114
spec = do
116-
describe "format" $ do
115+
describe "format" do
117116
test "not-in-scope" [] [r|
118117
module Foo where
119118
foo = c2w
120-
|] (variableNotInScope "c2w") [suggestImport "Data.ByteString.Internal" "c2w"]
121-
122-
test "not-in-scope-type-signature" [] [r|
123-
module Foo where
124-
foo :: String -> String -> String -> String -> String -> String -> String
125-
foo = c2w
126-
|] (variableNotInScope $ RequiredVariable Unqualified "c2w" $ Just "String -> String -> String -> String -> String -> String -> String") [suggestImport "Data.ByteString.Internal" "c2w"]
127-
128-
test "not-in-scope-qualified" [] [r|
129-
module Foo where
130-
foo = B.c2w
131-
|] (variableNotInScope $ RequiredVariable "B" "c2w" Nothing) [ImportName "Data.ByteString.Internal" (Qualified "B") "c2w"]
132-
133-
test "not-in-scope-qualified-2" [] [r|
134-
module Foo where
135-
import Data.List.NonEmpty qualified as Ma
136-
foo = Map.fromList
137-
|] (variableNotInScope $ RequiredVariable "Map" "fromList" Nothing) [
138-
UseName "Ma.fromList"
139-
, ImportName "Data.Map" (Qualified "Map") "fromList"
140-
]
119+
|] (notInScope "c2w") [importName "Data.ByteString.Internal" "c2w"]
141120

142121
test "not-in-scope-perhaps-use" [] [r|
143122
module Foo where
144123
foo = filter_
145-
|] (variableNotInScope "filter_") [UseName "filter"]
124+
|] (notInScope "filter_") [UseName "filter"]
146125

147126
test "not-in-scope-perhaps-use-one-of-these" [] [r|
148127
module Foo where
149128
foo = fold
150-
|] (variableNotInScope "fold") [UseName "foldl", UseName "foldr"]
129+
|] (notInScope "fold") [UseName "foldl", UseName "foldr"]
151130

152131
test "not-in-scope-perhaps-use-multiline" [] [r|
153132
module Foo where
154133
import Data.List
155134
foo = fold
156-
|] (variableNotInScope "fold") [UseName "foldl", UseName "foldr"]
135+
|] (notInScope "fold") [UseName "foldl", UseName "foldr"]
157136

158137
test "use-BlockArguments" [] [r|
159138
{-# LANGUAGE NoBlockArguments #-}
@@ -194,28 +173,29 @@ spec = do
194173
foo = "foo" + 23
195174
|] Nothing []
196175

197-
describe "extractIdentifiers" $ do
198-
it "extracts identifiers" $ do
176+
describe "extractIdentifiers" do
177+
it "extracts identifiers" do
199178
extractIdentifiers ".. `foldl' ..., `foldr' .." `shouldBe` [UseName "foldl", UseName "foldr"]
200179

201-
describe "qualifiedName" $ do
202-
it "" do
180+
describe "qualifiedName" do
181+
it "parses an unqualified name" do
203182
qualifiedName "foo" `shouldBe` RequiredVariable Unqualified "foo" Nothing
183+
184+
it "parses a qualified name" do
204185
qualifiedName "Foo.Bar.baz" `shouldBe` RequiredVariable "Foo.Bar" "baz" Nothing
205186

206-
describe "formatAnnotated" $ do
207-
it "extracts identifiers" $ do
208-
err <- B.readFile "test/fixtures/not-in-scope/err.json"
209-
Just foo <- return $ parseAnnotated availableImports err
210-
formatAnnotated foo `shouldBe` T.unlines [
187+
describe "formatAnnotated" do
188+
it "formats an annotated diagnostic message" do
189+
Just annotated <- B.readFile "test/fixtures/not-in-scope/err.json" <&> parseAnnotated availableImports
190+
formatAnnotated annotated `shouldBe` T.unlines [
211191
"test/fixtures/not-in-scope/Foo.hs:2:7: error: [GHC-88464]"
212192
, " Variable not in scope: c2w"
213193
, ""
214194
, T.pack (withColor Cyan " [1] ") <> "import Data.ByteString.Internal (c2w)"
215195
]
216196

217-
describe "applyReplace" $ do
218-
it "replaces a given source span with a substitute" $ do
197+
describe "applyReplace" do
198+
it "replaces a given source span with a substitute" do
219199
applyReplace (Location 2 7) (Location 2 14) "filter" [
220200
"module Foo where"
221201
, "foo = filter_ p xs"
@@ -224,7 +204,7 @@ spec = do
224204
, "foo = filter p xs"
225205
]
226206

227-
it "correctly handles source spans that span over multiple lines" $ do
207+
it "correctly handles source spans that span over multiple lines" do
228208
applyReplace (Location 2 8) (Location 3 7) "Ya" [
229209
"module Foo where"
230210
, "import Data.Maybe"
@@ -235,13 +215,3 @@ spec = do
235215
, "import Yabar"
236216
, "one = two"
237217
]
238-
239-
{-
240-
src/Command.hs:263:106: error: [GHC-88464]
241-
Data constructor not in scope: PascalCase :: [String] -> String
242-
Suggested fix: Perhaps use variable `pascalCase' (line 366)
243-
244-
test/Language/Haskell/GhciWrapperSpec.hs:164:25: error: [GHC-88464]
245-
Data constructor not in scope:
246-
NotInScope :: t0 -> [a0] -> GHC.Diagnostic.Annotated.Annotation
247-
-}

test/Helper.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module Helper (
2121

2222
, Annotated(..)
2323
, Diagnostic(..)
24+
, Annotation(..)
2425
, Span(..)
2526
, Location(..)
2627
, Severity(..)
@@ -57,6 +58,7 @@ import Language.Haskell.GhciWrapper
5758
import qualified Trigger
5859

5960
import GHC.Diagnostic
61+
import GHC.Diagnostic.Annotated
6062

6163
timeout :: HasCallStack => IO a -> IO a
6264
timeout action = do

test/Language/Haskell/GhciWrapperSpec.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import qualified Data.ByteString.Char8 as ByteString
77

88
import Language.Haskell.GhciWrapper (Config(..), Interpreter(..), ReloadStatus(..), Extract(..))
99
import qualified Language.Haskell.GhciWrapper as Interpreter
10-
import GHC.Diagnostic.Annotated
1110

1211
main :: IO ()
1312
main = hspec spec

0 commit comments

Comments
 (0)