packages feed

libclang-bindings-0.2.0.0: src/Clang/Paths.hs

module Clang.Paths (
    -- * Source paths
    SourcePath(..)
  , getSourcePath
  , getSourcePathText

    -- * Real paths
  , RealPath(..)
  , getRealPath
  , getRealPathText
  , realPathToSourcePath

    -- * C include directories
  , CIncludeDir(..)
  ) where

import Data.String
import Data.Text (Text)
import Data.Text qualified as Text

{-------------------------------------------------------------------------------
  Source paths
-------------------------------------------------------------------------------}

-- | Path of a source file as reported by @clang_getFileName@
--
-- For on-disk files this is typically the path used in the @#include@
-- directive. For virtual files (unsaved buffers, @#line@ directives)
-- it is the clang-assigned name. Platform-dependent format.
newtype SourcePath = SourcePath Text
  deriving newtype (Eq, IsString, Ord, Show)

-- | Get the 'FilePath' representation of a 'SourcePath'
getSourcePath :: SourcePath -> FilePath
getSourcePath = Text.unpack . getSourcePathText

-- | Get the 'Text' representation of a 'SourcePath'
getSourcePathText :: SourcePath -> Text
getSourcePathText (SourcePath path) = path

{-------------------------------------------------------------------------------
  Real paths
-------------------------------------------------------------------------------}

-- | Canonical absolute path of an on-disk file
--
-- Obtained via @clang_File_tryGetRealPathName@. Two 'RealPath' values
-- for the same physical file compare equal regardless of include spelling.
-- Platform-dependent format.
--
-- Virtual files (unsaved buffers, the @\<built-in\>@ buffer) have no real path,
-- so functions that must return a 'RealPath' for one throw
-- 'Clang.HighLevel.ClangRealPathException'. That includes the location
-- functions in "Clang.HighLevel". For virtual files, use
-- 'Clang.HighLevel.clang_tryGetRealPath' or a 'SourcePath' conversion such as
-- 'Clang.HighLevel.Types.toMultiSourcePath'.
newtype RealPath = RealPath Text
  deriving stock (Eq, Ord, Show)

-- | Get the 'FilePath' representation of a 'RealPath'
getRealPath :: RealPath -> FilePath
getRealPath = Text.unpack . getRealPathText

-- | Get the 'Text' representation of a 'RealPath'
getRealPathText :: RealPath -> Text
getRealPathText (RealPath path) = path

-- | Embed a 'RealPath' as a 'SourcePath'
realPathToSourcePath :: RealPath -> SourcePath
realPathToSourcePath (RealPath t) = SourcePath t

{-------------------------------------------------------------------------------
  C include directories
-------------------------------------------------------------------------------}

-- | C include directory
--
-- A /C include directory/ is a directory that contains C header files, and a
-- /C include search path/ is a list of C include directories that is used to
-- resolve headers.
--
-- The wrapped 'FilePath' may be absolute or relative to the current working
-- directory.  When an include directive is resolved using a relative
-- 'CIncludeDir', the resulting 'SourcePath' is also relative.
--
-- Examples:
--
-- * When using a C include search path that contains 'CIncludeDir'
--   @/usr/include@, @#include <stdint.h>@ may resolve to 'SourcePath'
--   @/usr/include/stdint.h@.
--
-- * When using a C include search path that contains 'CIncludeDir' @include@ (a
--   directory in the current working directory), @#include <foo.h>@ may resolve
--   to 'SourcePath' @include/foo.h@ (also relative to the current working
--   directory).
newtype CIncludeDir = CIncludeDir { getCIncludeDir :: FilePath }
  -- 'Show' instance valid due to 'IsString' instance
  deriving newtype (Eq, IsString, Ord, Show)