haskell-language-server-2.12.0.0: plugins/hls-signature-help-plugin/test/Main.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE QuasiQuotes #-}
import Control.Arrow ((>>>))
import Control.Exception (throw)
import Control.Lens ((^.))
import Data.Maybe (fromJust)
import Data.Text (Text)
import qualified Data.Text as T
import Development.IDE.Plugin.Completions.Types (PosPrefixInfo (PosPrefixInfo))
import Ide.Plugin.SignatureHelp (descriptor)
import qualified Language.LSP.Protocol.Lens as L
import Test.Hls
import Test.Hls.FileSystem (VirtualFileTree,
directCradle, file,
mkVirtualFileTree,
text)
main :: IO ()
main =
defaultTestRunner $
testGroup
"signatureHelp"
[ mkTest
"1 parameter"
[__i|
f :: Int -> Int
f = _
x = f 1
^^^^^^^^
|]
[ Nothing,
Nothing,
Nothing,
Nothing,
Nothing,
Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"2 parameters"
[__i|
f :: Int -> Int -> Int
f = _
x = f 1 2
^ ^^^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1))
],
mkTest
"3 parameters"
[__i|
f :: Int -> Int -> Int -> Int
f = _
x = f 1 2 3
^ ^ ^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing, ParameterInformation (InR (19, 22)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing, ParameterInformation (InR (19, 22)) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing, ParameterInformation (InR (19, 22)) Nothing]) (Just (InL 2))] (Just 0) (Just (InL 2))
],
mkTest
"parentheses"
[__i|
f :: Int -> Int -> Int
f = _
x = (f 1) 2
^^ ^^^^
|]
[ Nothing,
Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1))
],
mkTest
"newline"
[__i|
f :: Int -> Int -> Int
f = _
x =
(
^
f
^
1
^
)
^
2
^
^
|]
[ Nothing,
Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1)),
Nothing
],
mkTest
"nested"
[__i|
f :: Int -> Int -> Int
f = _
g :: Int -> Int
g = _
x = f (g 1) 2
^^^^ ^^^^
|]
[ Nothing,
Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "g :: Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "g :: Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1))
],
mkTest
"higher-order function"
[__i|
f :: (Int -> Int) -> Int -> Int
f = _
x = f (+ 1) 2
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: (Int -> Int) -> Int -> Int" Nothing (Just [ParameterInformation (InR (6, 16)) Nothing, ParameterInformation (InR (21, 24)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"type constraint"
[__i|
f :: (Num a) => a -> a -> a
f = _
x = f 1 2
^ ^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a. Num a => a -> a -> a" Nothing (Just [ParameterInformation (InR (24, 25)) Nothing, ParameterInformation (InR (29, 30)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> Integer -> Integer" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (16, 23)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a. Num a => a -> a -> a" Nothing (Just [ParameterInformation (InR (24, 25)) Nothing, ParameterInformation (InR (29, 30)) Nothing]) (Just (InL 1)), SignatureInformation "f :: Integer -> Integer -> Integer" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (16, 23)) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1))
],
mkTest
"type constraint with kind signatures"
[__i|
x :: IO Bool
x = pure True
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "pure :: forall (f :: Type -> Type) a. Applicative f => a -> f a" (Just $ InR $ MarkupContent MarkupKind_Markdown "Lift a value") (Just [ParameterInformation (InR (55, 56)) Nothing]) (Just (InL 0)), SignatureInformation "pure :: Bool -> IO Bool" (Just $ InR $ MarkupContent MarkupKind_Markdown "Lift a value") (Just [ParameterInformation (InR (8, 12)) Nothing]) (Just (InL 0)), SignatureInformation "pure :: forall a. a -> IO a" (Just $ InR $ MarkupContent MarkupKind_Markdown "Lift a value") (Just [ParameterInformation (InR (18, 19)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"2 type constraints"
[__i|
f :: forall a. (Eq a, Num a) => a -> a -> a
f = _
x = f True
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a. (Eq a, Num a) => a -> a -> a" Nothing (Just [ParameterInformation (InR (32, 33)) Nothing, ParameterInformation (InR (37, 38)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Bool -> Bool -> Bool" Nothing (Just [ParameterInformation (InR (5, 9)) Nothing, ParameterInformation (InR (13, 17)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"dynamic function"
[__i|
f :: Int -> Int -> Int
f = _
g :: Int -> Int -> Int
g = _
x = (if _ then f else g) 1 2
^^ ^^^ ^ ^^^ ^ ^^^^^^^^
|]
(replicate 18 Nothing),
mkTest
"very long type"
[__i|
f :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int
f = _
x = f 1
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int" Nothing (Just [ParameterInformation (InR (5, 8)) Nothing, ParameterInformation (InR (12, 15)) Nothing, ParameterInformation (InR (19, 22)) Nothing, ParameterInformation (InR (26, 29)) Nothing, ParameterInformation (InR (33, 36)) Nothing, ParameterInformation (InR (40, 43)) Nothing, ParameterInformation (InR (47, 50)) Nothing, ParameterInformation (InR (54, 57)) Nothing, ParameterInformation (InR (61, 64)) Nothing, ParameterInformation (InR (68, 71)) Nothing, ParameterInformation (InR (75, 78)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"very long type with type constraint"
[__i|
f :: Num abcdefghijklmn => abcdefghijklmn -> abcdefghijklmn -> abcdefghijklmn -> abcdefghijklmn -> abcdefghijklmn
f = _
x = f 1
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall abcdefghijklmn. Num abcdefghijklmn => abcdefghijklmn -> abcdefghijklmn -> abcdefghijklmn -> abcdefghijklmn -> abcdefghijklmn" Nothing (Just [ParameterInformation (InR (50, 64)) Nothing, ParameterInformation (InR (68, 82)) Nothing, ParameterInformation (InR (86, 100)) Nothing, ParameterInformation (InR (104, 118)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> Integer -> Integer -> Integer -> Integer" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (16, 23)) Nothing, ParameterInformation (InR (27, 34)) Nothing, ParameterInformation (InR (38, 45)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
-- TODO fix bug of wrong parameter range in the function type string
-- https://github.com/haskell/haskell-language-server/pull/4626#discussion_r2261133076
mkTestExpectFail
"middle =>"
[__i|
f :: Eq a => a -> Num b => b -> b
f = _
x = f 1 True
^ ^ ^
y = f True
^
z = f 1
^
|]
( BrokenIdeal
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> Num b => b -> b" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (39, 40)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> Num Bool => Bool -> Bool" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (28, 32)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> Num b => b -> b" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (39, 40)) Nothing]) (Just (InL 1)), SignatureInformation "f :: Integer -> Num Bool => Bool -> Bool" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (28, 32)) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> Num b => b -> b" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (39, 40)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Bool -> Num Integer => Integer -> Integer" Nothing (Just [ParameterInformation (InR (5, 9)) Nothing, ParameterInformation (InR (28, 35)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> Num b => b -> b" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (39, 40)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> Num Integer => Integer -> Integer" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (31, 38)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
]
)
( BrokenCurrent
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> Num b => b -> b" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (39, 40)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> Num Bool => Bool -> Bool" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (28, 32)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> Num b => b -> b" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (39, 40)) Nothing]) (Just (InL 1)), SignatureInformation "f :: Integer -> Num Bool => Bool -> Bool" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (28, 32)) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> Num b => b -> b" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (39, 40)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Bool -> Num Integer => Integer -> Integer" Nothing (Just [ParameterInformation (InR (5, 9)) Nothing, ParameterInformation (InR (28, 35)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> Num b => b -> b" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (39, 40)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> Num Integer => Integer -> Integer" Nothing (Just [ParameterInformation (InR (20, 27)) Nothing, ParameterInformation (InR (31, 38)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
]
),
mkTest
"=> in parameter"
[__i|
f :: Eq a => a -> (Num b => b -> b) -> a
f = _
x = f 1
^ ^
y = f 1 negate
^ ^
|]
( let typ =
if ghcVersion <= GHC98
then "f :: Integer -> (Num Any => Any -> Any) -> Integer"
else "f :: Integer -> (Num (ZonkAny 0) => ZonkAny 0 -> ZonkAny 0) -> Integer"
range = if ghcVersion <= GHC98 then (17, 38) else (17, 58)
in [ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> (Num b => b -> b) -> a" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (31, 46)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> (Num b => b -> b) -> Integer" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (17, 32)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> (Num b => b -> b) -> a" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (31, 46)) Nothing]) (Just (InL 0)), SignatureInformation typ Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR range) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. Eq a => a -> (Num b => b -> b) -> a" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (31, 46)) Nothing]) (Just (InL 1)), SignatureInformation typ Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR range) Nothing]) (Just (InL 1))] (Just 0) (Just (InL 1))
]
),
mkTest
"RankNTypes(forall in middle)"
[__i|
f :: Maybe a -> forall b. (a, b) -> b
f = _
x1 = f Nothing
^ ^
x2 = f (Just True)
^
x3 = f Nothing (1, True)
^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a. Maybe a -> forall b. (a, b) -> b" Nothing (Just [ParameterInformation (InR (15, 22)) Nothing, ParameterInformation (InR (36, 42)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Maybe a -> forall b. (a, b) -> b" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (26, 32)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a. Maybe a -> forall b. (a, b) -> b" Nothing (Just [ParameterInformation (InR (15, 22)) Nothing, ParameterInformation (InR (36, 42)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Maybe Bool -> forall b. (Bool, b) -> b" Nothing (Just [ParameterInformation (InR (5, 15)) Nothing, ParameterInformation (InR (29, 38)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a. Maybe a -> forall b. (a, b) -> b" Nothing (Just [ParameterInformation (InR (15, 22)) Nothing, ParameterInformation (InR (36, 42)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Maybe Integer -> forall b. (Integer, b) -> b" Nothing (Just [ParameterInformation (InR (5, 18)) Nothing, ParameterInformation (InR (32, 44)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
-- TODO fix bug of wrong parameter range in the function type string
-- https://github.com/haskell/haskell-language-server/pull/4626#discussion_r2261133076
mkTestExpectFail
"RankNTypes(forall in middle), another"
[__i|
f :: l -> forall a. a -> a
f = _
x = f 1
^ ^
|]
( BrokenIdeal
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall l. l -> forall a. a -> a" Nothing (Just [ParameterInformation (InR (15, 16)) Nothing, ParameterInformation (InR (30, 31)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> forall a. a -> a" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (26, 27)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
]
)
( BrokenCurrent
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall l. l -> forall a. a -> a" Nothing (Just [ParameterInformation (InR (25, 26)) Nothing, ParameterInformation (InR (30, 31)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> forall a. a -> a" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (26, 27)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
]
),
-- TODO fix bug of wrong parameter range in the function type string
-- https://github.com/haskell/haskell-language-server/pull/4626#discussion_r2261133076
mkTestExpectFail
"RankNTypes(forall in middle), again"
[__i|
f :: a -> forall a. a -> a
f = _
x = f 1
^ ^
|]
( BrokenIdeal
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a. a -> forall a1. a1 -> a1" Nothing (Just [ParameterInformation (InR (15, 16)) Nothing, ParameterInformation (InR (31, 33)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> forall a. a -> a" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (26, 27)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
]
)
( BrokenCurrent
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a. a -> forall a1. a1 -> a1" Nothing (Just [ParameterInformation (InR (27, 28)) Nothing, ParameterInformation (InR (31, 32)) Nothing]) (Just (InL 0)), SignatureInformation "f :: Integer -> forall a. a -> a" Nothing (Just [ParameterInformation (InR (5, 12)) Nothing, ParameterInformation (InR (26, 27)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
]
),
mkTest
"LinearTypes"
[__i|
{-\# LANGUAGE LinearTypes \#-}
f :: (a -> b) %1 -> a -> b
f = _
x1 = f negate
^ ^
x2 = f _ 1
^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. (a -> b) %1 -> a -> b" Nothing (Just [ParameterInformation (InR (18, 24)) Nothing, ParameterInformation (InR (32, 33)) Nothing]) (Just (InL 0)), SignatureInformation "f :: (Integer -> Integer) %1 -> Integer -> Integer" Nothing (Just [ParameterInformation (InR (6, 24)) Nothing, ParameterInformation (InR (32, 39)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0)),
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b. (a -> b) %1 -> a -> b" Nothing (Just [ParameterInformation (InR (18, 24)) Nothing, ParameterInformation (InR (32, 33)) Nothing]) (Just (InL 0)), SignatureInformation "f :: (Integer -> b) %1 -> Integer -> b" Nothing (Just [ParameterInformation (InR (6, 18)) Nothing, ParameterInformation (InR (26, 33)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"function documentation"
[__i|
-- |The 'f' function does something to a bool value.
f :: Bool -> Bool
f = _
x = f True
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Bool -> Bool" (Just $ InR $ MarkupContent MarkupKind_Markdown "The `f` function does something to a bool value") (Just [ParameterInformation (InR (5, 9)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"function and parameters documentation"
[__i|
-- |Doc for function 'f'.
f ::
-- | The first 'Bool' parameter
Bool ->
-- | The second 'Int' parameter
Int ->
-- | The return value
Bool
f = _
x = f True 1
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: Bool -> Int -> Bool" (Just $ InR $ MarkupContent MarkupKind_Markdown "Doc for function `f`") (Just [ParameterInformation (InR (5, 9)) (Just $ InR $ MarkupContent MarkupKind_Markdown "The first `Bool` parameter"), ParameterInformation (InR (13, 16)) (Just $ InR $ MarkupContent MarkupKind_Markdown "The second `Int` parameter")]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"imported function with no documentation"
[__i|
x = even 1
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "even :: forall a. Integral a => a -> Bool" (Just $ InR $ MarkupContent MarkupKind_Markdown "") (Just [ParameterInformation (InR (32, 33)) Nothing]) (Just (InL 0)), SignatureInformation "even :: Integer -> Bool" (Just $ InR $ MarkupContent MarkupKind_Markdown "") (Just [ParameterInformation (InR (8, 15)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"imported function with parameter documentation"
[__i|
import Language.Haskell.TH.Lib (mkBytes)
x = mkBytes _
^ ^
|]
[ Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "mkBytes :: ForeignPtr Word8 -> Word -> Word -> Bytes" (Just $ InR $ MarkupContent MarkupKind_Markdown "Create a Bytes datatype representing raw bytes to be embedded into the") (Just [ParameterInformation (InR (11, 27)) (Just $ InR $ MarkupContent MarkupKind_Markdown "Pointer to the data"), ParameterInformation (InR (31, 35)) (Just $ InR $ MarkupContent MarkupKind_Markdown "Offset from the pointer"), ParameterInformation (InR (39, 43)) (Just $ InR $ MarkupContent MarkupKind_Markdown "Number of bytes")]) (Just (InL 0))] (Just 0) (Just (InL 0))
],
mkTest
"TypeApplications"
[__i|
f :: a -> b -> c
f = _
x = f @Int @_ 1 True
^ ^ ^ ^
|]
[ Nothing,
Nothing,
Nothing,
Just $ SimilarSignatureHelp $ SignatureHelp [SignatureInformation "f :: forall a b c. a -> b -> c" Nothing (Just [ParameterInformation (InR (19, 20)) Nothing, ParameterInformation (InR (24, 25)) Nothing]) (Just (InL 0))] (Just 0) (Just (InL 0))
]
]
mkTest :: TestName -> Text -> [Maybe SimilarSignatureHelp] -> TestTree
mkTest name sourceCode expectedSignatureHelps =
parameterisedCursorTest
name
sourceCode
expectedSignatureHelps
getSignatureHelpFromSession
mkTestExpectFail ::
TestName ->
Text ->
ExpectBroken 'Ideal [Maybe SimilarSignatureHelp] ->
ExpectBroken 'Current [Maybe SimilarSignatureHelp] ->
TestTree
mkTestExpectFail name sourceCode _idealSignatureHelps = unCurrent >>> mkTest name sourceCode
getSignatureHelpFromSession :: Text -> PosPrefixInfo -> IO (Maybe SimilarSignatureHelp)
getSignatureHelpFromSession sourceCode (PosPrefixInfo _ _ _ position) =
let fileName = "A.hs"
plugin = mkPluginTestDescriptor descriptor "signatureHelp"
virtualFileTree = mkVirtualFileTreeWithSingleFile fileName sourceCode
in runSessionWithServerInTmpDir def plugin virtualFileTree $ do
doc <- openDoc fileName "haskell"
(fmap . fmap) SimilarSignatureHelp (getSignatureHelp doc position)
mkVirtualFileTreeWithSingleFile :: FilePath -> Text -> VirtualFileTree
mkVirtualFileTreeWithSingleFile fileName sourceCode =
let testDataDir = "/not-used-dir"
in mkVirtualFileTree
testDataDir
[ directCradle [T.pack fileName],
file fileName (text sourceCode)
]
newtype SimilarSignatureHelp = SimilarSignatureHelp SignatureHelp
deriving newtype (Show)
-- custom Eq to ignore some details, such as added doc string
-- not symmetry
instance Eq SimilarSignatureHelp where
SimilarSignatureHelp
actualSignatureHelp@( SignatureHelp
actualSignatureInformations
actualActiveSignature
actualActiveParameter
)
== SimilarSignatureHelp
expectedSignatureHelp@( SignatureHelp
expectedSignatureInformations
expectedActiveSignature
expectedActiveParameter
)
| actualSignatureHelp == expectedSignatureHelp = True
| actualActiveSignature == expectedActiveSignature
&& actualActiveParameter == expectedActiveParameter =
actualSignatureInformations ~= expectedSignatureInformations
| otherwise = False
class IsSimilar a where
(~=) :: a -> a -> Bool
instance IsSimilar SignatureInformation where
actualSignatureInformation@( SignatureInformation
actualLabel
actualDocumentation
actualParameters
actualActiveParameter
)
~= expectedSignatureInformation@( SignatureInformation
expectedLabel
expectedDocumentation
expectedParameters
expectedActiveParameter
)
| actualSignatureInformation == expectedSignatureInformation = True
| actualLabel == expectedLabel && actualActiveParameter == expectedActiveParameter =
actualDocumentation ~= expectedDocumentation
&& actualParameters ~= expectedParameters
| otherwise = False
instance IsSimilar ParameterInformation where
actualParameterInformation@(ParameterInformation actualLabel actualDocumentation)
~= expectedParameterInformation@(ParameterInformation expectedLabel expectedDocumentation)
| actualParameterInformation == expectedParameterInformation = True
| actualLabel == expectedLabel = actualDocumentation ~= expectedDocumentation
| otherwise = False
instance IsSimilar MarkupContent where
actualMarkupContent@(MarkupContent actualKind actualText)
~= expectedMarkupContent@(MarkupContent expectedKind expectedText)
| actualMarkupContent == expectedMarkupContent = True
| actualKind == expectedKind = actualText ~= expectedText
| otherwise = False
instance IsSimilar Text where
actualText ~= expectedText = expectedText `T.isInfixOf` actualText
instance (IsSimilar a) => IsSimilar [a] where
[] ~= [] = True
(x : xs) ~= (y : ys) = x ~= y && xs ~= ys
_ ~= _ = False
instance (IsSimilar a) => IsSimilar (Maybe a) where
Nothing ~= Nothing = True
Just x ~= Just y = x ~= y
_ ~= _ = False
instance (IsSimilar a, IsSimilar b) => IsSimilar (a |? b) where
InL x ~= InL y = x ~= y
InR x ~= InR y = x ~= y
_ ~= _ = False
-- TODO use the one from lsp-test when we have https://github.com/haskell/lsp/pull/621
-- | Returns the signature help at the specified position.
getSignatureHelp :: TextDocumentIdentifier -> Position -> Session (Maybe SignatureHelp)
getSignatureHelp doc pos =
let params = SignatureHelpParams doc pos Nothing Nothing
in nullToMaybe . getResponseResult <$> request SMethod_TextDocumentSignatureHelp params
where
getResponseResult rsp =
case rsp ^. L.result of
Right x -> x
Left err -> throw $ UnexpectedResponseError (fromJust $ rsp ^. L.id) err