makeAnchor
    :: Maybe Span       -- ^ Anchor span. If missing, anchor is implicit.
    -> AnchorEdge       -- ^ How it refers its target.
    -> Raw.VName        -- ^ Anchor target.
    -> Maybe Span       -- ^ Snippet span.
    -> Maybe Raw.VName  -- ^ Reference context (like enclosing function).
    -> Conversion [Raw.Entry]
makeAnchor mbSource anchorEdge targetVName mbSnippet mbRefContext = do
    (vname, spanOrSubkindFacts) <- fromMaybeTPureDef implicits $ do
        -- TODO(robinpalotai): CPP - spanAndOffs can be Nothing, if a macro
        --   was expanded, since GHC expands the macro on the same, "long" line
        --   with columns over the true columns of that line - and so
        --   OffsetTable will indicate failure. Could workaround and emit anchor
        --   at the beginning of the line, or more properly (?) generate small
        --   virtual files for the macro expansion.
        SpanAndOffs source offs <- spanAndOffs mbSource
        lift $ do
            anchorVN <- anchorVName (spanFile source) offs
                        targetVName
            let spanFacts = makeLocFacts offs
            return (anchorVN, spanFacts)
    snippetFacts <- fromMaybeTPureDef [] $
        makeSnippetFacts . onlyOffset <$> spanAndOffs mbSnippet
    let nodeEntries = nodeFacts vname AnchorNK . concat $
            [ spanOrSubkindFacts
            , snippetFacts
            ]
    let edgeEntries =
            edge vname (AnchorEdgeE anchorEdge) targetVName
                : maybeToList (edge vname ChildOfE <$> mbRefContext)
    return $! nodeEntries ++ edgeEntries
  where
    implicits = ( implicitAnchorVName targetVName
                , [nodeFact AnchorSubkindF ImplicitAnchor] )

-- | Makes fact about a non-reference edge.
makeAnchor
    :: Maybe Span       -- ^ Anchor span. If missing, anchor is implicit.
    -> AnchorEdge       -- ^ How it refers its target.
    -> Raw.VName        -- ^ Anchor target.
    -> Maybe Span       -- ^ Snippet span.
    -> Maybe Raw.VName  -- ^ Reference context (like enclosing function).
    -> Conversion [Raw.Entry]
makeAnchor mbSource anchorEdge targetVName mbSnippet mbRefContext = do
    (vname, spanOrSubkindFacts) <- fromMaybeTPureDef implicits $ do
        -- TODO(robinpalotai): CPP - spanAndOffs can be Nothing, if a macro
        --   was expanded, since GHC expands the macro on the same, "long" line
        --   with columns over the true columns of that line - and so
        --   OffsetTable will indicate failure. Could workaround and emit anchor
        --   at the beginning of the line, or more properly (?) generate small
        --   virtual files for the macro expansion.
        SpanAndOffs source offs <- spanAndOffs mbSource
        lift $ do
            anchorVN <- anchorVName (spanFile source) offs
                        targetVName
            let spanFacts = makeLocFacts offs
            return (anchorVN, spanFacts)
    snippetFacts <- fromMaybeTPureDef [] $
        makeSnippetFacts . onlyOffset <$> spanAndOffs mbSnippet
    let nodeEntries = nodeFacts vname AnchorNK . concat $
            [ spanOrSubkindFacts
            , snippetFacts
            ]
    let edgeEntries =
            edge vname (AnchorEdgeE anchorEdge) targetVName
                : maybeToList (edge vname ChildOfE <$> mbRefContext)
    return $! nodeEntries ++ edgeEntries
  where
    implicits = ( implicitAnchorVName targetVName
                , [nodeFact AnchorSubkindF ImplicitAnchor] )

-- | Makes fact about a non-reference edge.
makeAnchor mbSource anchorEdge targetVName mbSnippet mbRefContext = do
    (vname, spanOrSubkindFacts) <- fromMaybeTPureDef implicits $ do
        -- TODO(robinpalotai): CPP - spanAndOffs can be Nothing, if a macro
        --   was expanded, since GHC expands the macro on the same, "long" line
        --   with columns over the true columns of that line - and so
        --   OffsetTable will indicate failure. Could workaround and emit anchor
        --   at the beginning of the line, or more properly (?) generate small
        --   virtual files for the macro expansion.
        SpanAndOffs source offs <- spanAndOffs mbSource
        lift $ do
            anchorVN <- anchorVName (spanFile source) offs
                        targetVName
            let spanFacts = makeLocFacts offs
            return (anchorVN, spanFacts)
    snippetFacts <- fromMaybeTPureDef [] $
        makeSnippetFacts . onlyOffset <$> spanAndOffs mbSnippet
    let nodeEntries = nodeFacts vname AnchorNK . concat $
            [ spanOrSubkindFacts
            , snippetFacts
            ]
    let edgeEntries =
            edge vname (AnchorEdgeE anchorEdge) targetVName
                : maybeToList (edge vname ChildOfE <$> mbRefContext)
    return $! nodeEntries ++ edgeEntries
  where
    implicits = ( implicitAnchorVName targetVName
                , [nodeFact AnchorSubkindF ImplicitAnchor] )

-- | Makes fact about a non-reference edge.