diff options
author | Alan Zimmerman <alan.zimm@gmail.com> | 2017-01-23 20:23:28 +0200 |
---|---|---|
committer | Alan Zimmerman <alan.zimm@gmail.com> | 2017-01-26 15:20:14 +0200 |
commit | 0d1cb1574dd58d1026cac812e2098135823fa419 (patch) | |
tree | 2c7955bc45a085cf54bab5c7204f9ebd24686adf /compiler/parser | |
parent | ff9355e48d0cb04b3adf26e27e12e128f79618f4 (diff) | |
download | haskell-0d1cb1574dd58d1026cac812e2098135823fa419.tar.gz |
Make type import/export API Annotation friendly
Summary:
At the moment an export of the form
type C(..)
is parsed by the rule
```
| 'type' oqtycon {% amms (mkTypeImpExp (sLL $1 $> (unLoc $2)))
[mj AnnType $1,mj AnnVal $2] }
```
This means that the origiinal oqtycon loses its location which is then retained
in the AnnVal annotation.
The problem is if the oqtycon has its own annotations, these get lost.
e.g. in
type (?)(..)
the parens annotations for (?) get lost.
This patch adds a wrapper around the name in the IE type to
(a) provide a distinct location for the adornment annotation and
(b) identify the specific adornment, for use in the pretty printer rather than
occName magic.
Updates haddock submodule
Test Plan: ./validate
Reviewers: mpickering, dfeuer, bgamari, austin
Reviewed By: dfeuer
Subscribers: dfeuer, thomie, mpickering
Differential Revision: https://phabricator.haskell.org/D3016
GHC Trac Issues: #13163
Diffstat (limited to 'compiler/parser')
-rw-r--r-- | compiler/parser/Parser.y | 25 | ||||
-rw-r--r-- | compiler/parser/RdrHsSyn.hs | 55 |
2 files changed, 51 insertions, 29 deletions
diff --git a/compiler/parser/Parser.y b/compiler/parser/Parser.y index 2b70fb7999..e0e060e053 100644 --- a/compiler/parser/Parser.y +++ b/compiler/parser/Parser.y @@ -793,7 +793,7 @@ export :: { OrdList (LIE RdrName) } >>= \ie -> amsu (sLL $1 $> ie) (fst $ unLoc $2) } | 'module' modid {% amsu (sLL $1 $> (IEModuleContents $2)) [mj AnnModule $1] } - | 'pattern' qcon {% amsu (sLL $1 $> (IEVar $2)) + | 'pattern' qcon {% amsu (sLL $1 $> (IEVar (sLL $1 $> (IEPattern $2)))) [mj AnnPattern $1] } export_subspec :: { Located ([AddAnn],ImpExpSubSpec) } @@ -803,13 +803,13 @@ export_subspec :: { Located ([AddAnn],ImpExpSubSpec) } (as ++ [mop $1,mcp $3] ++ fst $2, ie) } -qcnames :: { ([AddAnn], [Located (Maybe RdrName)]) } +qcnames :: { ([AddAnn], [Located ImpExpQcSpec]) } : {- empty -} { ([],[]) } | qcnames1 { $1 } -qcnames1 :: { ([AddAnn], [Located (Maybe RdrName)]) } -- A reversed list +qcnames1 :: { ([AddAnn], [Located ImpExpQcSpec]) } -- A reversed list : qcnames1 ',' qcname_ext_w_wildcard {% case (head (snd $1)) of - l@(L _ Nothing) -> + l@(L _ ImpExpQcWildcard) -> return ([mj AnnComma $2, mj AnnDotdot l] ,(snd (unLoc $3) : snd $1)) l -> (ams (head (snd $1)) [mj AnnComma $2] >> @@ -822,14 +822,15 @@ qcnames1 :: { ([AddAnn], [Located (Maybe RdrName)]) } -- A reversed list -- Variable, data constructor or wildcard -- or tagged type constructor -qcname_ext_w_wildcard :: { Located ([AddAnn],Located (Maybe RdrName)) } - : qcname_ext { sL1 $1 ([],Just `fmap` $1) } - | '..' { sL1 $1 ([mj AnnDotdot $1], sL1 $1 Nothing) } - -qcname_ext :: { Located RdrName } - : qcname { $1 } - | 'type' oqtycon {% amms (mkTypeImpExp (sLL $1 $> (unLoc $2))) - [mj AnnType $1,mj AnnVal $2] } +qcname_ext_w_wildcard :: { Located ([AddAnn], Located ImpExpQcSpec) } + : qcname_ext { sL1 $1 ([],$1) } + | '..' { sL1 $1 ([mj AnnDotdot $1], sL1 $1 ImpExpQcWildcard) } + +qcname_ext :: { Located ImpExpQcSpec } + : qcname { sL1 $1 (ImpExpQcName $1) } + | 'type' oqtycon {% do { n <- mkTypeImpExp $2 + ; ams (sLL $1 $> (ImpExpQcType n)) + [mj AnnType $1] } } qcname :: { Located RdrName } -- Variable or type constructor : qvar { $1 } -- Things which look like functions diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs index 64a60c4841..2c63c428b6 100644 --- a/compiler/parser/RdrHsSyn.hs +++ b/compiler/parser/RdrHsSyn.hs @@ -56,6 +56,7 @@ module RdrHsSyn ( -- Help with processing exports ImpExpSubSpec(..), + ImpExpQcSpec(..), mkModuleImpExp, mkTypeImpExp, mkImpExpSubSpec, @@ -1436,30 +1437,37 @@ mkExtName rdrNm = mkFastString (occNameString (rdrNameOcc rdrNm)) data ImpExpSubSpec = ImpExpAbs | ImpExpAll - | ImpExpList [Located RdrName] - | ImpExpAllWith [Located (Maybe RdrName)] + | ImpExpList [Located ImpExpQcSpec] + | ImpExpAllWith [Located ImpExpQcSpec] -mkModuleImpExp :: Located RdrName -> ImpExpSubSpec -> P (IE RdrName) -mkModuleImpExp n@(L l name) subs = +data ImpExpQcSpec = ImpExpQcName (Located RdrName) + | ImpExpQcType (Located RdrName) + | ImpExpQcWildcard + +mkModuleImpExp :: Located ImpExpQcSpec -> ImpExpSubSpec -> P (IE RdrName) +mkModuleImpExp (L l specname) subs = case subs of ImpExpAbs - | isVarNameSpace (rdrNameSpace name) -> return $ IEVar n - | otherwise -> IEThingAbs . L l <$> nameT - ImpExpAll -> IEThingAll . L l <$> nameT - ImpExpList xs -> - (\newName -> IEThingWith (L l newName) NoIEWildcard xs []) <$> nameT + | isVarNameSpace (rdrNameSpace name) + -> return $ IEVar (L l (ieNameFromSpec specname)) + | otherwise -> IEThingAbs . L l <$> nameT + ImpExpAll -> IEThingAll . L l <$> nameT + ImpExpList xs -> + (\newName -> IEThingWith (L l newName) NoIEWildcard (wrapped xs) []) + <$> nameT ImpExpAllWith xs -> do allowed <- extension patternSynonymsEnabled if allowed then let withs = map unLoc xs pos = maybe NoIEWildcard IEWildcard - (findIndex isNothing withs) - ies = [L l n | L l (Just n) <- xs] + (findIndex isImpExpQcWildcard withs) + ies = wrapped $ filter (not . isImpExpQcWildcard . unLoc) xs in (\newName -> IEThingWith (L l newName) pos ies []) <$> nameT else parseErrorSDoc l (text "Illegal export form (use PatternSynonyms to enable)") where + name = ieNameVal specname nameT = if isVarNameSpace (rdrNameSpace name) then parseErrorSDoc l @@ -1469,7 +1477,17 @@ mkModuleImpExp n@(L l name) subs = then text "If" <+> quotes (ppr name) <+> text "is a type constructor" <+> text "then enable ExplicitNamespaces and use the 'type' keyword." else empty) - else return $ name + else return $ ieNameFromSpec specname + + ieNameVal (ImpExpQcName ln) = unLoc ln + ieNameVal (ImpExpQcType ln) = unLoc ln + ieNameVal (ImpExpQcWildcard) = panic "ieNameVal got wildcard" + + ieNameFromSpec (ImpExpQcName ln) = IEName ln + ieNameFromSpec (ImpExpQcType ln) = IEType ln + ieNameFromSpec (ImpExpQcWildcard) = panic "ieName got wildcard" + + wrapped = map (\(L l x) -> L l (ieNameFromSpec x)) mkTypeImpExp :: Located RdrName -- TcCls or Var name space -> P (Located RdrName) @@ -1492,15 +1510,18 @@ checkImportSpec ie@(L _ specs) = $+$ text "pattern synonyms with types in module exports.") -- In the correct order -mkImpExpSubSpec :: [Located (Maybe RdrName)] -> P ([AddAnn], ImpExpSubSpec) +mkImpExpSubSpec :: [Located ImpExpQcSpec] -> P ([AddAnn], ImpExpSubSpec) mkImpExpSubSpec [] = return ([], ImpExpList []) -mkImpExpSubSpec [L l Nothing] = - return ([\s -> addAnnotation s AnnDotdot l], ImpExpAll) +mkImpExpSubSpec [L _ ImpExpQcWildcard] = + return ([], ImpExpAll) mkImpExpSubSpec xs = - if (any (isNothing . unLoc) xs) + if (any (isImpExpQcWildcard . unLoc) xs) then return $ ([], ImpExpAllWith xs) - else return $ ([], ImpExpList ([L l x | L l (Just x) <- xs])) + else return $ ([], ImpExpList xs) +isImpExpQcWildcard :: ImpExpQcSpec -> Bool +isImpExpQcWildcard ImpExpQcWildcard = True +isImpExpQcWildcard _ = False ----------------------------------------------------------------------------- -- Misc utils |