content: {-# LANGUAGE ConstraintKinds #-}
  {-# LANGUAGE FlexibleContexts #-}
  
  -- | Functions for manipulating 'Clang.Token's.
  --
  -- This module is intended to be imported qualified.
  module Clang.Token
  (
  -- * Token lists
    tokenize
  , List
  
  -- * Token kinds
  , getKind
  
  -- * Mapping between tokens and source code
  , getSpelling
  , getLocation
  , getExtent
  , annotateTokens
  ) where
  
  import Control.Monad.IO.Class
  import qualified Data.Vector.Storable as DVS
  
  import qualified Clang.Internal.FFI as FFI
  import Clang.Internal.Monad
  
  -- | Tokenizes the source code described by the given range into raw
  -- lexical tokens.
  tokenize :: ClangBase m
           => FFI.TranslationUnit s'  -- ^ The translation list
                                      -- containing the source code.
           -> FFI.SourceRange s''     -- ^ The source range in which text
                                      -- should be tokenized.
           -> ClangT s m (List s)
  tokenize = FFI.tokenize
  
  -- | A list of tokens, stored as a 'DVS.Vector' for efficiency.
  type List s = DVS.Vector (FFI.Token s)
  
  -- | Determines the kind of the given token, expressed as a
  -- 'FFI.TokenKind' value.
  getKind :: ClangBase m => FFI.Token s' -> ClangT s m FFI.TokenKind
  getKind t = liftIO $ FFI.getTokenKind t
  
  -- | Retrieves the \'spelling\', or textual representation, of the
  -- given token.
  getSpelling :: ClangBase m => FFI.TranslationUnit s' -> FFI.Token s'' -> ClangT s m (FFI.ClangString s)
  getSpelling = FFI.getTokenSpelling
  
  -- | Returns the source location of the given token.
  getLocation :: ClangBase m => FFI.TranslationUnit s' -> FFI.Token s''
              -> ClangT s m (FFI.SourceLocation s)
  getLocation tu tk = liftIO $ FFI.getTokenLocation mkProxy tu tk
  
  -- | Retrieves the source range that covers the given token.
  getExtent :: ClangBase m => FFI.TranslationUnit s' -> FFI.Token s''
            -> ClangT s m (FFI.SourceRange s)
  getExtent tu tk = liftIO $ FFI.getTokenExtent mkProxy tu tk
  
  -- | Annotates the given set of tokens by providing cursors for each token
  -- that can be mapped to a specific entity within the abstract syntax tree.
  -- 
  -- This is equivalent to invoking 'Clang.Cursor.getCursor' on the
  -- source locations of each of these tokens. The cursors provided are
  -- filtered, so that only those cursors that have a direct
  -- correspondence to the token are accepted. For example, given a
  -- function call \'f(x)\', 'Clang.Cursor.getCursor' would provide the
  -- following cursors:
  -- 
  --   * When the cursor is over the \'f\', a 'Clang.DeclRefExpr' cursor
  --     referring to \'f\'.
  --
  --   * When the cursor is over the \'(\' or the \')\', a
  --     'Clang.CallExpr' referring to \'f\'.
  --
  --   * When the cursor is over the \'x\', a 'Clang.DeclRefExpr' cursor
  --     referring to \'x\'.
  -- 
  -- Only the first and last of these cursors will occur within the
  -- annotate, since the tokens \'f\' and \'x\' directly refer to a function
  -- and a variable, respectively, but the parentheses are just a small
  -- part of the full syntax of the function call expression, which is
  -- not provided as an annotation.
  annotateTokens :: ClangBase m
                 => FFI.TranslationUnit s' -- ^ The translation unit that owns the tokens.
                 -> List s''               -- ^ The tokens to annotate.
                 -> ClangT s m (FFI.CursorList s)
  annotateTokens = FFI.annotateTokens
  