Skip to content

Commit 73c2305

Browse files
committed
Omit more parens for wildcard type signature (#2929)
This is a followup to #2764.
1 parent 1a0d4a7 commit 73c2305

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

ghcide/src/Development/IDE/Plugin/CodeAction.hs

+12-8
Original file line numberDiff line numberDiff line change
@@ -1561,15 +1561,19 @@ mkRenameEdit contents range name =
15611561
-- require understanding both the precedence of the context of the hole and of
15621562
-- the signature itself. Inserting them (almost) unconditionally is ugly but safe.
15631563
extractWildCardTypeSignature :: T.Text -> T.Text
1564-
extractWildCardTypeSignature msg = (if enclosed || not application then id else bracket) signature
1564+
extractWildCardTypeSignature msg
1565+
| enclosed || not isApp || isToplevelSig = sig
1566+
| otherwise = "(" <> sig <> ")"
15651567
where
1566-
msgSigPart = snd $ T.breakOnEnd "standing for " msg
1567-
signature = T.takeWhile (/='') . T.dropWhile (=='') . T.dropWhile (/='') $ msgSigPart
1568-
-- parenthesize type applications, e.g. (Maybe Char)
1569-
application = any isSpace . T.unpack $ signature
1570-
-- do not add extra parentheses to lists, tuples and already parenthesized types
1571-
enclosed = not (T.null signature) && (T.head signature, T.last signature) `elem` [('(',')'), ('[',']')]
1572-
bracket = ("(" `T.append`) . (`T.append` ")")
1568+
msgSigPart = snd $ T.breakOnEnd "standing for " msg
1569+
(sig, rest) = T.span (/='') . T.dropWhile (=='') . T.dropWhile (/='') $ msgSigPart
1570+
(prefix, rest') = T.breakOn "• In the type signature:" rest
1571+
-- If we're completing something like ‘foo :: _’ parens can be safely omitted.
1572+
isToplevelSig = not (T.null prefix) && " :: _" `T.isSuffixOf` T.takeWhile (/= '\n') rest'
1573+
-- Parenthesize type applications, e.g. (Maybe Char).
1574+
isApp = T.any isSpace sig
1575+
-- Do not add extra parentheses to lists, tuples and already parenthesized types.
1576+
enclosed = not (T.null sig) && (T.head sig, T.last sig) `elem` [('(', ')'), ('[', ']')]
15731577

15741578
extractRenamableTerms :: T.Text -> [T.Text]
15751579
extractRenamableTerms msg

ghcide/test/exe/Main.hs

+40-3
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,7 @@ typeWildCardActionTests = testGroup "type wildcard actions"
11961196
[ "func :: _"
11971197
, "func x = x"
11981198
]
1199-
[ "func :: (p -> p)"
1199+
[ "func :: p -> p"
12001200
, "func x = x"
12011201
]
12021202
, testUseTypeSignature "local signature"
@@ -1212,11 +1212,11 @@ typeWildCardActionTests = testGroup "type wildcard actions"
12121212
, " y = x * 2"
12131213
, " in y"
12141214
]
1215-
, testUseTypeSignature "multi-line message"
1215+
, testUseTypeSignature "multi-line message 1"
12161216
[ "func :: _"
12171217
, "func x y = x + y"
12181218
]
1219-
[ "func :: (Integer -> Integer -> Integer)"
1219+
[ "func :: Integer -> Integer -> Integer"
12201220
, "func x y = x + y"
12211221
]
12221222
, testUseTypeSignature "type in parentheses"
@@ -1240,6 +1240,43 @@ typeWildCardActionTests = testGroup "type wildcard actions"
12401240
[ "func :: IO ()"
12411241
, "func = putChar 'H'"
12421242
]
1243+
, testUseTypeSignature "no spaces around '::'"
1244+
[ "func::_"
1245+
, "func x y = x + y"
1246+
]
1247+
[ "func::Integer -> Integer -> Integer"
1248+
, "func x y = x + y"
1249+
]
1250+
, testGroup "add parens if hole is part of bigger type"
1251+
[ testUseTypeSignature "subtype 1"
1252+
[ "func :: _ -> Integer -> Integer"
1253+
, "func x y = x + y"
1254+
]
1255+
[ "func :: Integer -> Integer -> Integer"
1256+
, "func x y = x + y"
1257+
]
1258+
, testUseTypeSignature "subtype 2"
1259+
[ "func :: Integer -> _ -> Integer"
1260+
, "func x y = x + y"
1261+
]
1262+
[ "func :: Integer -> Integer -> Integer"
1263+
, "func x y = x + y"
1264+
]
1265+
, testUseTypeSignature "subtype 3"
1266+
[ "func :: Integer -> Integer -> _"
1267+
, "func x y = x + y"
1268+
]
1269+
[ "func :: Integer -> Integer -> Integer"
1270+
, "func x y = x + y"
1271+
]
1272+
, testUseTypeSignature "subtype 4"
1273+
[ "func :: Integer -> _"
1274+
, "func x y = x + y"
1275+
]
1276+
[ "func :: Integer -> (Integer -> Integer)"
1277+
, "func x y = x + y"
1278+
]
1279+
]
12431280
]
12441281
where
12451282
-- | Test session of given name, checking action "Use type signature..."

0 commit comments

Comments
 (0)