PageRenderTime 54ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Cxx/Operations.hs

http://github.com/Eelis/geordi
Haskell | 1030 lines | 808 code | 178 blank | 44 comment | 33 complexity | ce49598e9aa1fd1d74a410a6e7b13621 MD5 | raw file
  1. {-# LANGUAGE UnicodeSyntax, DeriveDataTypeable, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, UndecidableInstances, PatternGuards, Rank2Types, OverlappingInstances, ScopedTypeVariables, ExistentialQuantification, TypeSynonymInstances, CPP, ViewPatterns, TupleSections #-}
  2. module Cxx.Operations (apply, mapply, squared, parenthesized, is_primary_TypeSpecifier, split_all_decls, map_plain, parseAbbrMain, expand, line_breaks, specT, find, is_pointer_or_reference, namedPathTo, findable_productions, make_edits, ShortCode) where
  3. import qualified Cxx.Show
  4. import qualified Data.List.NonEmpty as NeList
  5. import Data.List.NonEmpty (NonEmpty((:|)), nonEmpty)
  6. import qualified Data.Maybe as Maybe
  7. import Util (Convert(..), (.), total_tail, strip, isIdChar, TriBool(..), MaybeEitherString(..), Phantom(..), neElim, NeList, orElse, neFilter, Apply(..), MaybeApply(..), MyMonadError(..))
  8. import Cxx.Basics
  9. import Editing.Basics (Range(..), Offsettable(..), TextEdit(..), Pos(Pos), pos, contained_in, fullRange)
  10. import Editing.Diff (diff_as_Edits)
  11. import Data.Function (on)
  12. import Data.Foldable (toList, any)
  13. import Control.Arrow (first, second)
  14. import Control.Monad.Identity
  15. import Data.Generics (cast, gmapT, everywhere, Data, Typeable, gfoldl, dataTypeOf, toConstr, Constr, DataType, dataTypeName, constrType)
  16. import Prelude hiding ((.), any)
  17. import Prelude.Unicode
  18. -- Operations on Chunks/Code
  19. map_plain :: (String String) Chunk Chunk
  20. map_plain f (Plain s) = Plain $ f s
  21. map_plain f (Curlies c) = Curlies $ map (map_plain f) c
  22. map_plain f (Parens c) = Parens $ map (map_plain f) c
  23. map_plain f (Squares c) = Squares $ map (map_plain f) c
  24. map_plain _ x = x
  25. int_main :: String
  26. int_main = "\nint main(int argc, char * argv[])"
  27. gen :: String String String TString
  28. gen left middle right
  29. = map (, 0) left
  30. ++ zip middle [0..]
  31. ++ map (, length middle) right
  32. generateMain :: AbbreviatedMain TString
  33. generateMain (Block c) = gen int_main ("{" ++ show c ++ "}") ""
  34. generateMain (Call c) = gen (int_main ++ "{printf") (show c) "\n;}"
  35. generateMain (Print c) = gen (int_main ++ "{::std::cout") ("<<" ++ show c) "\n;}"
  36. -- The newlines make //-style comments work.
  37. cstyle_comments :: Code Code
  38. cstyle_comments = map f where f (SingleComment s) = MultiComment s; f c = c
  39. type ShortCode = (Maybe AbbreviatedMain, Code)
  40. instance Show AbbreviatedMain where
  41. show (Block c) = show [Curlies c]
  42. show (Call c) = show c
  43. show (Print c) = show $ [Plain "<<"] ++ c
  44. type TString = [(Char, Int {- position in the request body -})]
  45. expand :: Code -> (Maybe TString {- generated main -}, TString {- rest -})
  46. expand requestChunks =
  47. ( generateMain . mAbbrMain
  48. , zip (show rest) [maybe 0 (length . show) mAbbrMain ..])
  49. where
  50. (mAbbrMain, rest) = parseAbbrMain requestChunks
  51. parseAbbrMain :: Code (Maybe AbbreviatedMain, Code)
  52. parseAbbrMain (Curlies c : b) = (Just (Block c), b)
  53. parseAbbrMain (Plain ('<':'<':a) : b) = (Just (Print x), total_tail y)
  54. where (x, y) = break (== Plain ";") $ Plain a : b
  55. parseAbbrMain (Parens c : b) = (Just (Call (Parens c : x)), total_tail y)
  56. where (x, y) = break (== Plain ";") b
  57. parseAbbrMain c = (Nothing, c)
  58. line_breaks :: Code Code
  59. line_breaks = map $ map_plain $ map $ \c if c == '\\' then '\n' else c
  60. -- Convenience constructors
  61. squared :: a Squared a
  62. squared x = Squared (OpenSquare_, White "") (Enclosed x) (CloseSquare_, White "")
  63. parenthesized :: a Parenthesized a
  64. parenthesized x = Parenthesized (OpenParen_, White "") (Enclosed x) (CloseParen_, White "")
  65. specT :: TypeSpecifier
  66. specT = TypeSpecifier_TrailingTypeSpecifier $ TrailingTypeSpecifier_SimpleTypeSpecifier $ SimpleTypeSpecifier_TypeName (OptQualified Nothing Nothing) $ TypeName_ClassName $ ClassName_Identifier $ Identifier "T" $ White " "
  67. -- Applying make-specifications.
  68. apply_makedecl_to :: Data d MakeDeclaration d MaybeEitherString d
  69. apply_makedecl_to makedecl = Maybe.fromMaybe (const $ MaybeEitherString Nothing) $ Maybe.listToMaybe . Maybe.catMaybes $
  70. [ cast ((\d case d of
  71. SimpleDeclaration specs (Just (InitDeclaratorList (Commad (InitDeclarator x mi) []))) w
  72. case makedecl of
  73. MakeDeclaration _ _ Definitely throwError "Cannot purify simple-declaration."
  74. MakeDeclaration specs' mpad _ → return $ let (specs'', x') = apply (specs', mpad) (specs, x) in
  75. SimpleDeclaration specs'' (Just (InitDeclaratorList (Commad (InitDeclarator x' mi) []))) w
  76. _ MaybeEitherString Nothing) :: SimpleDeclaration MaybeEitherString SimpleDeclaration)
  77. , cast (mapply makedecl :: ParameterDeclaration MaybeEitherString ParameterDeclaration)
  78. , cast ((\d case d of
  79. ExceptionDeclaration u (Just (Left e))
  80. case makedecl of
  81. MakeDeclaration _ _ Definitely throwError "Cannot purify exception-declaration."
  82. MakeDeclaration specs mpad _
  83. (\(u', e') ExceptionDeclaration u' $ Just $ Left e') . mapply (specs, mpad) (u, e)
  84. _ MaybeEitherString Nothing) :: ExceptionDeclaration MaybeEitherString ExceptionDeclaration)
  85. , cast ((\d case d of
  86. MemberDeclaration specs (Just (MemberDeclaratorList (Commad (MemberDeclarator decl ps) []))) semicolon
  87. return $ let (specs', decl', ps') = apply makedecl (specs, decl, ps) in
  88. MemberDeclaration specs' (Just (MemberDeclaratorList (Commad (MemberDeclarator decl' ps') []))) semicolon
  89. _ MaybeEitherString Nothing) :: MemberDeclaration MaybeEitherString MemberDeclaration)
  90. , cast (mapply makedecl :: FunctionDefinition MaybeEitherString FunctionDefinition)
  91. , cast ((\d case d of
  92. Condition_Declaration u e i
  93. case makedecl of
  94. MakeDeclaration _ _ Definitely throwError "Cannot purify condition-declaration."
  95. MakeDeclaration specs mpad _
  96. (\(u', e') Condition_Declaration u' e' i) . mapply (specs, mpad) (u, e)
  97. _ MaybeEitherString Nothing) :: Condition MaybeEitherString Condition)
  98. , cast (mapply makedecl :: ForRangeDeclaration MaybeEitherString ForRangeDeclaration)
  99. ]
  100. -- Getting declarator-ids out of things.
  101. instance Convert ClassSpecifier (Maybe DeclaratorId) where convert (ClassSpecifier h _) = convert h
  102. instance Convert ClassHead (Maybe DeclaratorId) where convert (ClassHead _ k _) = convert k
  103. instance Convert Identifier DeclaratorId where convert = DeclaratorId_IdExpression Nothing . convert
  104. instance Convert Identifier IdExpression where convert = IdExpression . Right . convert
  105. instance Convert Identifier UnqualifiedId where convert = UnqualifiedId_Identifier
  106. instance Convert (NestedNameSpecifier, Identifier) QualifiedId where convert (nns, i) = NestedUnqualifiedId Nothing nns Nothing (convert i)
  107. instance Convert (NestedNameSpecifier, Identifier) IdExpression where convert = IdExpression . Left . convert
  108. instance Convert SimpleTemplateId UnqualifiedId where convert = UnqualifiedId_TemplateId . convert
  109. instance Convert SimpleTemplateId IdExpression where convert = IdExpression . Right . convert
  110. instance Convert SimpleTemplateId DeclaratorId where convert = DeclaratorId_IdExpression Nothing . convert
  111. instance Convert SimpleTemplateId TemplateId where convert = TemplateId_SimpleTemplateId
  112. instance Convert (NestedNameSpecifier, SimpleTemplateId) DeclaratorId where convert = DeclaratorId_IdExpression Nothing . convert
  113. instance Convert (NestedNameSpecifier, SimpleTemplateId) IdExpression where convert = IdExpression . Left . convert
  114. instance Convert (NestedNameSpecifier, SimpleTemplateId) QualifiedId where convert (nns, tid) = NestedUnqualifiedId Nothing nns Nothing (convert tid)
  115. instance Convert ClassHeadKind (Maybe DeclaratorId) where
  116. convert (ClassHeadKind_Identifier m) = convert . m
  117. convert (ClassHeadKind_NestedIdentifier nns i) = Just $ DeclaratorId_IdExpression Nothing $ convert (nns, i)
  118. convert (ClassHeadKind_SimpleTemplateId Nothing i) = Just $ convert i
  119. convert (ClassHeadKind_SimpleTemplateId (Just nns) i) = Just $ convert (nns, i)
  120. instance Convert EnumSpecifier (Maybe DeclaratorId) where convert (EnumSpecifier x _) = convert x
  121. instance Convert EnumHead (Maybe DeclaratorId) where convert (EnumHead _ m _) = convert . m
  122. instance Convert DeclSpecifier (Maybe DeclaratorId) where
  123. convert (DeclSpecifier_TypeSpecifier (TypeSpecifier_ClassSpecifier c)) = convert c
  124. convert (DeclSpecifier_TypeSpecifier (TypeSpecifier_EnumSpecifier c)) = convert c
  125. convert (DeclSpecifier_TypeSpecifier (TypeSpecifier_TrailingTypeSpecifier (TrailingTypeSpecifier_ElaboratedTypeSpecifier c))) = Just $ convert c
  126. convert _ = Nothing
  127. instance Convert SimpleDeclaration (Maybe DeclaratorId) where
  128. convert (SimpleDeclaration _ (Just (InitDeclaratorList (Commad (InitDeclarator d _) []))) _) = Just $ convert d
  129. convert (SimpleDeclaration (Just (DeclSpecifierSeq (neElim (d, [])))) Nothing _) = convert d
  130. convert _ = Nothing
  131. instance Convert NamespaceAliasDefinition DeclaratorId where convert (NamespaceAliasDefinition _ i _ _ _ _) = convert i
  132. instance Convert BlockDeclaration (Maybe DeclaratorId) where
  133. convert (BlockDeclaration_SimpleDeclaration d) = convert d
  134. convert (BlockDeclaration_NamespaceAliasDefinition d) = Just $ convert d
  135. convert (BlockDeclaration_AliasDeclaration d) = Just $ convert d
  136. convert _ = Nothing
  137. instance Convert ExplicitSpecialization (Maybe DeclaratorId) where convert (ExplicitSpecialization _ _ d) = convert d
  138. instance Convert FunctionDefinition DeclaratorId where convert (FunctionDefinition _ d _) = convert d
  139. instance Convert NamespaceDefinition (Maybe DeclaratorId) where convert (NamespaceDefinition _ _ m _) = convert . m
  140. instance Convert AliasDeclaration DeclaratorId where convert (AliasDeclaration _ i _ _ _) = convert i
  141. instance Convert Declaration (Maybe DeclaratorId) where
  142. convert (Declaration_BlockDeclaration d) = convert d
  143. convert (Declaration_FunctionDefinition d) = Just $ convert d
  144. convert (Declaration_TemplateDeclaration d) = convert d
  145. convert (Declaration_NamespaceDefinition d) = convert d
  146. convert (Declaration_ExplicitSpecialization d) = convert d
  147. convert _ = Nothing
  148. instance Convert TemplateDeclaration (Maybe DeclaratorId) where convert (TemplateDeclaration _ _ _ d) = convert d
  149. instance Convert ExplicitInstantiation (Maybe DeclaratorId) where convert (ExplicitInstantiation _ _ d) = convert d
  150. instance Convert MemberDeclarator (Maybe DeclaratorId) where
  151. convert (MemberDeclarator d _) = Just $ convert d
  152. convert (BitField m _ _) = convert . m
  153. instance Convert MemberDeclaration (Maybe DeclaratorId) where
  154. convert (MemberFunctionDefinition d _) = Just $ convert d
  155. convert (MemberUsingDeclaration _) = Nothing
  156. convert (MemberTemplateDeclaration d) = convert d
  157. convert (MemberDeclaration _ (Just (MemberDeclaratorList (Commad d []))) _) = convert d
  158. convert (MemberDeclaration (Just (DeclSpecifierSeq (neElim (d, [])))) Nothing _) = convert d
  159. convert (MemberDeclaration _ _ _) = Nothing
  160. instance Convert ExceptionDeclaration (Maybe DeclaratorId) where
  161. convert (ExceptionDeclaration _ (Just (Left d))) = Just $ convert d
  162. convert _ = Nothing
  163. instance Convert ParameterDeclaration (Maybe DeclaratorId) where
  164. convert (ParameterDeclaration _ (Left d) _) = Just $ convert d
  165. convert _ = Nothing
  166. instance Convert Condition (Maybe DeclaratorId) where
  167. convert (Condition_Declaration _ d _) = Just $ convert d
  168. convert _ = Nothing
  169. instance Convert ForRangeDeclaration DeclaratorId where
  170. convert (ForRangeDeclaration _ d) = convert d
  171. instance Convert (OptQualified, Identifier) DeclaratorId where
  172. convert (OptQualified Nothing Nothing, i) = convert i
  173. convert (OptQualified (Just s) Nothing, i) = DeclaratorId_IdExpression Nothing $ IdExpression $ Left $ GlobalIdentifier s i
  174. convert (OptQualified ms (Just nns), i) = DeclaratorId_IdExpression Nothing $ IdExpression $ Left $ NestedUnqualifiedId ms nns Nothing $ convert i
  175. instance Convert QualifiedId DeclaratorId where
  176. convert = DeclaratorId_IdExpression Nothing . IdExpression . Left
  177. instance Convert (OptQualified, SimpleTemplateId) DeclaratorId where
  178. convert (OptQualified Nothing Nothing, stid) = convert stid
  179. convert (OptQualified (Just s) Nothing, stid) = DeclaratorId_IdExpression Nothing $ IdExpression $ Left $ GlobalTemplateId s $ convert stid
  180. convert (OptQualified ms (Just nns), stid) = DeclaratorId_IdExpression Nothing $ IdExpression $ Left $ NestedUnqualifiedId ms nns Nothing $ convert stid
  181. instance Convert ElaboratedTypeSpecifier DeclaratorId where
  182. convert (ElaboratedTypeSpecifier _ optqualified (Right identifier)) = convert (optqualified, identifier)
  183. convert (ElaboratedTypeSpecifier _ optqualified (Left (_, stid))) = convert (optqualified, stid)
  184. -- Todo: Maybe using the (KwdTemplate, White) pair in the declarator-id would be better.
  185. instance Convert Declarator DeclaratorId where
  186. convert (Declarator_PtrDeclarator p) = convert p
  187. convert (Declarator_TrailingReturnType d _ _) = convert d
  188. instance Convert PtrDeclarator DeclaratorId where
  189. convert (PtrDeclarator_NoptrDeclarator d) = convert d
  190. convert (PtrDeclarator _ d) = convert d
  191. instance Convert NoptrDeclarator DeclaratorId where
  192. convert (NoptrDeclarator_Id did) = did
  193. convert (NoptrDeclarator_WithParams d _) = convert d
  194. convert (NoptrDeclarator_Squared d _) = convert d
  195. convert (NoptrDeclarator_Parenthesized (Parenthesized _ (Enclosed d) _)) = convert d
  196. instance Convert ((ScopeRes, White), UnqualifiedId) (Maybe DeclaratorId) where
  197. convert (scoperes, UnqualifiedId_Identifier i) = Just $ convert (GlobalIdentifier scoperes i)
  198. convert (scoperes, UnqualifiedId_TemplateId i) = Just $ convert (GlobalTemplateId scoperes i)
  199. convert (scoperes, UnqualifiedId_OperatorFunctionId i) = Just $ convert (GlobalOperatorFunctionId scoperes i)
  200. convert (_, UnqualifiedId_Destructor _ _) = Nothing -- There are no global destructors.
  201. convert (_, UnqualifiedId_ConversionFunctionId _) = Nothing -- There are no global conversion operators.
  202. instance Convert UsingDeclaration (Maybe DeclaratorId) where
  203. convert (UsingDeclaration_Nested _ _ msr nns i _) = Just $ convert $ NestedUnqualifiedId msr nns Nothing i
  204. convert (UsingDeclaration_NonNested _ s i _) = convert (s, i)
  205. -- Finding declarations
  206. gfoldl_with_lengths :: Data a Int (forall d. Data d Int d [r]) a [r]
  207. gfoldl_with_lengths i f = runIdentity . gfoldl_with_lengthsM i ((Identity .) . f)
  208. gfoldl_with_ranges :: Data a Int (forall d. Data d Range Char d [r]) a [r]
  209. gfoldl_with_ranges i f = runIdentity . gfoldl_with_rangesM i ((Identity .) . f)
  210. gfoldl_with_lengthsM :: (Data a, Monad m) Int (forall d. Data d Int d m [r]) a m [r]
  211. gfoldl_with_lengthsM i f = gfoldl_with_rangesM i (f . pos . start)
  212. data GfoldlWithLengthsIntermediary m r a = GfoldlWithLengthsIntermediary { gwli_result :: m [r], _off :: Int }
  213. gfoldl_with_rangesM :: (Data a, Monad m) Int (forall d. Data d Range Char d m [r]) a m [r]
  214. gfoldl_with_rangesM i f = gwli_result . gfoldl (\(GfoldlWithLengthsIntermediary m o) y
  215. let n = length (Cxx.Show.show_simple y) in
  216. GfoldlWithLengthsIntermediary (liftM2 (++) m (f (Range (Pos o) n) y)) (o + n)) (\_ GfoldlWithLengthsIntermediary (return []) i)
  217. listElem :: forall a d . (Data a, Typeable a, Data d) Phantom a d Maybe (Range Char, Range Char)
  218. listElem _ d
  219. | Just (Commad x []) cast d :: Maybe (Commad a) =
  220. Just $ diag $ fullRange (Cxx.Show.show_simple x)
  221. | Just (Commad x ((cw, _):_)) cast d :: Maybe (Commad a) =
  222. Just (fullRange $ Cxx.Show.show_simple (x, cw), fullRange $ Cxx.Show.show_simple x)
  223. | Just x@(cw, r) cast d :: Maybe ((CommaOp, White), a) =
  224. Just (fullRange $ Cxx.Show.show_simple x,
  225. Range (Pos $ length $ Cxx.Show.show_simple cw) (length $ Cxx.Show.show_simple r))
  226. | otherwise = Nothing
  227. bodyOf :: Data d d DeclaratorId Maybe (Range Char)
  228. bodyOf x did
  229. | Just (GeordiRequest_Block (FunctionBody _ (CompoundStatement (Curlied o b _))) _) cast x, strip (show did) == "main" =
  230. Just $ Range (Pos $ length $ Cxx.Show.show_simple o) (length $ Cxx.Show.show_simple b)
  231. | Just (ClassSpecifier classHead (Curlied o b _)) cast x, convert classHead == Just did =
  232. Just $ Range (Pos $ length $ Cxx.Show.show_simple (classHead, o)) (length $ Cxx.Show.show_simple b)
  233. | Just (EnumSpecifier enumHead (Curlied o b _)) cast x, convert enumHead == Just did =
  234. Just $ Range (Pos $ length $ Cxx.Show.show_simple (enumHead, o)) (length $ Cxx.Show.show_simple b)
  235. | Just (FunctionDefinition specs declarator (FunctionBody ctorInitializer (CompoundStatement (Curlied o b _)))) cast x, convert declarator == did =
  236. Just $ Range (Pos $ length $ Cxx.Show.show_simple (specs, declarator, ctorInitializer, o)) (length $ Cxx.Show.show_simple b)
  237. | Just (NamespaceDefinition inline kwd (Just identifier) (Curlied o b _)) cast x, convert identifier == did =
  238. Just $ Range (Pos $ length $ Cxx.Show.show_simple (inline, kwd, identifier, o)) (length $ Cxx.Show.show_simple b)
  239. | otherwise = Nothing
  240. instance Eq DataType where (==) = (==) `on` dataTypeName
  241. constr_eq :: Constr Constr Bool
  242. -- The existing Eq instance only compares constructor indices for algebraic data types, so for instance the first constructors of two unrelated algebraic data types are considered equal.
  243. constr_eq c d = c == d constrType c == constrType d
  244. data AnyData = forall d . Data d AnyData d
  245. type TreePath = NeList AnyData
  246. applyAny :: (forall a. Data a a b) (AnyData b)
  247. applyAny p (AnyData x) = p x
  248. diag :: a (a, a)
  249. diag x = (x, x)
  250. finder :: Findable TreePath Maybe (Range Char, Range Char)
  251. finder f = case f of
  252. FindableDataType t (diag .) . simpleFinder ((== t) . applyAny dataTypeOf . NeList.head)
  253. FindableConstr c (diag .) . simpleFinder (constr_eq c . applyAny toConstr . NeList.head)
  254. BodyOf d (diag .) . applyAny (`bodyOf` d) . NeList.head
  255. DeclarationOf d (diag .) . simpleFinder (complete (`isDeclarationOf` d))
  256. Constructor (diag .) . simpleFinder (complete $ isSpecialFuncWith isConstructorId)
  257. Destructor (diag .) . simpleFinder (complete $ isSpecialFuncWith isDestructorId)
  258. ConversionFunction (diag .) . simpleFinder (complete $ isSpecialFuncWith isConversionFunctionId)
  259. FindableParameterDeclaration applyAny (listElem (Phantom :: Phantom ParameterDeclaration)) . NeList.head
  260. TemplateParameter applyAny (listElem (Phantom :: Phantom TemplateParameter)) . NeList.head
  261. TemplateArgument applyAny (listElem (Phantom :: Phantom TemplateArgument)) . NeList.head
  262. where
  263. simpleFinder p t | AnyData x NeList.head t =
  264. if p t then Just $ fullRange $ Cxx.Show.show_simple x else Nothing
  265. find :: Data d Findable d [(Range Char, Range Char)]
  266. find f = findRange (finder f) [] 0
  267. complete :: (forall d . Data d d Bool) TreePath Bool
  268. complete p d | AnyData x NeList.head d =
  269. p x case NeList.tail d of [] True; AnyData h : _ not $ p h
  270. pathTo :: Data d d Range Char Int TreePath
  271. -- Precondition: the range is entirely within [0, length (show d)]
  272. pathTo x r i = AnyData x :| case gfoldl_with_ranges i f x of
  273. [] []
  274. l : _ toList l
  275. where f r'@(Range st _) y = [pathTo y r (pos st) | r `contained_in` r']
  276. findable_productions, all_productions :: [DataType]
  277. findable_productions =
  278. #define P(n) dataTypeOf (undefined :: Cxx.Basics.n)
  279. -- A.1 Keywords [gram.key]
  280. [ P(TypedefName), P(NamespaceName), P(OriginalNamespaceName), P(NamespaceAlias)
  281. , P(ClassName), P(EnumName), P(TemplateName)
  282. -- A.2 Lexical conventions [gram.lex]
  283. , P(Identifier), P(Literal), P(IntegerLiteral), P(CharacterLiteral), P(FloatingLiteral), P(StringLiteral), P(EncodingPrefix)
  284. -- A.4 Expressions [gram.expr]
  285. , P(PrimaryExpression), P(IdExpression), P(UnqualifiedId), P(QualifiedId), P(NestedNameSpecifier), P(PostfixExpression)
  286. , P(ExpressionList), P(PseudoDestructorName), P(UnaryExpression), P(UnaryOperator), P(NewExpression), P(NewPlacement)
  287. , P(NewTypeId), P(NewDeclarator), P(NoptrNewDeclarator), P(NewInitializer), P(DeleteExpression)
  288. , P(CastExpression), P(PmExpression), P(MultiplicativeExpression), P(AdditiveExpression), P(ShiftExpression)
  289. , P(RelationalExpression), P(EqualityExpression), P(AndExpression), P(ExclusiveOrExpression)
  290. , P(InclusiveOrExpression), P(LogicalAndExpression), P(LogicalOrExpression), P(ConditionalExpression)
  291. , P(AssignmentExpression), P(AssignmentOperator), P(Expression), P(ConstantExpression)
  292. , P(LambdaExpression), P(LambdaIntroducer), P(LambdaCapture), P(CaptureDefault), P(CaptureList), P(Capture), P(LambdaDeclarator)
  293. -- A.5 Statements [gram.stmt]
  294. , P(Statement), P(StatementSeq), P(Label), P(LabeledStatement), P(ExpressionStatement), P(CompoundStatement)
  295. , P(SelectionStatement), P(Condition), P(IterationStatement), P(ForInitStatement), P(ForRangeDeclaration), P(ForRangeInitializer), P(JumpStatement), P(DeclarationStatement)
  296. -- A.6 Declarations [gram.dcl]
  297. , P(Declaration), P(DeclarationSeq), P(BlockDeclaration), P(AliasDeclaration), P(SimpleDeclaration), P(StaticAssertDeclaration)
  298. , P(DeclSpecifier), P(DeclSpecifierSeq), P(StorageClassSpecifier), P(FunctionSpecifier), P(TrailingTypeSpecifier), P(TypeSpecifier), P(TypeSpecifierSeq), P(SimpleTypeSpecifier)
  299. , P(TypeName), P(ElaboratedTypeSpecifier), P(EnumSpecifier), P(EnumHead), P(EnumKey), P(EnumeratorList), P(EnumeratorDefinition)
  300. , P(Enumerator), P(NamespaceDefinition), P(NamespaceAliasDefinition), P(UsingDeclaration), P(UsingDirective), P(AsmDefinition), P(LinkageSpecification)
  301. , P(AlignmentSpecifier)
  302. -- A.7 Declarators [gram.decl]
  303. , P(InitDeclaratorList), P(InitDeclarator), P(Declarator), P(PtrDeclarator), P(NoptrDeclarator), P(ParametersAndQualifiers)
  304. , P(PtrOperator), P(CvQualifier), P(CvQualifierSeq), P(DeclaratorId), P(TypeId), P(AbstractDeclarator), P(PtrAbstractDeclarator)
  305. , P(NoptrAbstractDeclarator), P(ParameterDeclarationClause), P(ParameterDeclarationList), P(FunctionDefinition)
  306. , P(FunctionBody), P(Initializer), P(BraceOrEqualInitializer), P(InitializerClause), P(InitializerList), P(BracedInitList), P(NamespaceBody)
  307. , P(TrailingReturnType)
  308. -- A.8 Classes [gram.class]
  309. , P(ClassSpecifier), P(ClassHead), P(ClassKey), P(MemberAccessSpecifier)
  310. , P(MemberSpecification), P(MemberDeclaration), P(MemberDeclaratorList), P(MemberDeclarator), P(PureSpecifier)
  311. -- A.9 Derived classes [gram.derived]
  312. , P(BaseClause), P(BaseSpecifierList), P(BaseSpecifier), P(AccessSpecifier)
  313. -- A.10 Special member functions [gram.special]
  314. , P(ConversionFunctionId), P(ConversionTypeId), P(CtorInitializer), P(MemInitializerList), P(MemInitializer), P(MemInitializerId)
  315. -- A.11 Overloading [gram.over]
  316. , P(OperatorFunctionId)
  317. -- A.12 Templates [gram.temp]
  318. , P(TemplateDeclaration), P(TemplateParameterList), P(TypeParameter), P(TemplateArguments), P(SimpleTemplateId)
  319. , P(TemplateId), P(TemplateArgumentList), P(TemplateArgument), P(TypenameSpecifier), P(ExplicitInstantiation)
  320. , P(ExplicitSpecialization)
  321. -- A.13 Exception handling [gram.except]
  322. , P(TryBlock), P(FunctionTryBlock), P(Handler), P(HandlerSeq), P(ExceptionDeclaration), P(ThrowExpression), P(ExceptionSpecification)
  323. , P(TypeIdList) ]
  324. all_productions = findable_productions ++ [P(ParameterDeclaration), P(TemplateParameter), P(TemplateArgument)]
  325. -- These three are not part of findable_productions because they get special Findable treatment.
  326. #undef P
  327. namedPathTo :: Data d d Range Char [String]
  328. namedPathTo d r = map Cxx.Show.dataType_abbreviated_productionName $
  329. filter ( all_productions) $ toList $ fmap (applyAny dataTypeOf) (pathTo d r 0)
  330. findRange :: (Offsettable a, Data d) (TreePath Maybe a) [AnyData] Int d [a]
  331. findRange p tp i x = Maybe.maybeToList (offset i . p (AnyData x :| tp)) ++ gfoldl_with_lengths i (findRange p (AnyData x : tp)) x
  332. make_edits :: (MyMonadError String m, Data d) Range Char MakeDeclaration Int d m [TextEdit Char]
  333. make_edits r m i d = do
  334. ot gfoldl_with_lengthsM i (make_edits r m) d
  335. oi (if Range (Pos i) (length $ strip $ Cxx.Show.show_simple d) == r
  336. then (case apply_makedecl_to m d of
  337. MaybeEitherString (Just (Right d')) → return $ offset i $ diff_as_Edits (Cxx.Show.show_simple d) (Cxx.Show.show_simple d')
  338. MaybeEitherString (Just (Left e)) throwError e
  339. MaybeEitherString Nothing return [])
  340. else return [])
  341. return $ oi ++ ot
  342. instance Convert [DeclSpecifier] [TypeSpecifier] where
  343. convert = Maybe.mapMaybe $ \ds
  344. case ds of
  345. DeclSpecifier_TypeSpecifier t Just t
  346. _ Nothing
  347. isSpecialFunc :: Data d d Maybe DeclaratorId
  348. -- "special" meaning: without any type-specifiers.
  349. isSpecialFunc x
  350. | Just s@(MemberDeclaration l _ _) cast x, null (convert l :: [TypeSpecifier]) = convert s
  351. | Just (MemberFunctionDefinition f@(FunctionDefinition Nothing _ _) _) cast x = Just $ convert f
  352. | Just (MemberTemplateDeclaration d) cast x = isSpecialFunc d
  353. | Just f@(FunctionDefinition l _ _) cast x, null (convert l :: [TypeSpecifier]) = Just $ convert f
  354. | Just (TemplateDeclaration _ _ _ d) cast x = isSpecialFunc d
  355. | Just (Declaration_FunctionDefinition d) cast x = isSpecialFunc d
  356. | Just (Declaration_TemplateDeclaration d) cast x = isSpecialFunc d
  357. | Just (Declaration_BlockDeclaration d) cast x = isSpecialFunc d
  358. | Just (BlockDeclaration_SimpleDeclaration d) cast x = isSpecialFunc d
  359. | Just s@(SimpleDeclaration l _ _) cast x, null (convert l :: [TypeSpecifier]) = convert s
  360. | otherwise = Nothing
  361. isSpecialFuncWith :: Data d (DeclaratorId Bool) d Bool
  362. isSpecialFuncWith p x
  363. | Just did isSpecialFunc x = p did
  364. | otherwise = False
  365. isConstructorId :: DeclaratorId Bool
  366. isConstructorId i = not $ isDestructorId i isConversionFunctionId i
  367. isDestructorId :: DeclaratorId Bool
  368. isDestructorId (DeclaratorId_IdExpression Nothing (IdExpression e)) = case e of
  369. Right (UnqualifiedId_Destructor _ _) True
  370. Left (NestedUnqualifiedId _ _ _ (UnqualifiedId_Destructor _ _)) True
  371. _ False
  372. isDestructorId _ = False
  373. isConversionFunctionId :: DeclaratorId Bool
  374. isConversionFunctionId = Maybe.isJust . (convert :: DeclaratorId Maybe ConversionFunctionId)
  375. isDeclarationOf :: Data d d DeclaratorId Bool
  376. isDeclarationOf x did = Just did == case () of { ()
  377. | Just s cast x convert (s :: Declaration)
  378. | Just s cast x convert (s :: BlockDeclaration)
  379. | Just s cast x Just $ convert (s :: FunctionDefinition)
  380. | Just s cast x convert (s :: TemplateDeclaration)
  381. | Just s cast x convert (s :: ExplicitInstantiation)
  382. | Just s cast x convert (s :: ExplicitSpecialization)
  383. | Just s cast x convert (s :: NamespaceDefinition)
  384. | Just s cast x convert (s :: SimpleDeclaration)
  385. | Just s cast x Just $ convert (s :: NamespaceAliasDefinition)
  386. | Just s cast x convert (s :: UsingDeclaration)
  387. | Just s cast x Just $ convert (s :: AliasDeclaration)
  388. | Just s cast x convert (s :: MemberDeclaration)
  389. | Just s cast x convert (s :: ExceptionDeclaration)
  390. | Just s cast x convert (s :: ParameterDeclaration)
  391. | Just s cast x convert (s :: Condition)
  392. | Just s cast x Just $ convert (s :: ForRangeDeclaration)
  393. | otherwise Nothing }
  394. -- Specifier/qualifier compatibility.
  395. class Compatible a b where compatible :: a b Bool
  396. -- For instances where a=b, compatible should be symmetric.
  397. instance Compatible CvQualifier CvQualifier where compatible = ()
  398. instance Compatible CvQualifier TypeSpecifier where
  399. compatible cv (TypeSpecifier_TrailingTypeSpecifier (TrailingTypeSpecifier_CvQualifier (cv', _))) = compatible cv cv'
  400. compatible _ _ = True
  401. instance Compatible CvQualifier DeclSpecifier where
  402. compatible cv (DeclSpecifier_TypeSpecifier t) = compatible cv t
  403. compatible _ _ = True
  404. instance Compatible SimpleTypeSpecifier SimpleTypeSpecifier where
  405. compatible (SignSpec _) (LengthSpec _) = True
  406. compatible (LengthSpec _) (SignSpec _) = True
  407. compatible (LengthSpec (LongSpec, _)) (SimpleTypeSpecifier_BasicType (Int', _)) = True
  408. compatible (LengthSpec (LongSpec, _)) (SimpleTypeSpecifier_BasicType (Double', _)) = True
  409. compatible x@(SimpleTypeSpecifier_BasicType _) y@(LengthSpec _) = compatible y x
  410. compatible (SignSpec _) (SimpleTypeSpecifier_BasicType (Int', _)) = True
  411. compatible (SimpleTypeSpecifier_BasicType (Int', _)) (SignSpec _) = True
  412. compatible _ _ = False
  413. instance Compatible TrailingTypeSpecifier TrailingTypeSpecifier where
  414. compatible (TrailingTypeSpecifier_CvQualifier (cv, _)) (TrailingTypeSpecifier_CvQualifier (cv', _)) = compatible cv cv'
  415. compatible (TrailingTypeSpecifier_CvQualifier _) _ = True
  416. compatible _ (TrailingTypeSpecifier_CvQualifier _) = True
  417. compatible (TrailingTypeSpecifier_SimpleTypeSpecifier x) (TrailingTypeSpecifier_SimpleTypeSpecifier y) = compatible x y
  418. compatible _ _ = False
  419. instance Compatible TypeSpecifier TypeSpecifier where
  420. compatible (TypeSpecifier_TrailingTypeSpecifier x) (TypeSpecifier_TrailingTypeSpecifier y) = compatible x y
  421. compatible _ _ = False
  422. instance Compatible MakeSpecifier MakeSpecifier where
  423. compatible (MakeSpecifier_DeclSpecifier d) (MakeSpecifier_DeclSpecifier d') = compatible d d'
  424. compatible x@(MakeSpecifier_DeclSpecifier _) y = compatible y x
  425. compatible (NonStorageClassSpecifier scs) (MakeSpecifier_DeclSpecifier (DeclSpecifier_StorageClassSpecifier (scs', _))) = scs ≠ scs'
  426. compatible _ _ = True
  427. instance Compatible DeclSpecifier DeclSpecifier where
  428. compatible (DeclSpecifier_TypeSpecifier x) (DeclSpecifier_TypeSpecifier y) = compatible x y
  429. compatible (DeclSpecifier_StorageClassSpecifier _) (DeclSpecifier_StorageClassSpecifier _) = False
  430. compatible (DeclSpecifier_FunctionSpecifier (s, _)) (DeclSpecifier_FunctionSpecifier (s', _)) | s == s' = False
  431. compatible (DeclSpecifier_Typedef _) (DeclSpecifier_Typedef _) = False
  432. compatible (DeclSpecifier_ConstExpr _) (DeclSpecifier_ConstExpr _) = False
  433. compatible (DeclSpecifier_AlignmentSpecifier _) (DeclSpecifier_AlignmentSpecifier _) = False
  434. compatible (DeclSpecifier_FunctionSpecifier (Virtual, _)) (DeclSpecifier_StorageClassSpecifier (Static, _)) = False
  435. compatible (DeclSpecifier_StorageClassSpecifier (Static, _)) (DeclSpecifier_FunctionSpecifier (Virtual, _)) = False
  436. compatible _ _ = True
  437. -- Making sure things end with whitespace.
  438. data WithAlternate a = WithoutAlternate a | WithAlternate { _wa_primary :: a, _wa_alternate :: a } deriving Typeable
  439. instance Functor WithAlternate where
  440. fmap f (WithoutAlternate x) = WithoutAlternate $ f x
  441. fmap f (WithAlternate x y) = WithAlternate (f x) (f y)
  442. with_trailing_white :: Data d d d
  443. with_trailing_white = \x case f x of WithoutAlternate y y; WithAlternate _ y y
  444. where
  445. f :: Data d d WithAlternate d
  446. f | Just h cast (\w@(White s) WithAlternate w (White $ if null s then " " else s)) = h
  447. | otherwise = gfoldl (\e d case e of
  448. (WithAlternate h i) case f d of
  449. WithoutAlternate x WithAlternate (h x) (i x)
  450. WithAlternate x y WithAlternate (h x) (h y)
  451. (WithoutAlternate h) h . f d) WithoutAlternate
  452. -- Specifier/qualifier conversion
  453. instance Convert TrailingTypeSpecifier TypeSpecifier where convert = TypeSpecifier_TrailingTypeSpecifier
  454. instance Convert (BasicType, White) TypeSpecifier where convert = convert . TrailingTypeSpecifier_SimpleTypeSpecifier . SimpleTypeSpecifier_BasicType
  455. instance Convert (BasicType, White) DeclSpecifier where convert = (convert :: TypeSpecifier DeclSpecifier) . convert
  456. instance Convert CvQualifier TrailingTypeSpecifier where convert cvq = TrailingTypeSpecifier_CvQualifier (cvq, White " ")
  457. instance Convert CvQualifier TypeSpecifier where convert = convert . (convert :: CvQualifier TrailingTypeSpecifier)
  458. instance Convert CvQualifier DeclSpecifier where convert = convert . (convert :: CvQualifier TypeSpecifier)
  459. instance Convert CvQualifier MakeSpecifier where convert = convert . (convert :: TypeSpecifier DeclSpecifier) . convert
  460. instance Convert SimpleTypeSpecifier (Maybe Sign) where convert (SignSpec (s, _)) = Just s; convert _ = Nothing
  461. instance Convert SimpleTypeSpecifier (Maybe LengthSpec) where convert (LengthSpec (s, _)) = Just s; convert _ = Nothing
  462. instance Convert SimpleTypeSpecifier TypeSpecifier where convert = convert . TrailingTypeSpecifier_SimpleTypeSpecifier
  463. instance Convert TypeSpecifier DeclSpecifier where convert = DeclSpecifier_TypeSpecifier
  464. instance Convert TypeSpecifier (Maybe Sign) where convert x = convert x >>= (convert :: SimpleTypeSpecifier Maybe Sign)
  465. instance Convert TypeSpecifier (Maybe SimpleTypeSpecifier) where convert (TypeSpecifier_TrailingTypeSpecifier (TrailingTypeSpecifier_SimpleTypeSpecifier s)) = Just s; convert _ = Nothing
  466. instance Convert TypeSpecifier (Maybe LengthSpec) where convert x = convert x >>= (convert :: SimpleTypeSpecifier Maybe LengthSpec)
  467. instance Convert TypeSpecifier (Maybe (CvQualifier, White)) where convert (TypeSpecifier_TrailingTypeSpecifier (TrailingTypeSpecifier_CvQualifier cvq)) = Just cvq; convert _ = Nothing
  468. instance Convert TypeSpecifier (Maybe CvQualifier) where convert x = fst . (convert x :: Maybe (CvQualifier, White))
  469. instance Convert DeclSpecifier (Maybe TypeSpecifier) where convert (DeclSpecifier_TypeSpecifier s) = Just s; convert _ = Nothing
  470. instance Convert DeclSpecifier (Maybe StorageClassSpecifier) where convert (DeclSpecifier_StorageClassSpecifier (s, _)) = Just s; convert _ = Nothing
  471. instance Convert DeclSpecifier (Maybe FunctionSpecifier) where convert (DeclSpecifier_FunctionSpecifier (s, _)) = Just s; convert _ = Nothing
  472. instance Convert DeclSpecifier MakeSpecifier where convert = MakeSpecifier_DeclSpecifier
  473. instance Convert DeclSpecifier (Maybe Sign) where convert x = convert x >>= (convert :: TypeSpecifier Maybe Sign)
  474. instance Convert DeclSpecifier (Maybe LengthSpec) where convert x = convert x >>= (convert :: TypeSpecifier Maybe LengthSpec)
  475. instance Convert DeclSpecifier (Maybe (CvQualifier, White)) where convert (DeclSpecifier_TypeSpecifier t) = convert t; convert _ = Nothing
  476. instance Convert DeclSpecifier (Maybe CvQualifier) where convert x = fst . (convert x :: Maybe (CvQualifier, White))
  477. instance Convert MakeSpecifier (Maybe (CvQualifier, White)) where convert (MakeSpecifier_DeclSpecifier t) = convert t; convert _ = Nothing
  478. instance Convert LengthSpec SimpleTypeSpecifier where convert x = LengthSpec (x, White " ")
  479. instance Convert LengthSpec TypeSpecifier where convert = convert . (convert :: LengthSpec SimpleTypeSpecifier)
  480. instance Convert LengthSpec DeclSpecifier where convert = convert . (convert :: LengthSpec TypeSpecifier)
  481. instance Convert LengthSpec MakeSpecifier where convert = convert . (convert :: LengthSpec DeclSpecifier)
  482. -- Misc conversions
  483. instance Convert PtrDeclarator Declarator where convert = Declarator_PtrDeclarator
  484. instance Convert NoptrDeclarator PtrDeclarator where convert = PtrDeclarator_NoptrDeclarator
  485. instance Convert NoptrDeclarator Declarator where convert = convert . (convert :: NoptrDeclarator PtrDeclarator)
  486. instance Convert NoptrDeclarator InitDeclarator where convert = flip InitDeclarator Nothing . convert
  487. instance Convert DeclaratorId (Maybe ConversionFunctionId) where
  488. convert (DeclaratorId_IdExpression Nothing (IdExpression e)) =
  489. case e of
  490. Left (NestedUnqualifiedId _ _ _ (UnqualifiedId_ConversionFunctionId i)) Just i
  491. Right (UnqualifiedId_ConversionFunctionId i) Just i
  492. _ Nothing
  493. convert _ = Nothing
  494. -- Declaration splitting
  495. class SplitDecls a where split_decls :: a NeList a
  496. instance SplitDecls Declaration where
  497. split_decls (Declaration_BlockDeclaration bd) = fmap Declaration_BlockDeclaration $ split_decls bd
  498. split_decls d = return d
  499. instance SplitDecls BlockDeclaration where
  500. split_decls (BlockDeclaration_SimpleDeclaration sd) = fmap BlockDeclaration_SimpleDeclaration $ split_decls sd
  501. split_decls d = return d
  502. instance SplitDecls SimpleDeclaration where
  503. split_decls d@(SimpleDeclaration _ Nothing _) = return d
  504. split_decls (SimpleDeclaration specs (Just (InitDeclaratorList (Commad x l))) w) =
  505. (\y SimpleDeclaration specs (Just (InitDeclaratorList (Commad y []))) w) . (x :| (snd . l))
  506. instance SplitDecls Statement where
  507. split_decls (Statement_DeclarationStatement (DeclarationStatement d)) =
  508. Statement_DeclarationStatement . DeclarationStatement . split_decls d
  509. split_decls (Statement_CompoundStatement (CompoundStatement (Curlied x (Enclosed (Just (StatementSeq l))) y))) =
  510. return (Statement_CompoundStatement $ CompoundStatement $ Curlied x (Enclosed $ Just $ StatementSeq $ l >>= split_decls) y)
  511. split_decls (Statement_SelectionStatement (IfStatement k c s Nothing)) =
  512. return (Statement_SelectionStatement $ IfStatement k c (compound_split_decls s) Nothing) -- todo: do else part as well
  513. -- todo: do while and do-loops as well.
  514. split_decls s = return $ gmapT split_all_decls s
  515. instance SplitDecls MemberDeclaration where
  516. split_decls (MemberDeclaration specs (Just (MemberDeclaratorList (Commad d ds))) s) =
  517. (\d' → MemberDeclaration specs (Just (MemberDeclaratorList (Commad d' []))) s) . (d :| (snd . ds))
  518. split_decls d = return $ gmapT split_all_decls d
  519. compound_split_decls :: Statement Statement
  520. compound_split_decls s
  521. | null (NeList.tail l) = NeList.head l
  522. | otherwise = Statement_CompoundStatement $ CompoundStatement $ Curlied (OpenCurly_, White "") (Enclosed $ Just $ StatementSeq l) (CloseCurly_, White "")
  523. where l = split_decls s
  524. split_all_decls :: Data a a a
  525. split_all_decls = everywhere $ Maybe.fromMaybe id $ Maybe.listToMaybe . Maybe.catMaybes $
  526. [ cast ((>>= split_decls) :: NeList Declaration NeList Declaration)
  527. , cast ((>>= split_decls) :: NeList Statement NeList Statement)
  528. , cast (compound_split_decls :: Statement Statement)
  529. , cast (concatMap (either (map Left . toList . split_decls) ((:[]) . Right)) :: [Either MemberDeclaration MemberAccessSpecifier] [Either MemberDeclaration MemberAccessSpecifier])
  530. ]
  531. -- Qualifier/specifier classification
  532. is_primary_TrailingTypeSpecifier :: TrailingTypeSpecifier Bool
  533. is_primary_TrailingTypeSpecifier (TrailingTypeSpecifier_CvQualifier _) = False
  534. is_primary_TrailingTypeSpecifier _ = True
  535. is_primary_TypeSpecifier :: TypeSpecifier Bool
  536. is_primary_TypeSpecifier (TypeSpecifier_TrailingTypeSpecifier t) = is_primary_TrailingTypeSpecifier t
  537. is_primary_TypeSpecifier _ = True
  538. is_primary_DeclSpecifier :: DeclSpecifier Bool
  539. is_primary_DeclSpecifier (DeclSpecifier_TypeSpecifier t) = is_primary_TypeSpecifier t
  540. is_primary_DeclSpecifier _ = False
  541. is_primary_MakeSpecifier :: MakeSpecifier Bool
  542. is_primary_MakeSpecifier (MakeSpecifier_DeclSpecifier t) = is_primary_DeclSpecifier t
  543. is_primary_MakeSpecifier _ = False
  544. instance Apply a b b Apply [a] b b where apply = flip $ foldl $ flip apply
  545. instance Apply a b c Apply a (Enclosed b) (Enclosed c) where apply x (Enclosed y) = Enclosed $ apply x y
  546. instance MaybeApply a b MaybeApply a (Enclosed b) where mapply x (Enclosed y) = Enclosed . mapply x y
  547. -- Id application
  548. instance Apply DeclaratorId PtrAbstractDeclarator PtrDeclarator where
  549. apply i (PtrAbstractDeclarator_NoptrAbstractDeclarator npad) = PtrDeclarator_NoptrDeclarator $ apply i npad
  550. apply i (PtrAbstractDeclarator o Nothing) = PtrDeclarator (with_trailing_white o) $ PtrDeclarator_NoptrDeclarator $ NoptrDeclarator_Id i
  551. apply i (PtrAbstractDeclarator o (Just pad)) = let pd = apply i pad in PtrDeclarator (case Cxx.Show.show_simple pd of
  552. (h:_) | not (isIdChar h) o; _ with_trailing_white o) pd
  553. instance Apply DeclaratorId NoptrAbstractDeclarator NoptrDeclarator where
  554. apply i (NoptrAbstractDeclarator Nothing (Right s)) = NoptrDeclarator_Squared (NoptrDeclarator_Id i) s
  555. apply i (NoptrAbstractDeclarator (Just npad) (Right s)) = NoptrDeclarator_Squared (apply i npad) s
  556. apply i (NoptrAbstractDeclarator Nothing (Left params)) = NoptrDeclarator_WithParams (NoptrDeclarator_Id i) params
  557. apply i (NoptrAbstractDeclarator (Just npad) (Left params)) = NoptrDeclarator_WithParams (apply i npad) params
  558. apply i (NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w (Enclosed pad) w')) =
  559. NoptrDeclarator_Parenthesized $ Parenthesized w (Enclosed $ apply i pad) w'
  560. -- TypeSpecifier application
  561. -- Here and elsewhere, we always keep specifiers in the order they appeared in the source text as much as possible.
  562. instance Apply TypeSpecifier (NeList TypeSpecifier) (NeList TypeSpecifier) where
  563. apply d = (with_trailing_white d :|) . filter (compatible d) . toList
  564. -- DeclSpecifier application
  565. instance Apply DeclSpecifier [DeclSpecifier] [DeclSpecifier] where
  566. apply d = (with_trailing_white d :) . filter (compatible d)
  567. instance Apply DeclSpecifier (NeList DeclSpecifier) (NeList DeclSpecifier) where
  568. apply d = (with_trailing_white d :|) . filter (compatible d) . toList
  569. instance Apply [DeclSpecifier] (NeList DeclSpecifier) (NeList DeclSpecifier) where
  570. apply [] l = l
  571. apply l@(h:t) x = h :| (with_trailing_white t ++ filter (\s all (compatible s) l) (toList x))
  572. instance MaybeApply DeclSpecifier (NeList TypeSpecifier) where
  573. mapply (DeclSpecifier_TypeSpecifier x) typespecs = return $ apply x typespecs
  574. mapply x _ = throwError $ "Invalid decl-specifier for type-specifier-seq: " ++ Cxx.Show.show_simple x
  575. instance MaybeApply [DeclSpecifier] (NeList TypeSpecifier) where
  576. mapply = flip $ foldM $ flip mapply
  577. -- MakeSpecifier application
  578. type M = ([MakeSpecifier], Maybe PtrAbstractDeclarator)
  579. instance MaybeApply M (DeclSpecifierSeq, Either Declarator (Maybe AbstractDeclarator)) where
  580. mapply x (l, Left d) | (l', d') apply x (l, d) = return (l', Left d')
  581. mapply x (DeclSpecifierSeq l, Right Nothing) = return $
  582. first DeclSpecifierSeq $ second (Right . (AbstractDeclarator_PtrAbstractDeclarator .)) $
  583. apply x (l, Nothing :: Maybe PtrAbstractDeclarator)
  584. mapply x (DeclSpecifierSeq l, Right (Just (AbstractDeclarator_PtrAbstractDeclarator d))) = return $
  585. first DeclSpecifierSeq $ second (Right . (AbstractDeclarator_PtrAbstractDeclarator .)) $ apply x (l, Just d)
  586. mapply _ (_, Right (Just (AbstractDeclarator_Ellipsis _))) = throwError "Sorry, make-application to abstract-declarator with ellipsis not yet implemented."
  587. instance MaybeApply M (TypeSpecifierSeq, Declarator) where
  588. mapply x (l, Declarator_PtrDeclarator d) = second Declarator_PtrDeclarator . mapply x (l, d)
  589. mapply _ _ = throwError "Sorry, not yet implemented."
  590. instance Apply M (Maybe DeclSpecifierSeq, Declarator) (Maybe DeclSpecifierSeq, Declarator) where
  591. apply x (y, Declarator_PtrDeclarator d) = second Declarator_PtrDeclarator $ apply x (y, d)
  592. apply _ y = y -- Sorry, not yet implemented.
  593. instance Apply M (NeList DeclSpecifier, Declarator) (NeList DeclSpecifier, Declarator) where
  594. apply x (l, Declarator_PtrDeclarator d) = second Declarator_PtrDeclarator $ apply x (l, d)
  595. apply _ y = y -- Sorry, not yet implemented.
  596. instance Apply M (DeclSpecifierSeq, Declarator) (DeclSpecifierSeq, Declarator) where
  597. apply x (DeclSpecifierSeq l, d)= first DeclSpecifierSeq $ apply x (l, d)
  598. instance Apply M (Maybe DeclSpecifierSeq, PtrDeclarator) (Maybe DeclSpecifierSeq, PtrDeclarator) where
  599. apply x (m, d) = first convert $ apply x (convert m :: [DeclSpecifier], d)
  600. instance (Apply [MakeSpecifier] (l DeclSpecifier) (l DeclSpecifier), Apply MakeSpecifier (l DeclSpecifier, PtrDeclarator) (l DeclSpecifier, PtrDeclarator)) Apply M (l DeclSpecifier, PtrDeclarator) (l DeclSpecifier, PtrDeclarator) where
  601. apply (l, Nothing) (l', x) =
  602. if any is_primary_MakeSpecifier l
  603. then (apply l l', PtrDeclarator_NoptrDeclarator $ NoptrDeclarator_Id $ convert x)
  604. else foldl (flip apply) (l', x) l
  605. apply (l, Just pad) (l', x) = (apply l l', apply (convert x :: DeclaratorId) pad)
  606. instance Apply M (NeList DeclSpecifier, Maybe PtrAbstractDeclarator) (NeList DeclSpecifier, Maybe PtrAbstractDeclarator) where
  607. apply (l, Nothing) (l', Just x) =
  608. if any is_primary_MakeSpecifier l
  609. then (apply l l', Just x)
  610. else second Just $ foldl (flip apply) (l', x) l
  611. apply (l, m) (l', Nothing) = (apply l l', m)
  612. apply (l, Just x) (l', _) = (apply l l', Just x)
  613. instance MaybeApply M (TypeSpecifierSeq, PtrDeclarator) where
  614. mapply (l, Nothing) (l', x) =
  615. if any is_primary_MakeSpecifier l
  616. then flip (,) (PtrDeclarator_NoptrDeclarator $ NoptrDeclarator_Id $ convert x) . mapply l l'
  617. else foldM (flip mapply) (l', x) l
  618. mapply (l, Just pad) (l', x) = flip (,) (apply (convert x :: DeclaratorId) pad) . mapply l l'
  619. instance MaybeApply [MakeSpecifier] TypeSpecifierSeq where mapply l l' = foldM (flip mapply) l' l
  620. instance Apply MakeSpecifier ([DeclSpecifier], PtrDeclarator) ([DeclSpecifier], PtrDeclarator) where
  621. apply s (x, y) = maybe (apply s x, y) ((,) x) (mapply s y)
  622. instance Apply MakeSpecifier (NeList DeclSpecifier, PtrAbstractDeclarator) (NeList DeclSpecifier, PtrAbstractDeclarator) where
  623. apply s (x, y) = maybe (apply s x, y) ((,) x) (mapply s y)
  624. instance MaybeApply MakeSpecifier (TypeSpecifierSeq, PtrDeclarator) where
  625. mapply s (x, y) = maybe (flip (,) y . mapply s x) (return . (,) x) (mapply s y)
  626. instance MaybeApply MakeSpecifier PtrDeclarator where
  627. mapply s (PtrDeclarator_NoptrDeclarator d) = PtrDeclarator_NoptrDeclarator . mapply s d
  628. mapply s (PtrDeclarator o d) = maybe (flip PtrDeclarator d . mapply s o) (return . PtrDeclarator o) (mapply s d)
  629. instance MaybeApply MakeSpecifier PtrAbstractDeclarator where
  630. mapply s (PtrAbstractDeclarator_NoptrAbstractDeclarator d) =
  631. PtrAbstractDeclarator_NoptrAbstractDeclarator . mapply s d
  632. mapply _ _ = throwError "Sorry, not yet implemented."
  633. instance MaybeApply MakeSpecifier PtrOperator where
  634. mapply s (PtrOperator_Ptr o cvs) = PtrOperator_Ptr o . mapply s cvs
  635. mapply s (PtrOperator_Nested x y z cvs) = PtrOperator_Nested x y z . mapply s cvs
  636. mapply _ (PtrOperator_Ref _) = throwError "Cannot apply make-specifier to reference ptr-operator."
  637. eraseCv :: CvQualifier Maybe CvQualifierSeq Maybe CvQualifierSeq
  638. eraseCv _ Nothing = Nothing
  639. eraseCv q (Just (CvQualifierSeq l)) = CvQualifierSeq . nonEmpty (neFilter (( q) . fst) l)
  640. instance MaybeApply MakeSpecifier (Maybe CvQualifierSeq) where
  641. mapply (MakeSpecifier_DeclSpecifier (DeclSpecifier_TypeSpecifier (TypeSpecifier_TrailingTypeSpecifier (TrailingTypeSpecifier_CvQualifier (cvq, _))))) =
  642. return . apply cvq
  643. mapply (NonCv cvq) = return . eraseCv cvq
  644. mapply _ = const $ throwError "Cannot apply non-cv make-specifier to cv-qualifier-seq."
  645. instance MaybeApply MakeSpecifier NoptrAbstractDeclarator where
  646. mapply s (NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w (Enclosed d) w')) = do
  647. d' ← mapply s d
  648. return (NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w (Enclosed d') w'))
  649. mapply _ _ = throwError "Sorry, not yet implemented."
  650. instance MaybeApply MakeSpecifier NoptrDeclarator where
  651. mapply _ (NoptrDeclarator_Id _) = throwError "Cannot apply make-specifier to declarator-id."
  652. mapply s (NoptrDeclarator_Parenthesized (Parenthesized w (Enclosed d) w')) = do
  653. d' ← mapply s d
  654. return (NoptrDeclarator_Parenthesized (Parenthesized w (Enclosed d') w'))
  655. mapply s (NoptrDeclarator_Squared d ce) = do
  656. d' ← mapply s d
  657. return $ NoptrDeclarator_Squared d' ce
  658. mapply s (NoptrDeclarator_WithParams d p) =
  659. case mapply s d of
  660. Just d' → return $ NoptrDeclarator_WithParams d' p
  661. Nothing NoptrDeclarator_WithParams d . mapply s p
  662. instance MaybeApply MakeSpecifier ParametersAndQualifiers where
  663. mapply (MakeSpecifier_DeclSpecifier (DeclSpecifier_TypeSpecifier (TypeSpecifier_TrailingTypeSpecifier (TrailingTypeSpecifier_CvQualifier (cvq, _))))) (ParametersAndQualifiers c cvqs m e) =
  664. return $ ParametersAndQualifiers c (apply cvq cvqs) m e
  665. mapply (NonCv cvq) (ParametersAndQualifiers c cvqs m e) =
  666. return $ ParametersAndQualifiers c (eraseCv cvq cvqs) m e
  667. mapply _ _ = throwError "Cannot apply non-cv make-specifier to parameters-and-qualifiers (yet)."
  668. instance Apply MakeSpecifier (NeList DeclSpecifier, PtrDeclarator) (NeList DeclSpecifier, PtrDeclarator) where
  669. apply s (x, y) = maybe (apply s x, y) ((,) x) (mapply s y)
  670. nonIntSpec :: (Eq s, Eq t, Convert t (Maybe s), Convert (BasicType, White) t) s NeList t NeList t
  671. nonIntSpec s l = case neFilter (( Just s) . convert) l of
  672. l'@(h:t) | (convert (Int', White "") l') ∨ (convert (Double', White "") l') → h :| t
  673. l' → convert (Int', White " ") :| l'
  674. instance MaybeApply MakeSpecifier (NeList TypeSpecifier) where
  675. mapply (MakeSpecifier_DeclSpecifier s) = mapply s
  676. mapply (NonStorageClassSpecifier _) = return
  677. mapply (NonFunctionSpecifier _) = return
  678. mapply (NonCv cvq) = return . filter_but_keep_nonempty (( Just cvq) . convert)
  679. mapply (NonSign s) = return . nonIntSpec s
  680. mapply (NonLength s) = return . nonIntSpec s
  681. mapply LongLong = return . (convert LongSpec :|) . (convert LongSpec :) . filter (compatible (convert LongSpec :: TypeSpecifier)) . toList
  682. instance MaybeApply MakeSpecifier TypeSpecifierSeq where
  683. mapply s (TypeSpecifierSeq l) = TypeSpecifierSeq . mapply s l
  684. -- decl-specifier-seqs (which are always nonempty) always contain at least one primary specifier. Hence, removing, say, all cv-qualifiers, will always produce a proper (nonempty) decl-specifier-seq. However, the type system does not know that, and so we use the following ugly function:
  685. filter_but_keep_nonempty :: forall a . (a Bool) NeList a NeList a
  686. filter_but_keep_nonempty p l = nonEmpty (filter p $ toList l) `orElse` return (NeList.head l)
  687. instance Apply MakeSpecifier (NeList DeclSpecifier) (NeList DeclSpecifier) where
  688. apply (MakeSpecifier_DeclSpecifier s) = apply s
  689. apply (NonStorageClassSpecifier scs) = filter_but_keep_nonempty $ ( Just scs) . convert
  690. apply (NonFunctionSpecifier fs) = filter_but_keep_nonempty $ ( Just fs) . convert
  691. apply (NonCv cvq) = filter_but_keep_nonempty $ ( Just cvq) . convert
  692. apply (NonSign s) = nonIntSpec s
  693. apply (NonLength s) = nonIntSpec s
  694. apply LongLong = (convert LongSpec :|) . (convert LongSpec :) . filter (compatible (convert LongSpec :: DeclSpecifier)) . toList
  695. instance Apply MakeSpecifier [DeclSpecifier] [DeclSpecifier] where
  696. apply (MakeSpecifier_DeclSpecifier d) = apply d
  697. apply (NonStorageClassSpecifier scs) = filter $ ( Just scs) . convert
  698. apply (NonFunctionSpecifier fs) = filter $ ( Just fs) . convert
  699. apply (NonCv cvq) = filter $ ( Just cvq) . convert
  700. apply (NonSign s) = maybe [] (toList . nonIntSpec s) . nonEmpty
  701. apply (NonLength s) = maybe [] (toList . nonIntSpec s) . nonEmpty
  702. apply LongLong = (convert LongSpec :) . (convert LongSpec :) . filter (compatible (convert LongSpec :: DeclSpecifier))
  703. -- PtrOperator application
  704. instance MaybeApply PtrOperator (Maybe AbstractDeclarator) where
  705. mapply o Nothing = return $ Just $ AbstractDeclarator_PtrAbstractDeclarator $ PtrAbstractDeclarator o Nothing
  706. mapply o (Just (AbstractDeclarator_PtrAbstractDeclarator pad)) =
  707. return $ Just $ AbstractDeclarator_PtrAbstractDeclarator $ apply o pad
  708. mapply _ (Just (AbstractDeclarator_Ellipsis _)) = throwError "Cannot apply ptr-operator to ellipsis."
  709. instance Apply PtrOperator PtrAbstractDeclarator PtrAbstractDeclarator where
  710. apply o (PtrAbstractDeclarator_NoptrAbstractDeclarator npad) =
  711. PtrAbstractDeclarator_NoptrAbstractDeclarator (apply o npad)
  712. apply o (PtrAbstractDeclarator o' Nothing) =
  713. PtrAbstractDeclarator o' $ Just $ PtrAbstractDeclarator o Nothing
  714. apply o (PtrAbstractDeclarator o' (Just pad)) = PtrAbstractDeclarator o' $ Just $ apply o pad
  715. instance Apply PtrOperator NoptrAbstractDeclarator NoptrAbstractDeclarator where
  716. apply o (NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w pad w')) =
  717. NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w (apply o pad) w')
  718. apply o (NoptrAbstractDeclarator (Just npad) e) = NoptrAbstractDeclarator (Just $ apply o npad) e
  719. apply o (NoptrAbstractDeclarator Nothing e) =
  720. NoptrAbstractDeclarator (Just $ NoptrAbstractDeclarator_PtrAbstractDeclarator $ parenthesized (PtrAbstractDeclarator o Nothing)) e
  721. instance Apply PtrOperator ([TypeSpecifier], Either TypeSpecifier PtrAbstractDeclarator)
  722. ([TypeSpecifier], PtrAbstractDeclarator) where
  723. apply o (specs, Left spec) = (specs ++ [spec], PtrAbstractDeclarator o Nothing)
  724. apply o (specs, Right ad) = (specs, apply o ad)
  725. -- Declarator application
  726. instance Apply (Maybe PtrAbstractDeclarator) ([TypeSpecifier], Either TypeSpecifier PtrAbstractDeclarator)
  727. ([TypeSpecifier], Either TypeSpecifier PtrAbstractDeclarator) where
  728. apply Nothing = id
  729. apply (Just ad) = second Right . apply ad
  730. instance Apply PtrAbstractDeclarator ([TypeSpecifier], Either TypeSpecifier PtrAbstractDeclarator)
  731. ([TypeSpecifier], PtrAbstractDeclarator) where
  732. apply pad (specs, Left spec) = (specs ++ [spec], pad)
  733. apply pad (specs, Right pad') = (specs, apply pad pad')
  734. instance Apply PtrAbstractDeclarator PtrAbstractDeclarator PtrAbstractDeclarator where
  735. apply pad (PtrAbstractDeclarator o Nothing) = PtrAbstractDeclarator o $ Just pad
  736. apply pad (PtrAbstractDeclarator o (Just pad')) = PtrAbstractDeclarator o $ Just $ apply pad pad'
  737. apply pad (PtrAbstractDeclarator_NoptrAbstractDeclarator npad') = PtrAbstractDeclarator_NoptrAbstractDeclarator (apply pad npad')
  738. instance Apply PtrAbstractDeclarator NoptrAbstractDeclarator NoptrAbstractDeclarator where
  739. apply pad (NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w pad' w')) =
  740. NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w (apply pad pad') w')
  741. apply (PtrAbstractDeclarator_NoptrAbstractDeclarator npad) npad' = apply npad npad'
  742. apply pad (NoptrAbstractDeclarator Nothing e) = NoptrAbstractDeclarator (Just $ NoptrAbstractDeclarator_PtrAbstractDeclarator $ parenthesized pad) e
  743. apply pad (NoptrAbstractDeclarator (Just npad) e) = NoptrAbstractDeclarator (Just $ apply pad npad) e
  744. instance Apply NoptrAbstractDeclarator (Maybe NoptrAbstractDeclarator) NoptrAbstractDeclarator where
  745. apply x = maybe x (apply x)
  746. instance Apply NoptrAbstractDeclarator NoptrAbstractDeclarator NoptrAbstractDeclarator where
  747. apply npad (NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w pad w')) =
  748. NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w (apply (PtrAbstractDeclarator_NoptrAbstractDeclarator npad) pad) w')
  749. apply npad (NoptrAbstractDeclarator m e) = NoptrAbstractDeclarator (Just $ apply npad m) e
  750. -- MakeDeclaration application
  751. instance Convert [a] (Maybe (NeList a)) where convert = nonEmpty
  752. instance Convert [DeclSpecifier] (Maybe DeclSpecifierSeq) where convert = fmap DeclSpecifierSeq . convert
  753. instance Convert (Maybe DeclSpecifierSeq) [DeclSpecifier] where
  754. convert Nothing = []
  755. convert (Just (DeclSpecifierSeq l)) = toList l
  756. instance Convert (Maybe DeclSpecifierSeq) [TypeSpecifier] where
  757. convert = convert . (convert :: Maybe DeclSpecifierSeq [DeclSpecifier])
  758. instance Apply MakeDeclaration (Maybe DeclSpecifierSeq, Declarator, Maybe (Either PureSpecifier BraceOrEqualInitializer)) (Maybe DeclSpecifierSeq, Declarator, Maybe (Either PureSpecifier BraceOrEqualInitializer)) where
  759. apply (MakeDeclaration specs m b) (specs', d, p) = (convert specs'', d', pure)
  760. where
  761. (specs'', d') = first (convert :: Maybe DeclSpecifierSeq → [DeclSpecifier]) $ apply (specs, m) (specs', d)
  762. pure = if any (\ms case ms of NonFunctionSpecifier Virtual True; MakeSpecifier_DeclSpecifier (DeclSpecifier_StorageClassSpecifier (Static, _)) True; _ False) specs then Nothing else case b of Definitely Just $ Left $ PureSpecifier (IsOperator, White " ") (KwdZero, White " "); Indeterminate p; DefinitelyNot Nothing
  763. instance MaybeApply MakeDeclaration FunctionDefinition where
  764. mapply (MakeDeclaration _ _ Definitely) _ = throwError "Cannot purify function-definition."
  765. mapply (MakeDeclaration specs' mpad _) (FunctionDefinition specs decl body) =
  766. return $ FunctionDefinition specs'' decl' body
  767. where (specs'', decl') = apply (specs', mpad) (specs, decl)
  768. instance MaybeApply MakeDeclaration ParameterDeclaration where
  769. mapply (MakeDeclaration _ _ Definitely) _ = throwError "Cannot purify parameter-declaration."
  770. mapply (MakeDeclaration specs' mpad _) (ParameterDeclaration specs x m) = (\(specs'', x') ParameterDeclaration specs'' x' m) . mapply (specs', mpad) (specs, x)
  771. instance MaybeApply MakeDeclaration ForRangeDeclaration where
  772. mapply (MakeDeclaration _ _ Definitely) _ = throwError "Cannot purify for-range-declaration."
  773. mapply (MakeDeclaration specs' mpad _) (ForRangeDeclaration specs d) =
  774. return $ uncurry ForRangeDeclaration $ apply (specs', mpad) (specs, d)
  775. -- cv-qualifier application
  776. instance Apply CvQualifier (Maybe CvQualifierSeq) (Maybe CvQualifierSeq) where
  777. apply cvq Nothing = Just $ CvQualifierSeq $ return (cvq, White " ")
  778. apply cvq (Just x) = Just $ apply cvq x
  779. instance Apply CvQualifier CvQualifierSeq CvQualifierSeq where
  780. apply cvq (CvQualifierSeq l) = CvQualifierSeq $ if any ((== cvq) . fst) l then l else NeList.cons (cvq, White " ") l
  781. instance MaybeApply CvQualifier a MaybeApply [CvQualifier] a where
  782. mapply l x = foldM (flip mapply) x l
  783. instance MaybeApply CvQualifier PtrOperator where
  784. mapply cvq (PtrOperator_Nested mw n w cvq') = return $ PtrOperator_Nested mw n w $ apply cvq cvq'
  785. mapply cvq (PtrOperator_Ptr w cvq') = return $ PtrOperator_Ptr w $ apply cvq cvq'
  786. mapply _ (PtrOperator_Ref _) = throwError "Cannot cv-qualify reference."
  787. instance (Convert CvQualifier t, Compatible t t) Apply CvQualifier [t] [t] where
  788. apply cvq l = let x = convert cvq in if any (not . compatible x) l then l else x : l
  789. instance (Convert CvQualifier t, Compatible t t) Apply CvQualifier (NeList t) (NeList t) where
  790. apply cvq l = let x = convert cvq in if any (not . compatible x) (toList l) then l else NeList.cons x l
  791. -- todo: merge last two using ListLike
  792. instance Apply CvQualifier x x Apply CvQualifier (x, Maybe PtrAbstractDeclarator) (x, Maybe PtrAbstractDeclarator) where
  793. apply cvq (l, Just ad) | Just ad' ← mapply cvq ad = (l, Just ad')
  794. apply cvq (l, mad) = (apply cvq l, mad)
  795. instance MaybeApply CvQualifier InitDeclarator where
  796. mapply cvq (InitDeclarator d mi) = flip InitDeclarator mi . mapply cvq d
  797. instance MaybeApply CvQualifier Declarator where
  798. mapply cvq (Declarator_PtrDeclarator d) = Declarator_PtrDeclarator . mapply cvq d
  799. mapply _ _ = throwError "Sorry, not yet implemented."
  800. instance MaybeApply CvQualifier PtrDeclarator where
  801. mapply cvq (PtrDeclarator_NoptrDeclarator d) = PtrDeclarator_NoptrDeclarator . mapply cvq d
  802. mapply cvq (PtrDeclarator o d) = case mapply cvq d of
  803. Just d' → return $ PtrDeclarator o d'
  804. Nothing flip PtrDeclarator d . mapply cvq o
  805. instance MaybeApply CvQualifier NoptrDeclarator where
  806. mapply cvq (NoptrDeclarator_WithParams d p) = return $ case mapply cvq d of
  807. Just d' → NoptrDeclarator_WithParams d' p
  808. Nothing NoptrDeclarator_WithParams d $ apply cvq p
  809. mapply cvq (NoptrDeclarator_Parenthesized (Parenthesized w d w'))
  810. = NoptrDeclarator_Parenthesized . (\x Parenthesized w x w') . mapply cvq d
  811. mapply cvq (NoptrDeclarator_Squared d s) = flip NoptrDeclarator_Squared s . mapply cvq d
  812. mapply _ (NoptrDeclarator_Id _) = throwError "Cannot cv-qualify declarator-id."
  813. instance Apply CvQualifier ParametersAndQualifiers ParametersAndQualifiers where
  814. apply cvq (ParametersAndQualifiers d cvq' m e) = ParametersAndQualifiers d (apply cvq cvq') m e
  815. instance Apply CvQualifier ([TypeSpecifier], Either TypeSpecifier PtrAbstractDeclarator)
  816. ([TypeSpecifier], Either TypeSpecifier PtrAbstractDeclarator) where
  817. apply cvq (l, Right ad)
  818. | Just ad' ← mapply cvq ad = (l, Right ad')
  819. | otherwise = (apply cvq l, Right ad)
  820. apply cvq (l, Left s) = let (s', l') = neElim $ apply cvq (s :| l) in (l', Left s')
  821. instance MaybeApply CvQualifier PtrAbstractDeclarator where
  822. mapply cvq (PtrAbstractDeclarator_NoptrAbstractDeclarator d) =
  823. PtrAbstractDeclarator_NoptrAbstractDeclarator . mapply cvq d
  824. mapply cvq (PtrAbstractDeclarator o Nothing) = flip PtrAbstractDeclarator Nothing . mapply cvq o
  825. mapply cvq (PtrAbstractDeclarator o (Just a)) = case mapply cvq a of
  826. Just a' → return $ PtrAbstractDeclarator o (Just a')
  827. Nothing flip PtrAbstractDeclarator (Just a) . mapply cvq o
  828. instance MaybeApply CvQualifier NoptrAbstractDeclarator where
  829. mapply cvq (NoptrAbstractDeclarator (Just d) (Right t)) = flip NoptrAbstractDeclarator (Right t) . Just . mapply cvq d
  830. mapply _ (NoptrAbstractDeclarator Nothing (Right _)) = throwError "Cannot cv-qualify leaf array noptr-abstract-declarator."
  831. mapply cvq (NoptrAbstractDeclarator m (Left p)) = return $ case m >>= mapply cvq of
  832. Nothing NoptrAbstractDeclarator m $ Left $ apply cvq p
  833. Just m' → NoptrAbstractDeclarator (Just m') $ Left p
  834. mapply cvq (NoptrAbstractDeclarator_PtrAbstractDeclarator (Parenthesized w d w')) =
  835. NoptrAbstractDeclarator_PtrAbstractDeclarator . (\x Parenthesized w x w') . mapply cvq d
  836. -- Determination of whether declarators declare pointers/references
  837. class IsPointerOrReference t r | t r where is_pointer_or_reference :: t r
  838. instance IsPointerOrReference Declarator Bool where
  839. is_pointer_or_reference (Declarator_PtrDeclarator d) = case is_pointer_or_reference d of
  840. Definitely True; _ False
  841. is_pointer_or_reference (Declarator_TrailingReturnType _ _ _) = False
  842. instance IsPointerOrReference PtrDeclarator TriBool where
  843. is_pointer_or_reference (PtrDeclarator_NoptrDeclarator d) = is_pointer_or_reference d
  844. is_pointer_or_reference (PtrDeclarator _ d) = case is_pointer_or_reference d of
  845. DefinitelyNot DefinitelyNot; _ Definitely
  846. instance IsPointerOrReference NoptrDeclarator TriBool where
  847. is_pointer_or_reference (NoptrDeclarator_Id _) = Indeterminate
  848. is_pointer_or_reference (NoptrDeclarator_WithParams d _) = case is_pointer_or_reference d of
  849. Definitely Definitely; _ DefinitelyNot
  850. is_pointer_or_reference (NoptrDeclarator_Squared d _) = case is_pointer_or_reference d of
  851. Definitely Definitely; _ DefinitelyNot
  852. is_pointer_or_reference (NoptrDeclarator_Parenthesized (Parenthesized _ (Enclosed d) _)) = is_pointer_or_reference d