1
- {-# LANGUAGE DeriveGeneric #-}
2
- {-# LANGUAGE DerivingVia #-}
3
- {-# LANGUAGE FlexibleInstances #-}
4
- {-# LANGUAGE RankNTypes #-}
1
+ {-# LANGUAGE DeriveDataTypeable #-}
2
+ {-# LANGUAGE DeriveGeneric #-}
3
+ {-# LANGUAGE FlexibleInstances #-}
4
+ {-# LANGUAGE RankNTypes #-}
5
5
module Ide.Plugin.Literals (
6
6
collectLiterals
7
7
, Literal (.. )
8
8
, getSrcText
9
9
, getSrcSpan
10
10
) where
11
11
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 )
17
13
import Data.Text (Text )
18
14
import qualified Data.Text as T
19
15
import Development.IDE.GHC.Compat hiding (getSrcSpan )
20
16
import Development.IDE.GHC.Util (unsafePrintSDoc )
21
17
import Development.IDE.Graph.Classes (NFData (rnf ))
22
18
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 )
25
21
26
22
-- data type to capture what type of literal we are dealing with
27
23
-- provides location and possibly source text (for OverLits) as well as it's value
28
24
-- we currently don't have any use for PrimLiterals. They never have source text so we always drop them
29
25
-- | 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 )
33
29
34
30
instance NFData RealSrcSpan where
35
31
rnf x = x `seq` ()
@@ -49,33 +45,41 @@ getSrcSpan = \case
49
45
FracLiteral ss _ _ -> ss
50
46
51
47
-- | 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
-
62
48
collectLiterals :: (Data ast , Typeable ast ) => ast -> [Literal ]
63
- collectLiterals = everything (<>) (mkQ ( [] :: [ Literal ]) (maybeToList . getLiteral ))
49
+ collectLiterals = everything (<>) (maybeToList . ( const Nothing `extQ` getLiteral `extQ` getPattern ))
64
50
65
51
-- | Translate from HsLit and HsOverLit Types to our Literal Type
66
52
getLiteral :: GenLocated SrcSpan (HsExpr GhcPs ) -> Maybe Literal
67
53
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
71
73
HsInt _ val -> fromIntegralLit sSpan val
72
74
HsRat _ val _ -> fromFractionalLit sSpan val
73
75
_ -> Nothing
74
- HsOverLit _ OverLit {.. } -> case ol_val of
76
+
77
+ fromOverLit :: HsOverLit p -> RealSrcSpan -> Maybe Literal
78
+ fromOverLit OverLit {.. } sSpan = case ol_val of
75
79
HsIntegral il -> fromIntegralLit sSpan il
76
80
HsFractional fl -> fromFractionalLit sSpan fl
77
81
_ -> Nothing
78
- _ -> Nothing
82
+ fromOverLit _ _ = Nothing
79
83
80
84
fromIntegralLit :: RealSrcSpan -> IntegralLit -> Maybe Literal
81
85
fromIntegralLit s (IL txt _ val) = fmap (\ txt' -> IntLiteral s txt' val) (fromSourceText txt)
0 commit comments