Skip to content

Commit 81d0b25

Browse files
committed
Sort select messages before emitting them
1 parent 5ce12d5 commit 81d0b25

File tree

1 file changed

+73
-3
lines changed
  • hs-bindgen/src-internal/HsBindgen/Frontend/Pass

1 file changed

+73
-3
lines changed

hs-bindgen/src-internal/HsBindgen/Frontend/Pass/Select.hs

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,30 @@ module HsBindgen.Frontend.Pass.Select (
22
selectDecls
33
) where
44

5+
import Data.List (sortBy)
56
import Data.Map.Strict qualified as Map
7+
import Data.Ord (comparing)
68
import Data.Set ((\\))
79
import Data.Set qualified as Set
810

911
import Clang.HighLevel.Types
12+
import Clang.Paths
1013

1114
import HsBindgen.Errors (panicPure)
1215
import HsBindgen.Frontend.Analysis.DeclIndex (DeclIndex (..), Match,
1316
selectDeclIndex)
1417
import HsBindgen.Frontend.Analysis.DeclIndex qualified as DeclIndex
1518
import HsBindgen.Frontend.Analysis.DeclUseGraph qualified as DeclUseGraph
19+
import HsBindgen.Frontend.Analysis.IncludeGraph (IncludeGraph)
20+
import HsBindgen.Frontend.Analysis.IncludeGraph qualified as IncludeGraph
1621
import HsBindgen.Frontend.Analysis.UseDeclGraph (UseDeclGraph)
1722
import HsBindgen.Frontend.Analysis.UseDeclGraph qualified as UseDeclGraph
1823
import HsBindgen.Frontend.AST.Coerce (CoercePass (coercePass))
1924
import HsBindgen.Frontend.AST.Internal qualified as C
2025
import HsBindgen.Frontend.Naming qualified as C
2126
import HsBindgen.Frontend.Pass
2227
import HsBindgen.Frontend.Pass.ConstructTranslationUnit.IsPass
28+
import HsBindgen.Frontend.Pass.HandleMacros.Error
2329
import HsBindgen.Frontend.Pass.Parse.IsPass
2430
import HsBindgen.Frontend.Pass.ResolveBindingSpecs.IsPass
2531
import HsBindgen.Frontend.Pass.Select.IsPass
@@ -164,11 +170,15 @@ selectDecls
164170
, C.unitAnn = unitAnn
165171
}
166172

167-
in ( unitSelect
168-
, selectMsgs
173+
msgs :: [Msg Select]
174+
msgs =
175+
selectMsgs
176+
++ getDelayedMsgs selectedIndex
169177
-- If there were no predicate matches we issue a warning to the user.
170178
++ [ SelectNoDeclarationsMatched | Set.null rootIds ]
171-
++ getDelayedMsgs selectedIndex
179+
180+
in ( unitSelect
181+
, sortSelectMsgs unitIncludeGraph msgs
172182
)
173183
where
174184
notAttempted, failed, failedMacros :: Set DeclId
@@ -320,3 +330,63 @@ getDelayedMsgs DeclIndex{..} = concat [
320330

321331
getMsgss :: (a -> [b]) -> Map k a -> [b]
322332
getMsgss f = concatMap f . Map.elems
333+
334+
{-------------------------------------------------------------------------------
335+
Sort messages
336+
-------------------------------------------------------------------------------}
337+
338+
type OrderMap = Map SourcePath Int
339+
340+
buildOrderMap :: Ord a => [a] -> Map a Int
341+
buildOrderMap xs = Map.fromList (zip xs [0..])
342+
343+
-- [Performance]: Working with hashed source paths (hash them once) and a
344+
-- `HashMap` may be a bit faster.
345+
compareByOrder :: OrderMap -> SourcePath -> SourcePath -> Ordering
346+
compareByOrder xs x y =
347+
let ix = lookupUnsafe x
348+
iy = lookupUnsafe y
349+
in compare ix iy
350+
where
351+
lookupUnsafe z = case Map.lookup z xs of
352+
Nothing -> panicPure $ "unknown source path: " <> show z
353+
Just v -> v
354+
355+
compareSingleLocs :: OrderMap -> SingleLoc -> SingleLoc -> Ordering
356+
compareSingleLocs xs x y =
357+
case compareByOrder xs (singleLocPath x) (singleLocPath y) of
358+
LT -> LT
359+
EQ -> comparing getLineCol x y
360+
GT -> GT
361+
where
362+
getLineCol :: SingleLoc -> (Int, Int)
363+
getLineCol z = (singleLocLine z, singleLocColumn z)
364+
365+
getSingleLoc :: Msg Select -> Maybe SingleLoc
366+
getSingleLoc = \case
367+
SelectStatusInfo _ d -> fromD d
368+
TransitiveDependencyOfDeclarationUnavailable _ _ d -> fromD d
369+
SelectDeprecated d -> fromD d
370+
SelectParseSuccess m -> fromM m
371+
SelectParseNotAttempted (ParseNotAttempted m) -> fromM m
372+
SelectParseFailure (ParseFailure m) -> fromM m
373+
SelectMacroFailure (HandleMacrosParseMsg m) -> fromM m
374+
SelectNoDeclarationsMatched -> Nothing
375+
where
376+
fromD = Just . C.declLoc . C.declInfo
377+
fromM = Just . loc
378+
379+
compareMsgs :: OrderMap -> Msg Select -> Msg Select -> Ordering
380+
compareMsgs orderMap x y =
381+
case (getSingleLoc x, getSingleLoc y) of
382+
(Just lx, Just ly) -> compareSingleLocs orderMap lx ly
383+
-- Sort messages not attached to a declaration to the back.
384+
(Nothing, _ ) -> GT
385+
(_ , Nothing) -> LT
386+
387+
sortSelectMsgs :: IncludeGraph -> [Msg Select] -> [Msg Select]
388+
sortSelectMsgs includeGraph = sortBy (compareMsgs orderMap)
389+
where
390+
-- Compute the order map once.
391+
orderMap :: OrderMap
392+
orderMap = buildOrderMap $ IncludeGraph.toSortedList includeGraph

0 commit comments

Comments
 (0)