Skip to content

Commit

Permalink
Parenthesize operators when exporting (haskell/ghcide#906)
Browse files Browse the repository at this point in the history
* Parenthesize operators when exporting

* Add tests

* Only consider if the head is an operator letter
  • Loading branch information
berberman authored Nov 13, 2020
1 parent d3806a3 commit 81394a8
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 2 deletions.
12 changes: 10 additions & 2 deletions ghcide/src/Development/IDE/Plugin/CodeAction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,14 @@ suggestExportUnusedTopBinding srcOpt ParsedModule{pm_parsed_source = L _ HsModul
_ -> False
needsComma _ _ = False

opLetter :: String
opLetter = ":!#$%&*+./<=>?@\\^|-~"

parenthesizeIfNeeds :: Bool -> T.Text -> T.Text
parenthesizeIfNeeds needsTypeKeyword x
| T.head x `elem` opLetter = (if needsTypeKeyword then "type " else "") <> "(" <> x <>")"
| otherwise = x

getLocatedRange :: Located a -> Maybe Range
getLocatedRange = srcSpanToRange . getLoc

Expand All @@ -386,9 +394,9 @@ suggestExportUnusedTopBinding srcOpt ParsedModule{pm_parsed_source = L _ HsModul
in loc >= Just l && loc <= Just r

printExport :: ExportsAs -> T.Text -> T.Text
printExport ExportName x = x
printExport ExportName x = parenthesizeIfNeeds False x
printExport ExportPattern x = "pattern " <> x
printExport ExportAll x = x <> "(..)"
printExport ExportAll x = parenthesizeIfNeeds True x <> "(..)"

isTopLevel :: Range -> Bool
isTopLevel l = (_character . _start) l == 0
Expand Down
78 changes: 78 additions & 0 deletions ghcide/test/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2075,6 +2075,84 @@ exportUnusedTests = testGroup "export unused actions"
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "module A (f) where"
, "a `f` b = ()"])
, testSession "function operator" $ template
(T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "module A () where"
, "(<|) = ($)"])
(R 2 0 2 9)
"Export ‘<|’"
(Just $ T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "module A ((<|)) where"
, "(<|) = ($)"])
, testSession "type synonym operator" $ template
(T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A () where"
, "type (:<) = ()"])
(R 3 0 3 13)
"Export ‘:<’"
(Just $ T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A ((:<)) where"
, "type (:<) = ()"])
, testSession "type family operator" $ template
(T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeFamilies #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A () where"
, "type family (:<)"])
(R 4 0 4 15)
"Export ‘:<’"
(Just $ T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeFamilies #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A (type (:<)(..)) where"
, "type family (:<)"])
, testSession "typeclass operator" $ template
(T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A () where"
, "class (:<) a"])
(R 3 0 3 11)
"Export ‘:<’"
(Just $ T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A (type (:<)(..)) where"
, "class (:<) a"])
, testSession "newtype operator" $ template
(T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A () where"
, "newtype (:<) = Foo ()"])
(R 3 0 3 20)
"Export ‘:<’"
(Just $ T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A (type (:<)(..)) where"
, "newtype (:<) = Foo ()"])
, testSession "data type operator" $ template
(T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A () where"
, "data (:<) = Foo ()"])
(R 3 0 3 17)
"Export ‘:<’"
(Just $ T.unlines
[ "{-# OPTIONS_GHC -Wunused-top-binds #-}"
, "{-# LANGUAGE TypeOperators #-}"
, "module A (type (:<)(..)) where"
, "data (:<) = Foo ()"])
]
]
where
Expand Down

0 comments on commit 81394a8

Please sign in to comment.