on master help sign in
Start adapting Reporting.Helpers from Text to Name values
a930922Evan Czaplicki
src/Reporting/Helpers.hs+87−87
@@ -1,21 +1,22 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Helpers
3module Reporting.Helpers
4− ( (|>)
4+ ( textToDoc
5− -- re-exports
5+ , nameToDoc
6− , Doc, (<+>), (<>), cat, dullyellow, fillSep, green, hang
7− , hsep, indent, parens, sep, text, underline, vcat
8− -- custom helpers
9− , i2t
10− , functionName, args, moreArgs
6+ , args, moreArgs
11− , toSimpleHint, toFancyHint, hintLink
7+ , toSimpleNote, toSimpleHint, toFancyHint
12− , stack, reflowParagraph
8+ , link, reflowLink
9+ , stack, reflow
13 , commaSep, capitalize, ordinalize, drawCycle
10 , commaSep, capitalize, ordinalize, drawCycle
14 , findPotentialTypos, findTypoPairs, vetTypos
11 , findPotentialTypos, findTypoPairs, vetTypos
15 , nearbyNames, distance, maybeYouWant, maybeYouWant'
12 , nearbyNames, distance, maybeYouWant, maybeYouWant'
13+ -- re-exports
14+ , Doc, (<+>), (<>), black, cat, dullyellow, fillSep, green, hang, hardline
15+ , hcat, hsep, indent, magenta, parens, sep, text, underline, vcat
16 )
16 )
17 where
17 where
18
18
19+
19import Data.Function (on)
20import Data.Function (on)
20import qualified Data.Char as Char
21import qualified Data.Char as Char
21import qualified Data.List as List
22import qualified Data.List as List
@@ -24,67 +25,51 @@ import Data.Monoid ((<>))
24import qualified Data.Set as Set
25import qualified Data.Set as Set
25import qualified Data.Text as Text
26import qualified Data.Text as Text
26import Data.Text (Text)
27import Data.Text (Text)
28+import qualified Elm.Name as N
27import qualified Text.EditDistance as Dist
29import qualified Text.EditDistance as Dist
28import qualified Text.PrettyPrint.ANSI.Leijen as P
30import qualified Text.PrettyPrint.ANSI.Leijen as P
29−import Text.PrettyPrint.ANSI.Leijen hiding ((<>), text)
31+import Text.PrettyPrint.ANSI.Leijen hiding ((<>))
30
32
31−import qualified AST.Helpers as Help
32import qualified Elm.Compiler.Version as Compiler
33import qualified Elm.Compiler.Version as Compiler
33import qualified Elm.Package as Pkg
34import qualified Elm.Package as Pkg
34
35
35
36
36
37
37−-- PIPES
38−
39−
40−(|>) :: a -> (a -> b) -> b
41−(|>) x f =
42− f x
43−
44−
45−infixl 0 |>
46−
47−
48−
49-- DOC HELPERS
38-- DOC HELPERS
50
39
51
40
52−text :: Text -> Doc
41+textToDoc :: Text -> Doc
53−text msg =
42+textToDoc msg =
54− P.text (Text.unpack msg)
43+ text (Text.unpack msg)
55
44
56
45
57−i2t :: Int -> Text
46+nameToDoc :: N.Name -> Doc
58−i2t n =
47+nameToDoc name =
59− Text.pack (show n)
48+ text (N.toString name)
60
49
61
50
62−functionName :: Text -> Text
63−functionName opName =
64− if Help.isOp opName then
65− "(" <> opName <> ")"
66−
67− else
68− "`" <> opName <> "`"
69−
70−
71−args :: Int -> Text
51+args :: Int -> String
72args n =
52args n =
73− i2t n <> if n == 1 then " argument" else " arguments"
53+ show n <> if n == 1 then " argument" else " arguments"
74
54
75
55
76−moreArgs :: Int -> Text
56+moreArgs :: Int -> String
77moreArgs n =
57moreArgs n =
78− i2t n <> " more" <> if n == 1 then " argument" else " arguments"
58+ show n <> " more" <> if n == 1 then " argument" else " arguments"
79
59
80
60
81
61
82-- HINTS
62-- HINTS
83
63
84
64
65+toSimpleNote :: String -> Doc
66+toSimpleNote message =
67+ fillSep ((underline (text "Note") <> ":") : map text (words message))
68+
69+
85−toSimpleHint :: Text -> Doc
70+toSimpleHint :: String -> Doc
86−toSimpleHint txt =
71+toSimpleHint message =
87− toFancyHint (map text (Text.words txt))
72+ toFancyHint (map text (words message))
88
73
89
74
90toFancyHint :: [Doc] -> Doc
75toFancyHint :: [Doc] -> Doc
@@ -92,11 +77,26 @@ toFancyHint chunks =
92 fillSep (underline (text "Hint") <> ":" : chunks)
77 fillSep (underline (text "Hint") <> ":" : chunks)
93
78
94
79
95−hintLink :: Text -> Text
80+link :: Doc -> String -> String -> String -> Doc
81+link word before fileName after =
82+ fillSep $
83+ (underline word <> ":")
84+ : map text (words before)
85+ ++ P.text (makeLink fileName)
86+ : map text (words after)
87+
88+
89+makeLink :: String -> String
96−hintLink fileName =
90+makeLink fileName =
97− "<https://github.com/elm-lang/elm-compiler/blob/"
98− <> Text.pack (Pkg.versionToString Compiler.version)
91+ "<http://elm-lang.org/hints/" <> Pkg.versionToString Compiler.version <> "/" <> fileName <> ".md>"
99− <> "/hints/" <> fileName <> ".md>"
92+
93+
94+reflowLink :: String -> String -> String -> Doc
95+reflowLink before fileName after =
96+ fillSep $
97+ map text (words before)
98+ ++ P.text (makeLink fileName)
99+ : map text (words after)
100
100
101
101
102stack :: [Doc] -> Doc
102stack :: [Doc] -> Doc
@@ -109,22 +109,26 @@ stack chunks =
109 List.foldl' (\a b -> a <> hardline <> hardline <> b) doc docs
109 List.foldl' (\a b -> a <> hardline <> hardline <> b) doc docs
110
110
111
111
112−reflowParagraph :: Text -> Doc
112+reflow :: String -> Doc
113−reflowParagraph paragraph =
113+reflow paragraph =
114− fillSep (map text (Text.words paragraph))
114+ fillSep (map text (words paragraph))
115
115
116
116
117−commaSep :: [Text] -> Text
117+commaSep :: Doc -> (Doc -> Doc) -> [Doc] -> [Doc]
118−commaSep tokens =
118+commaSep conjunction addStyle names =
119− case tokens of
119+ case names of
120− [token] ->
120+ [name] ->
121− " " <> token
121+ [ addStyle name ]
122
122
123− [token1,token2] ->
123+ [name1,name2] ->
124− " " <> token1 <> " and " <> token2
124+ [ addStyle name1, conjunction, addStyle name2 ]
125
125
126 _ ->
126 _ ->
127− " " <> Text.intercalate ", " (init tokens) <> ", and " <> last tokens
127+ map (\name -> addStyle name <> ",") (init names)
128+ ++
129+ [ conjunction
130+ , addStyle (last names)
131+ ]
128
132
129
133
130capitalize :: Text -> Text
134capitalize :: Text -> Text
@@ -137,7 +141,7 @@ capitalize txt =
137 Text.cons (Char.toUpper c) rest
141 Text.cons (Char.toUpper c) rest
138
142
139
143
140−ordinalize :: Int -> Text
144+ordinalize :: Int -> String
141ordinalize number =
145ordinalize number =
142 let
146 let
143 remainder10 =
147 remainder10 =
@@ -153,24 +157,24 @@ ordinalize number =
153 | remainder10 == 3 = "rd"
157 | remainder10 == 3 = "rd"
154 | otherwise = "th"
158 | otherwise = "th"
155 in
159 in
156− i2t number <> ending
160+ show number <> ending
157
161
158
162
159
163
160−drawCycle :: [Text] -> Doc
164+drawCycle :: [N.Name] -> Doc
161drawCycle names =
165drawCycle names =
162 let
166 let
163 topLine =
167 topLine =
164− text "┌─────┐"
168+ "┌─────┐"
165
169
166 nameLine name =
170 nameLine name =
167− text "│ " <> dullyellow (text name)
171+ "│ " <> dullyellow (textToDoc name)
168
172
169 midLine =
173 midLine =
170− text "│ ↓"
174+ "│ ↓"
171
175
172 bottomLine =
176 bottomLine =
173− text "└─────┘"
177+ "└─────┘"
174 in
178 in
175 vcat (topLine : List.intersperse midLine (map nameLine names) ++ [ bottomLine ])
179 vcat (topLine : List.intersperse midLine (map nameLine names) ++ [ bottomLine ])
176
180
@@ -179,12 +183,12 @@ drawCycle names =
179-- FIND TYPOS
183-- FIND TYPOS
180
184
181
185
182−findPotentialTypos :: [Text] -> Text -> [Text]
186+findPotentialTypos :: [String] -> String -> [String]
183findPotentialTypos knownNames badName =
187findPotentialTypos knownNames badName =
184 filter ((==1) . distance badName) knownNames
188 filter ((==1) . distance badName) knownNames
185
189
186
190
187−findTypoPairs :: [Text] -> [Text] -> [(Text, Text)]
191+findTypoPairs :: [String] -> [String] -> [(String, String)]
188findTypoPairs leftOnly rightOnly =
192findTypoPairs leftOnly rightOnly =
189 let
193 let
190 veryNear leftName =
194 veryNear leftName =
@@ -193,7 +197,7 @@ findTypoPairs leftOnly rightOnly =
193 concatMap veryNear leftOnly
197 concatMap veryNear leftOnly
194
198
195
199
196−vetTypos :: [(Text, Text)] -> Maybe (Set.Set Text, Set.Set Text)
200+vetTypos :: [(String, String)] -> Maybe (Set.Set String, Set.Set String)
197vetTypos potentialTypos =
201vetTypos potentialTypos =
198 let
202 let
199 tallyNames (ln, rn) (lc, rc) =
203 tallyNames (ln, rn) (lc, rc) =
@@ -204,7 +208,7 @@ vetTypos potentialTypos =
204 (leftCounts, rightCounts) =
208 (leftCounts, rightCounts) =
205 foldr tallyNames (Map.empty, Map.empty) potentialTypos
209 foldr tallyNames (Map.empty, Map.empty) potentialTypos
206
210
207− acceptable :: Map.Map Text Int -> Bool
211+ acceptable :: Map.Map String Int -> Bool
208 acceptable counts =
212 acceptable counts =
209 not (Map.null counts)
213 not (Map.null counts)
210 &&
214 &&
@@ -221,32 +225,28 @@ vetTypos potentialTypos =
221-- NEARBY NAMES
225-- NEARBY NAMES
222
226
223
227
224−nearbyNames :: (a -> Text) -> a -> [a] -> [a]
228+nearbyNames :: (a -> String) -> a -> [a] -> [a]
225nearbyNames format name names =
229nearbyNames format name names =
226 let editDistance =
230 let editDistance =
227− if Text.length (format name) < 3 then 1 else 2
231+ if length (format name) < 3 then 1 else 2
228 in
232 in
229− names
233+ map snd $
234+ filter ( (<= editDistance) . abs . fst ) $
235+ List.sortBy (compare `on` fst) $
230− |> map (\x -> (distance (format name) (format x), x))
236+ map (\x -> (distance (format name) (format x), x)) names
231− |> List.sortBy (compare `on` fst)
232− |> filter ( (<= editDistance) . abs . fst )
233− |> map snd
234
237
235
238
236−distance :: Text -> Text -> Int
239+distance :: String -> String -> Int
237distance x y =
240distance x y =
238− Dist.restrictedDamerauLevenshteinDistance
241+ Dist.restrictedDamerauLevenshteinDistance Dist.defaultEditCosts x y
239− Dist.defaultEditCosts
240− (Text.unpack x)
241− (Text.unpack y)
242
242
243
243
244−maybeYouWant :: Maybe Doc -> [Text] -> Doc
244+maybeYouWant :: Maybe Doc -> [N.Name] -> Doc
245maybeYouWant maybeStarter suggestions =
245maybeYouWant maybeStarter suggestions =
246 maybe P.empty id (maybeYouWant' maybeStarter suggestions)
246 maybe P.empty id (maybeYouWant' maybeStarter suggestions)
247
247
248
248
249−maybeYouWant' :: Maybe Doc -> [Text] -> Maybe Doc
249+maybeYouWant' :: Maybe Doc -> [N.Name] -> Maybe Doc
250maybeYouWant' maybeStarter suggestions =
250maybeYouWant' maybeStarter suggestions =
251 case suggestions of
251 case suggestions of
252 [] ->
252 [] ->
@@ -255,5 +255,5 @@ maybeYouWant' maybeStarter suggestions =
255 _:_ ->
255 _:_ ->
256 Just $ stack $
256 Just $ stack $
257 [ maybe id (<+>) maybeStarter "Maybe you want one of the following?"
257 [ maybe id (<+>) maybeStarter "Maybe you want one of the following?"
258− , P.indent 4 $ P.vcat $ map (P.dullyellow . text) (take 4 suggestions)
258+ , P.indent 4 $ P.vcat $ map (P.dullyellow . nameToDoc) (take 4 suggestions)
259 ]
259 ]