@@ -1561,15 +1561,57 @@ mkRenameEdit contents range name =
1561
1561
-- require understanding both the precedence of the context of the hole and of
1562
1562
-- the signature itself. Inserting them (almost) unconditionally is ugly but safe.
1563
1563
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 <> " )"
1565
1567
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
+ -- If we're completing something like ‘foo :: _’ parens can be safely omitted.
1571
+ isToplevelSig = errorMessageRefersToToplevelHole rest
1572
+ -- Parenthesize type applications, e.g. (Maybe Char).
1573
+ isApp = T. any isSpace sig
1574
+ -- Do not add extra parentheses to lists, tuples and already parenthesized types.
1575
+ enclosed = not (T. null sig) && (T. head sig, T. last sig) `elem` [(' (' , ' )' ), (' [' , ' ]' )]
1576
+
1577
+ -- | Detect whether user wrote something like @foo :: _@ or @foo :: (_, Int)@.
1578
+ -- The former is considered toplevel case for which the function returns 'True',
1579
+ -- the latter is not toplevel and the returned value is 'False'.
1580
+ --
1581
+ -- When type hole is at toplevel then there’s a line starting with
1582
+ -- "• In the type signature" which ends with " :: _" like in the
1583
+ -- following snippet:
1584
+ --
1585
+ -- source/library/Language/Haskell/Brittany/Internal.hs:131:13: error:
1586
+ -- • Found type wildcard ‘_’ standing for ‘HsDecl GhcPs’
1587
+ -- To use the inferred type, enable PartialTypeSignatures
1588
+ -- • In the type signature: decl :: _
1589
+ -- In an equation for ‘splitAnnots’:
1590
+ -- splitAnnots m@HsModule {hsmodAnn, hsmodDecls}
1591
+ -- = undefined
1592
+ -- where
1593
+ -- ann :: SrcSpanAnnA
1594
+ -- decl :: _
1595
+ -- L ann decl = head hsmodDecls
1596
+ -- • Relevant bindings include
1597
+ -- [REDACTED]
1598
+ --
1599
+ -- When type hole is not at toplevel there’s a stack of where
1600
+ -- the hole was located ending with "In the type signature":
1601
+ --
1602
+ -- source/library/Language/Haskell/Brittany/Internal.hs:130:20: error:
1603
+ -- • Found type wildcard ‘_’ standing for ‘GhcPs’
1604
+ -- To use the inferred type, enable PartialTypeSignatures
1605
+ -- • In the first argument of ‘HsDecl’, namely ‘_’
1606
+ -- In the type ‘HsDecl _’
1607
+ -- In the type signature: decl :: HsDecl _
1608
+ -- • Relevant bindings include
1609
+ -- [REDACTED]
1610
+ errorMessageRefersToToplevelHole :: T. Text -> Bool
1611
+ errorMessageRefersToToplevelHole msg =
1612
+ not (T. null prefix) && " :: _" `T.isSuffixOf` T. takeWhile (/= ' \n ' ) rest
1613
+ where
1614
+ (prefix, rest) = T. breakOn " • In the type signature:" msg
1573
1615
1574
1616
extractRenamableTerms :: T. Text -> [T. Text ]
1575
1617
extractRenamableTerms msg
0 commit comments