{-# LANGUAGE CPP #-}
module Language.Haskell.GHC.ExactPrint.Lookup
  (
    keywordToString
#if __GLASGOW_HASKELL__ <= 710
  , unicodeString
#endif
  ) where

import Language.Haskell.GHC.ExactPrint.Types
import qualified GHC (AnnKeywordId(..))
#if __GLASGOW_HASKELL__ <= 710
import Data.Maybe
#endif

-- | Maps `AnnKeywordId` to the corresponding String representation.
-- There is no specific mapping for the following constructors.
-- `AnnOpen`, `AnnClose`, `AnnVal`, `AnnPackageName`, `AnnHeader`, `AnnFunId`,
-- `AnnInfix`
keywordToString :: KeywordId -> String
keywordToString :: KeywordId -> String
keywordToString KeywordId
kw =
  let mkErr :: a -> a
mkErr a
x = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"keywordToString: missing case for:" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
x
  in
  case KeywordId
kw of
      -- Specifically handle all cases so that there are pattern match
      -- warnings if new constructors are added.
      AnnComment Comment
_      -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      AnnString String
_       -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
#if __GLASGOW_HASKELL__ >= 900
      (AnnEofPos       ) -> mkErr kw
#endif
#if __GLASGOW_HASKELL__ <= 710
      AnnUnicode kw'    -> keywordToString (G kw')
#endif
      KeywordId
AnnSemiSep        -> String
";"
#if __GLASGOW_HASKELL__ >= 801
      (G AnnKeywordId
GHC.AnnAnyclass) -> String
"anyclass"
#endif
      (G AnnKeywordId
GHC.AnnOpen  ) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnClose ) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnVal   ) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnPackageName) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnHeader ) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnFunId  ) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnInfix  ) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnValStr ) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnName   ) -> KeywordId -> String
forall a a. Show a => a -> a
mkErr KeywordId
kw
      (G AnnKeywordId
GHC.AnnAs     ) -> String
"as"
      (G AnnKeywordId
GHC.AnnAt     ) -> String
"@"
      (G AnnKeywordId
GHC.AnnBang   ) -> String
"!"
      (G AnnKeywordId
GHC.AnnBackquote ) -> String
"`"
      (G AnnKeywordId
GHC.AnnBy     ) -> String
"by"
      (G AnnKeywordId
GHC.AnnCase   ) -> String
"case"
      (G AnnKeywordId
GHC.AnnClass   ) -> String
"class"
#if __GLASGOW_HASKELL__ >= 801
      (G AnnKeywordId
GHC.AnnCloseB  ) -> String
"|)"
      (G AnnKeywordId
GHC.AnnCloseBU ) -> String
"⦈"
#endif
      (G AnnKeywordId
GHC.AnnCloseC  ) -> String
"}"
      (G AnnKeywordId
GHC.AnnCloseP  ) -> String
")"
#if __GLASGOW_HASKELL__ >= 801
      (G AnnKeywordId
GHC.AnnCloseQ  ) -> String
"|]"
      (G AnnKeywordId
GHC.AnnCloseQU ) -> String
"⟧"
#endif
      (G AnnKeywordId
GHC.AnnCloseS  ) -> String
"]"
      (G AnnKeywordId
GHC.AnnColon   ) -> String
":"
      (G AnnKeywordId
GHC.AnnComma   ) -> String
","
      (G AnnKeywordId
GHC.AnnCommaTuple ) -> String
","
      (G AnnKeywordId
GHC.AnnDarrow  ) -> String
"=>"
      (G AnnKeywordId
GHC.AnnData    ) -> String
"data"
      (G AnnKeywordId
GHC.AnnDcolon  ) -> String
"::"
      (G AnnKeywordId
GHC.AnnDefault ) -> String
"default"
      (G AnnKeywordId
GHC.AnnDeriving ) -> String
"deriving"
      (G AnnKeywordId
GHC.AnnDo       ) -> String
"do"
      (G AnnKeywordId
GHC.AnnDot      ) -> String
"."
      (G AnnKeywordId
GHC.AnnDotdot   ) -> String
".."
      (G AnnKeywordId
GHC.AnnElse     ) -> String
"else"
      (G AnnKeywordId
GHC.AnnEqual    ) -> String
"="
      (G AnnKeywordId
GHC.AnnExport   ) -> String
"export"
      (G AnnKeywordId
GHC.AnnFamily   ) -> String
"family"
      (G AnnKeywordId
GHC.AnnForall   ) -> String
"forall"
      (G AnnKeywordId
GHC.AnnForeign  ) -> String
"foreign"
      (G AnnKeywordId
GHC.AnnGroup    ) -> String
"group"
      (G AnnKeywordId
GHC.AnnHiding   ) -> String
"hiding"
      (G AnnKeywordId
GHC.AnnIf       ) -> String
"if"
      (G AnnKeywordId
GHC.AnnImport   ) -> String
"import"
      (G AnnKeywordId
GHC.AnnIn       ) -> String
"in"
      (G AnnKeywordId
GHC.AnnInstance ) -> String
"instance"
      (G AnnKeywordId
GHC.AnnLam      ) -> String
"\\"
      (G AnnKeywordId
GHC.AnnLarrow   ) -> String
"<-"
      (G AnnKeywordId
GHC.AnnLet      ) -> String
"let"
#if __GLASGOW_HASKELL__ >= 900
      -- (G GHC.AnnLolly    ) -> "#->"
      (G GHC.AnnLollyU    ) -> "⊸"
#endif
      (G AnnKeywordId
GHC.AnnMdo      ) -> String
"mdo"
      (G AnnKeywordId
GHC.AnnMinus    ) -> String
"-"
      (G AnnKeywordId
GHC.AnnModule   ) -> String
"module"
#if __GLASGOW_HASKELL__ >= 900
      (G GHC.AnnPercent   ) -> "%"
      (G GHC.AnnPercentOne) -> "%1"
#endif
      (G AnnKeywordId
GHC.AnnNewtype  ) -> String
"newtype"
      (G AnnKeywordId
GHC.AnnOf       ) -> String
"of"
#if __GLASGOW_HASKELL__ >= 801
      (G AnnKeywordId
GHC.AnnOpenB    ) -> String
"(|"
      (G AnnKeywordId
GHC.AnnOpenBU   ) ->  String
"⦇"
#endif
      (G AnnKeywordId
GHC.AnnOpenC    ) -> String
"{"
#if __GLASGOW_HASKELL__ > 710
      (G AnnKeywordId
GHC.AnnOpenE    ) -> String
"[e|"
#endif
#if __GLASGOW_HASKELL__ >= 801
      (G AnnKeywordId
GHC.AnnOpenEQ   ) -> String
"[|"
      (G AnnKeywordId
GHC.AnnOpenEQU  ) ->  String
"⟦"
#endif
      (G AnnKeywordId
GHC.AnnOpenP    ) -> String
"("
#if __GLASGOW_HASKELL__ < 900
      (G AnnKeywordId
GHC.AnnOpenPE   ) -> String
"$("
      (G AnnKeywordId
GHC.AnnOpenPTE  ) -> String
"$$("
#endif
      (G AnnKeywordId
GHC.AnnOpenS    ) -> String
"["
      (G AnnKeywordId
GHC.AnnPattern  ) -> String
"pattern"
      (G AnnKeywordId
GHC.AnnProc     ) -> String
"proc"
      (G AnnKeywordId
GHC.AnnQualified ) -> String
"qualified"
      (G AnnKeywordId
GHC.AnnRarrow   ) -> String
"->"
      (G AnnKeywordId
GHC.AnnRec      ) -> String
"rec"
      (G AnnKeywordId
GHC.AnnRole     ) -> String
"role"
      (G AnnKeywordId
GHC.AnnSafe     ) -> String
"safe"
      (G AnnKeywordId
GHC.AnnSemi     ) -> String
";"
#if __GLASGOW_HASKELL__ >= 801
      (G AnnKeywordId
GHC.AnnSignature) -> String
"signature"
      (G AnnKeywordId
GHC.AnnStock    ) -> String
"stock"
#endif
      (G AnnKeywordId
GHC.AnnStatic   ) -> String
"static"
      (G AnnKeywordId
GHC.AnnThen     ) -> String
"then"
      (G AnnKeywordId
GHC.AnnTilde    ) -> String
"~"
#if __GLASGOW_HASKELL__ <= 804
      (G GHC.AnnTildehsh ) -> "~#"
#endif
      (G AnnKeywordId
GHC.AnnType     ) -> String
"type"
      (G AnnKeywordId
GHC.AnnUnit     ) -> String
"()"
      (G AnnKeywordId
GHC.AnnUsing    ) -> String
"using"
      (G AnnKeywordId
GHC.AnnVbar     ) -> String
"|"
      (G AnnKeywordId
GHC.AnnWhere    ) -> String
"where"
      (G AnnKeywordId
GHC.Annlarrowtail ) -> String
"-<"
      (G AnnKeywordId
GHC.Annrarrowtail ) -> String
">-"
      (G AnnKeywordId
GHC.AnnLarrowtail ) -> String
"-<<"
      (G AnnKeywordId
GHC.AnnRarrowtail ) -> String
">>-"
      (G AnnKeywordId
GHC.AnnSimpleQuote ) -> String
"'"
      (G AnnKeywordId
GHC.AnnThTyQuote   ) -> String
"''"
#if __GLASGOW_HASKELL__ >= 900
      (G GHC.AnnDollar       ) -> "$"
      (G GHC.AnnDollarDollar ) -> "$$"
#else
      (G AnnKeywordId
GHC.AnnThIdSplice  ) -> String
"$"
      (G AnnKeywordId
GHC.AnnThIdTySplice ) -> String
"$$"
#endif
#if __GLASGOW_HASKELL__ < 900
      (G AnnKeywordId
GHC.AnnEofPos       ) -> String
""
#endif
#if __GLASGOW_HASKELL__ > 710
      (G AnnKeywordId
GHC.AnnDarrowU) -> String
"⇒"
      (G AnnKeywordId
GHC.AnnDcolonU) -> String
"∷"
      (G AnnKeywordId
GHC.AnnForallU) -> String
"∀"
      (G AnnKeywordId
GHC.AnnLarrowU) -> String
"←"
      (G AnnKeywordId
GHC.AnnLarrowtailU) -> String
"⤛"
      (G AnnKeywordId
GHC.AnnRarrowU) -> String
"→"
      (G AnnKeywordId
GHC.AnnRarrowtailU) -> String
"⤜"
      (G AnnKeywordId
GHC.AnnlarrowtailU) -> String
"⤙"
      (G AnnKeywordId
GHC.AnnrarrowtailU) -> String
"⤚"
#endif
#if __GLASGOW_HASKELL__ >= 800
      KeywordId
AnnTypeApp             -> String
"@"
#endif
#if __GLASGOW_HASKELL__ > 804
      (G AnnKeywordId
GHC.AnnVia) -> String
"via"
#endif

#if __GLASGOW_HASKELL__ <= 710
-- | Tries to find a unicode equivalent to a 'KeywordId'.
-- If none exists then fall back to find the ASCII version.
unicodeString :: KeywordId -> String
unicodeString kw =
  fromMaybe (keywordToString kw) (lookup kw unicodeChars)

unicodeChars :: [(KeywordId, String)]
unicodeChars =
    -- AZ:TODO:make this a Data.Map, doing linear scan each time
      [ (G GHC.AnnDarrow, "⇒")
      , (G GHC.AnnDcolon, "∷")
      , (G GHC.AnnForall, "∀")
      , (G GHC.AnnLarrow, "←")
      , (G GHC.AnnLarrowtail, "⤛")
      , (G GHC.AnnRarrow, "→")
      , (G GHC.AnnRarrowtail, "⤜")
      , (G GHC.Annlarrowtail, "⤙")
      , (G GHC.Annrarrowtail, "⤚")
      ]

{-
From Lexer.x

       ,("∷",   ITdcolon, unicodeSyntaxEnabled)
       ,("⇒",   ITdarrow, unicodeSyntaxEnabled)
       ,("∀",   ITforall, unicodeSyntaxEnabled)
       ,("→",   ITrarrow, unicodeSyntaxEnabled)
       ,("←",   ITlarrow, unicodeSyntaxEnabled)

       ,("⤙",   ITlarrowtail, \i -> unicodeSyntaxEnabled i && arrowsEnabled i)
       ,("⤚",   ITrarrowtail, \i -> unicodeSyntaxEnabled i && arrowsEnabled i)
       ,("⤛",   ITLarrowtail, \i -> unicodeSyntaxEnabled i && arrowsEnabled i)
       ,("⤜",   ITRarrowtail, \i -> unicodeSyntaxEnabled i && arrowsEnabled i)

       ,("★", ITstar, unicodeSyntaxEnabled)

-}

#endif