Skip to content

Commit 04e1c06

Browse files
committed
Use extQ to choose parser.
- In the process of development, it was forgotten that the "parent" type of patterns and exprs is different. When traversal occurs, SYB would throw out `Pat` types as it was only expecting `HsExpr` types. - Using `extQ` allows us to chain the expected types and we can then destructure patterns appropriately.
1 parent 83c8fde commit 04e1c06

File tree

1 file changed

+34
-30
lines changed
  • plugins/hls-alternate-number-format-plugin/src/Ide/Plugin

1 file changed

+34
-30
lines changed

plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Literals.hs

+34-30
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,31 @@
1-
{-# LANGUAGE DeriveGeneric #-}
2-
{-# LANGUAGE DerivingVia #-}
3-
{-# LANGUAGE FlexibleInstances #-}
4-
{-# LANGUAGE RankNTypes #-}
1+
{-# LANGUAGE DeriveDataTypeable #-}
2+
{-# LANGUAGE DeriveGeneric #-}
3+
{-# LANGUAGE FlexibleInstances #-}
4+
{-# LANGUAGE RankNTypes #-}
55
module Ide.Plugin.Literals (
66
collectLiterals
77
, Literal(..)
88
, getSrcText
99
, getSrcSpan
1010
) where
1111

12-
import Data.Generics (mkQ)
13-
import Data.Maybe (catMaybes, mapMaybe,
14-
maybeToList)
15-
import Data.Set (Set)
16-
import qualified Data.Set as S
12+
import Data.Maybe (maybeToList)
1713
import Data.Text (Text)
1814
import qualified Data.Text as T
1915
import Development.IDE.GHC.Compat hiding (getSrcSpan)
2016
import Development.IDE.GHC.Util (unsafePrintSDoc)
2117
import Development.IDE.Graph.Classes (NFData (rnf))
2218
import qualified GHC.Generics as GHC
23-
import Generics.SYB (Data, Typeable, cast,
24-
everything, listify)
19+
import Generics.SYB (Data, Typeable, everything,
20+
extQ)
2521

2622
-- data type to capture what type of literal we are dealing with
2723
-- provides location and possibly source text (for OverLits) as well as it's value
2824
-- we currently don't have any use for PrimLiterals. They never have source text so we always drop them
2925
-- | Captures a Numeric Literals Location, Source Text, and Value.
30-
data Literal = IntLiteral RealSrcSpan Text Integer
31-
| FracLiteral RealSrcSpan Text Rational
32-
deriving (GHC.Generic, Show, Ord, Eq)
26+
data Literal = IntLiteral RealSrcSpan Text Integer
27+
| FracLiteral RealSrcSpan Text Rational
28+
deriving (GHC.Generic, Show, Ord, Eq, Data)
3329

3430
instance NFData RealSrcSpan where
3531
rnf x = x `seq` ()
@@ -49,33 +45,41 @@ getSrcSpan = \case
4945
FracLiteral ss _ _ -> ss
5046

5147
-- | Find all literals in a Parsed Source File
52-
collectLiterals' :: (Data ast, Typeable ast) => ast -> [Literal]
53-
collectLiterals' = mapMaybe getLiteral . listify isReal
54-
where
55-
isReal :: GenLocated SrcSpan (HsExpr GhcPs) -> Bool
56-
isReal (L (RealSrcSpan _ _) lit) = case lit of
57-
HsLit{} -> True
58-
HsOverLit{} -> True
59-
_ -> False
60-
isReal _ = False
61-
6248
collectLiterals :: (Data ast, Typeable ast) => ast -> [Literal]
63-
collectLiterals = everything (<>) (mkQ ([] :: [Literal]) (maybeToList . getLiteral))
49+
collectLiterals = everything (<>) (maybeToList . (const Nothing `extQ` getLiteral `extQ` getPattern))
6450

6551
-- | Translate from HsLit and HsOverLit Types to our Literal Type
6652
getLiteral :: GenLocated SrcSpan (HsExpr GhcPs) -> Maybe Literal
6753
getLiteral (L (UnhelpfulSpan _) _) = Nothing
68-
getLiteral (L (RealSrcSpan sSpan _ ) lit) = case lit of
69-
-- only want
70-
HsLit _ lit -> case lit of
54+
getLiteral (L (RealSrcSpan sSpan _ ) expr) = case expr of
55+
HsLit _ lit -> fromLit lit sSpan
56+
HsOverLit _ overLit -> fromOverLit overLit sSpan
57+
_ -> Nothing
58+
59+
-- | Destructure Patterns to unwrap any Literals
60+
getPattern :: GenLocated SrcSpan (Pat GhcPs) -> Maybe Literal
61+
getPattern (L (UnhelpfulSpan _) _) = Nothing
62+
getPattern (L (RealSrcSpan patSpan _) pat) = case pat of
63+
LitPat _ lit -> case lit of
64+
HsInt _ val -> fromIntegralLit patSpan val
65+
HsRat _ val _ -> fromFractionalLit patSpan val
66+
_ -> Nothing
67+
NPat _ (L (RealSrcSpan sSpan _) overLit) _ _ -> fromOverLit overLit sSpan
68+
NPlusKPat _ _ (L (RealSrcSpan sSpan _) overLit1) _ _ _ -> fromOverLit overLit1 sSpan
69+
_ -> Nothing
70+
71+
fromLit :: HsLit p -> RealSrcSpan -> Maybe Literal
72+
fromLit lit sSpan = case lit of
7173
HsInt _ val -> fromIntegralLit sSpan val
7274
HsRat _ val _ -> fromFractionalLit sSpan val
7375
_ -> Nothing
74-
HsOverLit _ OverLit{..} -> case ol_val of
76+
77+
fromOverLit :: HsOverLit p -> RealSrcSpan -> Maybe Literal
78+
fromOverLit OverLit{..} sSpan = case ol_val of
7579
HsIntegral il -> fromIntegralLit sSpan il
7680
HsFractional fl -> fromFractionalLit sSpan fl
7781
_ -> Nothing
78-
_ -> Nothing
82+
fromOverLit _ _ = Nothing
7983

8084
fromIntegralLit :: RealSrcSpan -> IntegralLit -> Maybe Literal
8185
fromIntegralLit s (IL txt _ val) = fmap (\txt' -> IntLiteral s txt' val) (fromSourceText txt)

0 commit comments

Comments
 (0)