Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit 82f3870

Browse files
committed
Add more test cases for context queries
1 parent 2060ad0 commit 82f3870

File tree

3 files changed

+90
-17
lines changed

3 files changed

+90
-17
lines changed

hie-plugin-api/Haskell/Ide/Engine/Context.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
module Haskell.Ide.Engine.Context where
22

33
import Data.Generics
4-
import Data.Foldable (asum)
54
import Language.Haskell.LSP.Types
65
import GHC
76
import qualified GhcModCore as GM (GhcPs) -- for GHC 8.2.2
@@ -37,10 +36,10 @@ getContext pos pm
3736
, pos `isInsideRange` r
3837
= Just ExportContext
3938

40-
| Just ctx <- everything (<|>) (Nothing `mkQ` go `extQ` goInline) decl
39+
| Just ctx <- something (Nothing `mkQ` go `extQ` goInline) decl
4140
= Just ctx
4241

43-
| Just ctx <- asum $ map importGo imports
42+
| Just ctx <- something (Nothing `mkQ` importGo) imports
4443
= Just ctx
4544

4645
| otherwise

test/testdata/context/ExampleContext.hs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import Data.List (find)
44
import Control.Monad hiding (fix)
55

66
foo :: Int -> Int
7-
foo xs = xs + 1
7+
foo xs = bar xs + 1
8+
where
9+
bar :: Int -> Int
10+
bar x = x + 2
811

9-
data Foo a = Foo a
12+
data Foo a = Foo a
1013
deriving (Show)
1114

1215
class Bar a where

test/unit/ContextSpec.hs

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ spec = describe "Context of different cursor positions" $ do
7777

7878
actual `shouldBe` res
7979

80+
it "import hiding context" $ withCurrentDirectory "./test/testdata/context" $ do
81+
fp_ <- makeAbsolute "./ExampleContext.hs"
82+
let res = IdeResultOk (Just (ImportHidingContext "Control.Monad"))
83+
actual <- getContextAt fp_ (toPos (4, 32))
84+
85+
actual `shouldBe` res
86+
8087
it "function declaration context"
8188
$ withCurrentDirectory "./test/testdata/context"
8289
$ do
@@ -85,6 +92,14 @@ spec = describe "Context of different cursor positions" $ do
8592
actual <- getContextAt fp_ (toPos (6, 1))
8693

8794
actual `shouldBe` res
95+
96+
it "function signature context"
97+
$ withCurrentDirectory "./test/testdata/context"
98+
$ do
99+
fp_ <- makeAbsolute "./ExampleContext.hs"
100+
let res = IdeResultOk (Just TypeContext)
101+
actual <- getContextAt fp_ (toPos (6, 8))
102+
actual `shouldBe` res
88103

89104

90105
it "function definition context"
@@ -95,70 +110,126 @@ spec = describe "Context of different cursor positions" $ do
95110
actual <- getContextAt fp_ (toPos (7, 1))
96111
actual `shouldBe` res
97112

98-
it "function signature context"
113+
-- This is interesting, the context for this is assumed to be ValueContext
114+
-- although the cursor is at the signature of a function in a where clause.
115+
-- Reason is probably that we only traverse the AST until we know that
116+
-- that we are in a ValueContext, however, within a ValueContext, another
117+
-- TypeContext may arise, like in this case.
118+
it "inner function declaration context"
99119
$ withCurrentDirectory "./test/testdata/context"
100120
$ do
101-
fp_ <- makeAbsolute "./ExampleContext.hs"
102-
let res = IdeResultOk (Just TypeContext)
103-
actual <- getContextAt fp_ (toPos (6, 8))
104-
actual `shouldBe` res
121+
fp_ <- makeAbsolute "./ExampleContext.hs"
122+
let res = IdeResultOk (Just ValueContext)
123+
actual <- getContextAt fp_ (toPos (9, 10))
124+
actual `shouldBe` res
125+
126+
it "inner function value context"
127+
$ withCurrentDirectory "./test/testdata/context"
128+
$ do
129+
fp_ <- makeAbsolute "./ExampleContext.hs"
130+
let res = IdeResultOk (Just ValueContext)
131+
actual <- getContextAt fp_ (toPos (10, 10))
132+
actual `shouldBe` res
105133

134+
135+
-- Declare a datatype, is Nothing, could be DataContext
106136
it "data declaration context"
107137
$ withCurrentDirectory "./test/testdata/context"
108138
$ do
109139
fp_ <- makeAbsolute "./ExampleContext.hs"
110140
let res = IdeResultOk Nothing
111-
actual <- getContextAt fp_ (toPos (9, 8))
141+
actual <- getContextAt fp_ (toPos (12, 8))
142+
actual `shouldBe` res
143+
144+
-- Define a datatype.
145+
it "data definition context"
146+
$ withCurrentDirectory "./test/testdata/context"
147+
$ do
148+
fp_ <- makeAbsolute "./ExampleContext.hs"
149+
let res = IdeResultOk (Just TypeContext)
150+
actual <- getContextAt fp_ (toPos (12, 18))
112151
actual `shouldBe` res
113152

114153
it "class declaration context"
115154
$ withCurrentDirectory "./test/testdata/context"
116155
$ do
117156
fp_ <- makeAbsolute "./ExampleContext.hs"
118157
let res = IdeResultOk (Just ClassContext)
119-
actual <- getContextAt fp_ (toPos (12, 8))
158+
actual <- getContextAt fp_ (toPos (15, 8))
120159
actual `shouldBe` res
121160

122161
it "class declaration function sig context"
123162
$ withCurrentDirectory "./test/testdata/context"
124163
$ do
125164
fp_ <- makeAbsolute "./ExampleContext.hs"
126165
let res = IdeResultOk (Just ClassContext)
127-
actual <- getContextAt fp_ (toPos (13, 7))
166+
actual <- getContextAt fp_ (toPos (16, 7))
128167
actual `shouldBe` res
129168

130169
it "instance declaration context"
131170
$ withCurrentDirectory "./test/testdata/context"
132171
$ do
133172
fp_ <- makeAbsolute "./ExampleContext.hs"
134173
let res = IdeResultOk (Just InstanceContext)
135-
actual <- getContextAt fp_ (toPos (15, 7))
174+
actual <- getContextAt fp_ (toPos (18, 7))
136175
actual `shouldBe` res
137176

177+
-- Function definition
138178
it "instance declaration function def context"
139179
$ withCurrentDirectory "./test/testdata/context"
140180
$ do
141181
fp_ <- makeAbsolute "./ExampleContext.hs"
142182
let res = IdeResultOk (Just InstanceContext)
143-
actual <- getContextAt fp_ (toPos (16, 6))
183+
actual <- getContextAt fp_ (toPos (19, 6))
144184
actual `shouldBe` res
145185

186+
-- This seems plain wrong, if the cursor is on the String "deriving",
187+
-- we would expect the context to be DerivingContext, but it is not.
188+
-- May require investigation if this is important.
146189
it "deriving context"
147190
$ withCurrentDirectory "./test/testdata/context"
148191
$ do
149192
fp_ <- makeAbsolute "./ExampleContext.hs"
150193
let res = IdeResultOk Nothing
151-
actual <- getContextAt fp_ (toPos (10, 9))
194+
actual <- getContextAt fp_ (toPos (13, 9))
195+
actual `shouldBe` res
196+
197+
-- Cursor is directly before the open parenthesis of a deriving clause.
198+
-- E.g. deriving (...)
199+
-- ^---- cursor is here
200+
-- Context is still Nothing.
201+
it "deriving parenthesis context"
202+
$ withCurrentDirectory "./test/testdata/context"
203+
$ do
204+
fp_ <- makeAbsolute "./ExampleContext.hs"
205+
let res = IdeResultOk Nothing
206+
actual <- getContextAt fp_ (toPos (13, 14))
207+
actual `shouldBe` res
208+
209+
-- Cursor is directly after the open parenthesis of a deriving clause.
210+
-- E.g. deriving (...)
211+
-- ^---- cursor is here
212+
-- Context is now Type. This makes sense, but an extension may be to be
213+
-- aware of the context of a deriving clause, thus offering only Type Classes
214+
-- as a completion.
215+
it "deriving parenthesis context"
216+
$ withCurrentDirectory "./test/testdata/context"
217+
$ do
218+
fp_ <- makeAbsolute "./ExampleContext.hs"
219+
let res = IdeResultOk (Just TypeContext)
220+
actual <- getContextAt fp_ (toPos (13, 15))
152221
actual `shouldBe` res
153222

154223
it "deriving typeclass context"
155224
$ withCurrentDirectory "./test/testdata/context"
156225
$ do
157226
fp_ <- makeAbsolute "./ExampleContext.hs"
158227
let res = IdeResultOk (Just TypeContext)
159-
actual <- getContextAt fp_ (toPos (10, 18))
228+
actual <- getContextAt fp_ (toPos (13, 18))
160229
actual `shouldBe` res
161230

231+
-- Point at an empty line.
232+
-- There is no context
162233
it "nothing" $ withCurrentDirectory "./test/testdata/context" $ do
163234
fp_ <- makeAbsolute "./ExampleContext.hs"
164235
let res = IdeResultOk Nothing

0 commit comments

Comments
 (0)