packages feed

doxygen-parser 0.1.1 → 0.1.2

raw patch · 4 files changed

+68/−2 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -10,6 +10,16 @@  ### Bug fixes +## 0.1.2 -- 2026-10-06++### Bug fixes++* Handle doxygen >= 1.18.0 anonymous struct/union compounds. Doxygen 1.18.0+  emits a separate XML file for each anonymous compound instead of flattening+  its fields into the enclosing struct. The parser now normalizes these compound+  names so the `DoxygenKey` map is stable across doxygen versions.+  ([hs-bindgen#2225](https://github.com/well-typed/hs-bindgen/issues/2225))+ ## 0.1.1 -- 2026-06-21  ### New features
doxygen-parser.cabal view
@@ -1,6 +1,6 @@ cabal-version:   3.0 name:            doxygen-parser-version:         0.1.1+version:         0.1.2 license:         BSD-3-Clause license-file:    LICENSE copyright:       2024-2026 Well-Typed LLP and Anduril Industries Inc.
src-internal/Doxygen/Parser/Internal.hs view
@@ -59,6 +59,7 @@   , parseInlineChildren   , normalizeWhitespace   , trimEdges+  , stripAnonymousSuffix   , XMLFileResult(..)   , extractEntity   , nodeElementName@@ -573,11 +574,15 @@     -- For struct/union compounds, all members are fields of that struct.     -- For other compounds (groups, files), fields are identified by their     -- <qualifiedname> (e.g. "config_t::id" → KeyField "config_t" "id").+    --+    -- 'stripAnonymousSuffix' normalizes compound names so that doxygen+    -- >= 1.18.0 anonymous-struct compounds (e.g. @outer::[struct].pos@)+    -- produce the same keys as the flattened layout used by older versions.     toFieldMap :: Text -> Maybe Text -> [MemberInfo] -> [(DoxygenKey, Comment DoxyRef)]     toFieldMap k mEntityName ms       | k `elem` ["struct", "union"]       , Just sname <- mEntityName-      = [(KeyField sname mi.miName, mi.miComment) | mi <- ms]+      = [(KeyField (stripAnonymousSuffix sname) mi.miName, mi.miComment) | mi <- ms]       | otherwise       = [ (KeyField sname fname, mi.miComment)         | mi <- ms@@ -1187,6 +1192,42 @@ isTitle c = case Cursor.node c of     XML.NodeElement el -> XML.nameLocalName (XML.elementName el) == "title"     _                  -> False++-- | Strip the anonymous compound suffix added by doxygen >= 1.18.0.+--+-- Given the C declaration+--+-- @+-- typedef struct {+--     struct { int ua; int ub; } pos;+-- } outer_t;+-- @+--+-- doxygen < 1.18 flattened fields @ua@ and @ub@ into+-- @structouter__t.xml@ and keyed them as @KeyField \"outer_t\" \"ua\"@.+--+-- doxygen >= 1.18 emits a separate @structouter__t_1_1...pos.xml@ with+-- compound name @\"outer_t::[struct].pos\"@, so without normalization the+-- fields would be keyed as @KeyField \"outer_t::[struct].pos\" \"ua\"@.+--+-- This function strips the suffix so the keys match the pre-1.18 layout:+--+-- @+-- stripAnonymousSuffix \"outer_t::[struct].pos\"          == \"outer_t\"+-- stripAnonymousSuffix \"outer_t::[struct].__unnamed0__\" == \"outer_t\"+-- stripAnonymousSuffix \"a::b::[union].data\"             == \"a::b\"+-- stripAnonymousSuffix \"plain_t\"                        == \"plain_t\"+-- @+--+-- With doxygen < 1.18 these patterns never appear, so the function is+-- the identity.+stripAnonymousSuffix :: Text -> Text+stripAnonymousSuffix name =+    case Text.breakOn "::[struct]." name of+      (before, after) | not (Text.null after) -> before+      _ -> case Text.breakOn "::[union]." name of+        (before, after) | not (Text.null after) -> before+        _ -> name  -- | Check if a @\<memberdef\>@ is a struct\/union field. --
test/Test/Doxygen/Parser/XMLFileResult.hs view
@@ -115,4 +115,19 @@         , "</doxygen>"         ]) $ \result ->           result.comments @?= Map.empty++  , testCase "anonymous struct fields keyed under parent (doxygen >= 1.18)" $+      withExtractedEntity+        (mkDoxygen $ mkCompound "struct"+            "structfoo_1_1anon" "foo_t::[struct].__unnamed0__" "" $+            mkSection "public-attrib" $ Text.concat+                [ mkMember "variable" "f_ua" "ua" "Unnamed inner a" ""+                , mkMember "variable" "f_ub" "ub" "Unnamed inner b" ""+                ]) $ \result -> do+          assertBool "field ua keyed under parent" $+            Map.member (KeyField "foo_t" "ua") result.comments+          assertBool "field ub keyed under parent" $+            Map.member (KeyField "foo_t" "ub") result.comments+          assertBool "NOT keyed under anonymous compound" $+            not (Map.member (KeyField "foo_t::[struct].__unnamed0__" "ua") result.comments)   ]