{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}

module Demangler.Substitution
  (
    -- * Parse a substitution reference
    substitution
    -- * Substitute the found substitution into the result
  , substituteUnscopedName
  , substitutePrefix
  , substitutePrefixR
  , substituteTemplateParam
  , substituteTemplatePrefix
  , substituteType
  , stdSubstToType
  , substituteUnresolvedType
  -- * When a subtitution candidate has been parsed, it is recorded here
  , canSubstUnscopedTemplateName
  , canSubstPrefix
  , canSubstTemplateArg
  , canSubstTemplateParam
  , canSubstTemplatePrefix
  , canSubstType
  , canSubstTypes
  , canSubstUnresolvedType
  , dropLastSubst
  )
where

import           Control.Applicative
import           Control.Lens ( (&), (^.), (%~) )
import           Control.Monad
import           Data.List.NonEmpty ( NonEmpty((:|)) )
import qualified Data.List.NonEmpty as NEL
import           Data.Maybe
import           Data.Sequence ( (|>), ViewR((:>)) )
import qualified Data.Sequence as Seq

import           Demangler.Engine
import           Demangler.Structure
import           Demangler.PPrint ()

#ifdef MIN_VERSION_panic
-- The debug flag is enabled in the cabal file
import           Demangler.Context
import           Text.Sayable
import           Debug.Trace
#endif

import           Prelude hiding ( last )


--------------------
-- * Handling Substitutions
--
-- Substition could be handled at parsing time or at pretty-printing time.  This
-- implementation handles substitution at parsing time for the following reasons:
--
--  1. Parser "type" information to confirm that the substitution value is
--     appropriate to be substituted in the current parsing element.
--
--  2. The resulting Demangled structure is fully expressed and does not need to
--     hold additional "sequencing" information that would allow Substitution
--     target identification.  Also simplifies use of the Demangled structure.
--
--  3. The sequencing information can also be more difficult to re-determine at
--     pretty-printing time (viz. the efforts in the itanium-abi package which
--     performs substitution at pretty-printing time).
--
-- Substitution is very tricky: the BNF (at the URL in the Dismantle module, and
-- which isn't fully correct) specifies that wherever "<substitution>" appears, a
-- substitution may be made OR a substitution capture can occur.  It also states
-- that substitutions are not duplicated.  It implies (but is not clear) that
-- there are actually two substitution namespaces: regular substitutions and
-- template subsitutions, where the former are accessed as "S[n]_" and the latter
-- are accessed as "T[m]_", where the n and m ordering are within the associated
-- namespace.  Here are the additional rules and exceptions not discussed:
--
--   * Constructor/Destructor names are not captured or substituted (but operator
--     names are)
--
--   * Known substitutions ("St" for "std::", "Sa" for "std::allocator", etc.)
--     are *not* added as a possible substitution if they appear alone, but if
--     they are part of a prefix (i.e. they are followed by other information)
--     then they are added as part of that longer sequence (e.g. "foo::list<i>"
--     will add "foo", "foo::list", and "foo::list<i>" for a total of 3 possible
--     substitution candidates whereas "std::list<i>" will add "std::list" and
--     "std::list<i>" for only 2 possible substitution candidates.
--
--   * Template argument substutions are in a different namespace and recursive
--     template arguments are not substitition candidates (e.g. foo<bar<int>>)
--     results in only one template substitution candidate (bar<int>).


-- | Parse a substitution specification and get the raw Substitution' result;
-- these should always be translated and never actually returned in the Demangled
-- result.

substitution :: AnyNext Substitution'
substitution :: AnyNext Substitution'
substitution =
  [NextArg a -> Maybe (NextArg Substitution')]
-> NextArg a -> Maybe (NextArg Substitution')
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Functor t, Alternative f) =>
t (a -> f b) -> a -> f b
asum' [ Text -> Next a a
forall a. Text -> Next a a
match Text
"S" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Next a Int
AnyNext Int
base36_num Next a Int
-> (NextArg Int -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (Int -> Substitution')
-> NextArg Int -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Natural -> Substitution'
Subs (Natural -> Substitution')
-> (Int -> Natural) -> Int -> Substitution'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Natural
forall a. Enum a => Int -> a
toEnum) (NextArg Int -> Maybe (NextArg Substitution'))
-> (NextArg Substitution' -> Maybe (NextArg Substitution'))
-> NextArg Int
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Text -> NextArg Substitution' -> Maybe (NextArg Substitution')
forall a. Text -> Next a a
match Text
"_"
        , Text -> Next a a
forall a. Text -> Next a a
match Text
"S_" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Substitution') -> NextArg a -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Substitution' -> a -> Substitution'
forall a b. a -> b -> a
const Substitution'
SubsFirst)
        , Text -> Next a a
forall a. Text -> Next a a
match Text
"St" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Substitution') -> NextArg a -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Substitution' -> a -> Substitution'
forall a b. a -> b -> a
const (Substitution' -> a -> Substitution')
-> Substitution' -> a -> Substitution'
forall a b. (a -> b) -> a -> b
$ Substitution -> Substitution'
SubsConst Substitution
SubStd)
        , Text -> Next a a
forall a. Text -> Next a a
match Text
"Sa" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Substitution') -> NextArg a -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Substitution' -> a -> Substitution'
forall a b. a -> b -> a
const (Substitution' -> a -> Substitution')
-> Substitution' -> a -> Substitution'
forall a b. (a -> b) -> a -> b
$ Substitution -> Substitution'
SubsConst Substitution
SubAlloc)
        , Text -> Next a a
forall a. Text -> Next a a
match Text
"Sb" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Substitution') -> NextArg a -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Substitution' -> a -> Substitution'
forall a b. a -> b -> a
const (Substitution' -> a -> Substitution')
-> Substitution' -> a -> Substitution'
forall a b. (a -> b) -> a -> b
$ Substitution -> Substitution'
SubsConst Substitution
SubBasicString)
        , Text -> Next a a
forall a. Text -> Next a a
match Text
"Ss" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Substitution') -> NextArg a -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Substitution' -> a -> Substitution'
forall a b. a -> b -> a
const (Substitution' -> a -> Substitution')
-> Substitution' -> a -> Substitution'
forall a b. (a -> b) -> a -> b
$ Substitution -> Substitution'
SubsConst (Substitution -> Substitution') -> Substitution -> Substitution'
forall a b. (a -> b) -> a -> b
$ StdType -> Substitution
SubStdType StdType
BasicStringChar)
        , Text -> Next a a
forall a. Text -> Next a a
match Text
"Si" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Substitution') -> NextArg a -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Substitution' -> a -> Substitution'
forall a b. a -> b -> a
const (Substitution' -> a -> Substitution')
-> Substitution' -> a -> Substitution'
forall a b. (a -> b) -> a -> b
$ Substitution -> Substitution'
SubsConst (Substitution -> Substitution') -> Substitution -> Substitution'
forall a b. (a -> b) -> a -> b
$ StdType -> Substitution
SubStdType StdType
BasicIStream)
        , Text -> Next a a
forall a. Text -> Next a a
match Text
"So" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Substitution') -> NextArg a -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Substitution' -> a -> Substitution'
forall a b. a -> b -> a
const (Substitution' -> a -> Substitution')
-> Substitution' -> a -> Substitution'
forall a b. (a -> b) -> a -> b
$ Substitution -> Substitution'
SubsConst (Substitution -> Substitution') -> Substitution -> Substitution'
forall a b. (a -> b) -> a -> b
$ StdType -> Substitution
SubStdType StdType
BasicOStream)
        , Text -> Next a a
forall a. Text -> Next a a
match Text
"Sd" Next a a
-> (NextArg a -> Maybe (NextArg Substitution'))
-> NextArg a
-> Maybe (NextArg Substitution')
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (a -> Substitution') -> NextArg a -> Maybe (NextArg Substitution')
forall (f :: * -> *) a b.
Applicative f =>
(a -> b) -> NextArg a -> f (NextArg b)
rmap (Substitution' -> a -> Substitution'
forall a b. a -> b -> a
const (Substitution' -> a -> Substitution')
-> Substitution' -> a -> Substitution'
forall a b. (a -> b) -> a -> b
$ Substitution -> Substitution'
SubsConst (Substitution -> Substitution') -> Substitution -> Substitution'
forall a b. (a -> b) -> a -> b
$ StdType -> Substitution
SubStdType StdType
BasicIOStream)
        ]

-- Internal to lookup a parsed Substitution'
getSubst :: NextArg Substitution' -> Either Substitution (Maybe SubsCandidate)
getSubst :: NextArg Substitution' -> Either Substitution (Maybe SubsCandidate)
getSubst NextArg Substitution'
i =
  case NextArg Substitution'
i NextArg Substitution'
-> Getting Substitution' (NextArg Substitution') Substitution'
-> Substitution'
forall s a. s -> Getting a s a -> a
^. Getting Substitution' (NextArg Substitution') Substitution'
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal of
    Substitution'
SubsFirst -> Maybe SubsCandidate -> Either Substitution (Maybe SubsCandidate)
forall a b. b -> Either a b
Right (Maybe SubsCandidate -> Either Substitution (Maybe SubsCandidate))
-> Maybe SubsCandidate -> Either Substitution (Maybe SubsCandidate)
forall a b. (a -> b) -> a -> b
$ Int -> Seq SubsCandidate -> Maybe SubsCandidate
forall a. Int -> Seq a -> Maybe a
Seq.lookup Int
0 (Seq SubsCandidate -> Maybe SubsCandidate)
-> Seq SubsCandidate -> Maybe SubsCandidate
forall a b. (a -> b) -> a -> b
$ NextArg Substitution'
i NextArg Substitution'
-> Getting
     (Seq SubsCandidate) (NextArg Substitution') (Seq SubsCandidate)
-> Seq SubsCandidate
forall s a. s -> Getting a s a -> a
^. Getting
  (Seq SubsCandidate) (NextArg Substitution') (Seq SubsCandidate)
forall a (f :: * -> *).
Functor f =>
(Seq SubsCandidate -> f (Seq SubsCandidate))
-> NextArg a -> f (NextArg a)
nSubs
    Subs Natural
n -> Maybe SubsCandidate -> Either Substitution (Maybe SubsCandidate)
forall a b. b -> Either a b
Right (Maybe SubsCandidate -> Either Substitution (Maybe SubsCandidate))
-> Maybe SubsCandidate -> Either Substitution (Maybe SubsCandidate)
forall a b. (a -> b) -> a -> b
$ Int -> Seq SubsCandidate -> Maybe SubsCandidate
forall a. Int -> Seq a -> Maybe a
Seq.lookup (Natural -> Int
forall a. Enum a => a -> Int
fromEnum Natural
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Seq SubsCandidate -> Maybe SubsCandidate)
-> Seq SubsCandidate -> Maybe SubsCandidate
forall a b. (a -> b) -> a -> b
$ NextArg Substitution'
i NextArg Substitution'
-> Getting
     (Seq SubsCandidate) (NextArg Substitution') (Seq SubsCandidate)
-> Seq SubsCandidate
forall s a. s -> Getting a s a -> a
^. Getting
  (Seq SubsCandidate) (NextArg Substitution') (Seq SubsCandidate)
forall a (f :: * -> *).
Functor f =>
(Seq SubsCandidate -> f (Seq SubsCandidate))
-> NextArg a -> f (NextArg a)
nSubs
    SubsConst Substitution
s -> Substitution -> Either Substitution (Maybe SubsCandidate)
forall a b. a -> Either a b
Left Substitution
s


#ifdef MIN_VERSION_panic
dumpSubs :: (Monad f, Applicative f)
         => NextArg a -> String -> f (NextArg a)
dumpSubs spec what = do
    mapM_ (traceM . show) $ Seq.zip
             (Seq.fromList [0.. Seq.length (spec ^. nSubs)])
             ((\ue -> (ue, sez @"debug" (addContext ue (spec ^. nContext))))
              <$> spec ^. nSubs)
    mapM_ (traceM . show) $ Seq.zip
             (Seq.fromList [0.. Seq.length (spec ^. nTmplSubs)])
             ((\ue -> ('T', ue, sez @"debug" (addContext ue (spec ^. nContext))))
              <$> spec ^. nTmplSubs)
    traceM $ "Subs Total: " <> show ((Seq.length $ spec ^. nSubs) + (Seq.length $ spec ^. nTmplSubs)) <> " "
        <> show ((Seq.length $ spec ^. nSubs), (Seq.length $ spec ^. nTmplSubs))
        <> " --> " <> sez @"debug" what
    pure spec
#endif

invalidSubst :: Show a => String -> NextArg a -> Maybe SubsCandidate -> Maybe b
invalidSubst :: forall a b.
Show a =>
String -> NextArg a -> Maybe SubsCandidate -> Maybe b
invalidSubst String
for NextArg a
spec = \case
  Just SubsCandidate
s -> do
#ifdef MIN_VERSION_panic
    -- Debug details
    _ <- dumpSubs spec "Just"
#endif
    Demangler -> String -> [String] -> Maybe b
forall a b. a -> String -> [String] -> Maybe b
cannot Demangler
Demangler String
for
         [ String
"Invalid " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
for String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" substitution (" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show (NextArg a
spec NextArg a -> Getting a (NextArg a) a -> a
forall s a. s -> Getting a s a -> a
^. Getting a (NextArg a) a
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"):"
         , SubsCandidate -> String
forall a. Show a => a -> String
show SubsCandidate
s
         ]
  Maybe SubsCandidate
Nothing -> do
#ifdef MIN_VERSION_panic
    -- Debug details
    _ <- dumpSubs spec "Nothing"
#endif
    Demangler -> String -> [String] -> Maybe b
forall a b. a -> String -> [String] -> Maybe b
cannot Demangler
Demangler String
for
         [ String
"Invalid " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
for String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" substitution reference:"
         , a -> String
forall a. Show a => a -> String
show (NextArg a
spec NextArg a -> Getting a (NextArg a) a -> a
forall s a. s -> Getting a s a -> a
^. Getting a (NextArg a) a
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal)
         ]

substituteUnscopedName :: Next Substitution UnscopedName
                          -> Next Substitution' UnscopedName
substituteUnscopedName :: Next Substitution UnscopedName -> Next Substitution' UnscopedName
substituteUnscopedName Next Substitution UnscopedName
direct NextArg Substitution'
i =
  case NextArg Substitution' -> Either Substitution (Maybe SubsCandidate)
getSubst NextArg Substitution'
i of
    Right (Just (SC_UQName Bool
s UnqualifiedName
n)) -> NextArg Substitution'
-> UnscopedName -> Maybe (NextArg UnscopedName)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i (UnscopedName -> Maybe (NextArg UnscopedName))
-> UnscopedName -> Maybe (NextArg UnscopedName)
forall a b. (a -> b) -> a -> b
$ Bool -> UnqualifiedName -> UnscopedName
UnScName Bool
s UnqualifiedName
n
    Right (Just (SC_Prefix Prefix
p)) ->
      let getUsn :: Prefix -> Maybe UnscopedName
getUsn = \case
            Prefix PrefixR
prefixr -> PrefixR -> Maybe UnscopedName
getUsn_PR PrefixR
prefixr
            Prefix
_ -> Maybe UnscopedName
forall a. Maybe a
Nothing
          getUsn_PR :: PrefixR -> Maybe UnscopedName
getUsn_PR = \case
            PrefixUQName UnqualifiedName
uqn PrefixR
PrefixEnd -> UnscopedName -> Maybe UnscopedName
forall a. a -> Maybe a
Just (UnscopedName -> Maybe UnscopedName)
-> UnscopedName -> Maybe UnscopedName
forall a b. (a -> b) -> a -> b
$ Bool -> UnqualifiedName -> UnscopedName
UnScName Bool
False UnqualifiedName
uqn
            PrefixUQName (StdSubst Substitution
SubStd) PrefixR
sp ->
              case PrefixR -> Maybe UnscopedName
getUsn_PR PrefixR
sp of
                Maybe UnscopedName
Nothing -> Maybe UnscopedName
forall a. Maybe a
Nothing
                Just (UnScName Bool
_ UnqualifiedName
uqn) -> UnscopedName -> Maybe UnscopedName
forall a. a -> Maybe a
Just (UnscopedName -> Maybe UnscopedName)
-> UnscopedName -> Maybe UnscopedName
forall a b. (a -> b) -> a -> b
$ Bool -> UnqualifiedName -> UnscopedName
UnScName Bool
True UnqualifiedName
uqn
                Just n :: UnscopedName
n@(UnScSubst Substitution
_) -> UnscopedName -> Maybe UnscopedName
forall a. a -> Maybe a
Just UnscopedName
n
            PrefixUQName (StdSubst Substitution
_) PrefixR
_ -> Maybe UnscopedName
forall a. Maybe a
Nothing
            PrefixUQName UnqualifiedName
_ PrefixR
_ -> Maybe UnscopedName
forall a. Maybe a
Nothing
            PrefixR
PrefixEnd -> Maybe UnscopedName
forall a. Maybe a
Nothing
            PrefixTemplateArgs TemplateArgs
_ PrefixR
_ -> Maybe UnscopedName
forall a. Maybe a
Nothing
      in case Prefix -> Maybe UnscopedName
getUsn Prefix
p of
           Maybe UnscopedName
Nothing -> Maybe (NextArg UnscopedName)
forall a. Maybe a
Nothing
           Just UnscopedName
usn -> NextArg Substitution'
-> UnscopedName -> Maybe (NextArg UnscopedName)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i UnscopedName
usn
    Right Maybe SubsCandidate
_ -> Maybe (NextArg UnscopedName)
forall a. Maybe a
Nothing
    Left Substitution
s -> Next Substitution UnscopedName
direct Next Substitution UnscopedName
-> Maybe (NextArg Substitution) -> Maybe (NextArg UnscopedName)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NextArg Substitution'
-> Substitution -> Maybe (NextArg Substitution)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i Substitution
s

substituteType :: (Next Substitution Type_) -> Next Substitution' Type_
substituteType :: Next Substitution Type_ -> Next Substitution' Type_
substituteType Next Substitution Type_
embed NextArg Substitution'
i =
  case NextArg Substitution' -> Either Substitution (Maybe SubsCandidate)
getSubst NextArg Substitution'
i of
    Right (Just (SC_Type Type_
t)) -> NextArg Substitution' -> Type_ -> Maybe (NextArg Type_)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i Type_
t
    Right (Just (SC_Prefix Prefix
p)) -> NextArg Substitution' -> Type_ -> Maybe (NextArg Type_)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i (Type_ -> Maybe (NextArg Type_))
-> Maybe Type_ -> Maybe (NextArg Type_)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Prefix -> Maybe Type_
prefixToType Prefix
p
    Right (Just (SC_UQName Bool
isStd UnqualifiedName
uqn)) ->
      NextArg Substitution' -> Type_ -> Maybe (NextArg Type_)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i (Type_ -> Maybe (NextArg Type_)) -> Type_ -> Maybe (NextArg Type_)
forall a b. (a -> b) -> a -> b
$ Name -> Type_
ClassUnionStructEnum (Name -> Type_) -> Name -> Type_
forall a b. (a -> b) -> a -> b
$ UnscopedName -> Name
UnscopedName (UnscopedName -> Name) -> UnscopedName -> Name
forall a b. (a -> b) -> a -> b
$ Bool -> UnqualifiedName -> UnscopedName
UnScName Bool
isStd UnqualifiedName
uqn
    Right Maybe SubsCandidate
o -> String
-> NextArg Substitution'
-> Maybe SubsCandidate
-> Maybe (NextArg Type_)
forall a b.
Show a =>
String -> NextArg a -> Maybe SubsCandidate -> Maybe b
invalidSubst String
"Type" NextArg Substitution'
i Maybe SubsCandidate
o
    Left Substitution
s -> Next Substitution Type_
embed Next Substitution Type_
-> Maybe (NextArg Substitution) -> Maybe (NextArg Type_)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NextArg Substitution'
-> Substitution -> Maybe (NextArg Substitution)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i Substitution
s


prefixToType :: Prefix -> Maybe Type_
prefixToType :: Prefix -> Maybe Type_
prefixToType Prefix
pfx =
  Name -> Type_
ClassUnionStructEnum
  (Name -> Type_) -> Maybe Name -> Maybe Type_
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case Prefix -> Maybe (Prefix, Either UnqualifiedName TemplateArgs)
prefixInitLast Prefix
pfx of
      Maybe (Prefix, Either UnqualifiedName TemplateArgs)
Nothing -> Demangler -> String -> [String] -> Maybe Name
forall a b. a -> String -> [String] -> Maybe b
cannot Demangler
Demangler String
"prefixToType"
                 [ String
"Cannot convert prefix to type: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Prefix -> String
forall a. Show a => a -> String
show Prefix
pfx ]
      Just (Prefix
iniPfx, Left UnqualifiedName
uqn) ->
        Name -> Maybe Name
forall a. a -> Maybe a
Just (Name -> Maybe Name) -> Name -> Maybe Name
forall a b. (a -> b) -> a -> b
$ NestedName -> Name
NameNested (NestedName -> Name) -> NestedName -> Name
forall a b. (a -> b) -> a -> b
$ Prefix
-> UnqualifiedName
-> [CVQualifier]
-> Maybe RefQualifier
-> NestedName
NestedName Prefix
iniPfx UnqualifiedName
uqn [] Maybe RefQualifier
forall a. Maybe a
Nothing
      Just (Prefix
iniPfx, Right TemplateArgs
ta) ->
        let tmpltpfx :: Maybe TemplatePrefix
tmpltpfx =
              case Prefix -> Maybe (Prefix, Either UnqualifiedName TemplateArgs)
prefixInitLast Prefix
iniPfx of
                Just (Prefix
EmptyPrefix, Left UnqualifiedName
luqn) ->
                  TemplatePrefix -> Maybe TemplatePrefix
forall a. a -> Maybe a
Just (TemplatePrefix -> Maybe TemplatePrefix)
-> TemplatePrefix -> Maybe TemplatePrefix
forall a b. (a -> b) -> a -> b
$ NonEmpty UnqualifiedName -> TemplatePrefix
GlobalTemplate (UnqualifiedName
luqn UnqualifiedName -> [UnqualifiedName] -> NonEmpty UnqualifiedName
forall a. a -> [a] -> NonEmpty a
:| [])
                Just (Prefix
p, Left UnqualifiedName
luqn) ->
                  TemplatePrefix -> Maybe TemplatePrefix
forall a. a -> Maybe a
Just (TemplatePrefix -> Maybe TemplatePrefix)
-> TemplatePrefix -> Maybe TemplatePrefix
forall a b. (a -> b) -> a -> b
$ Prefix -> NonEmpty UnqualifiedName -> TemplatePrefix
NestedTemplate Prefix
p (UnqualifiedName
luqn UnqualifiedName -> [UnqualifiedName] -> NonEmpty UnqualifiedName
forall a. a -> [a] -> NonEmpty a
:| [])
                Maybe (Prefix, Either UnqualifiedName TemplateArgs)
_ -> Demangler -> String -> [String] -> Maybe TemplatePrefix
forall a b. a -> String -> [String] -> Maybe b
cannot Demangler
Demangler String
"prefixToType"
                     [ String
"Cannot convert ta prefix to type: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Prefix -> String
forall a. Show a => a -> String
show Prefix
pfx ]
            mkntn :: TemplatePrefix -> NestedName
mkntn TemplatePrefix
tpfx = TemplatePrefix
-> TemplateArgs
-> [CVQualifier]
-> Maybe RefQualifier
-> NestedName
NestedTemplateName TemplatePrefix
tpfx TemplateArgs
ta [] Maybe RefQualifier
forall a. Maybe a
Nothing
        in NestedName -> Name
NameNested (NestedName -> Name)
-> (TemplatePrefix -> NestedName) -> TemplatePrefix -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TemplatePrefix -> NestedName
mkntn (TemplatePrefix -> Name) -> Maybe TemplatePrefix -> Maybe Name
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe TemplatePrefix
tmpltpfx

substituteUnresolvedType :: Next Substitution UnresolvedType
                         -> Next Substitution' UnresolvedType
substituteUnresolvedType :: Next Substitution UnresolvedType
-> Next Substitution' UnresolvedType
substituteUnresolvedType Next Substitution UnresolvedType
direct NextArg Substitution'
i =
  case NextArg Substitution' -> Either Substitution (Maybe SubsCandidate)
getSubst NextArg Substitution'
i of
    Right (Just (SC_Prefix Prefix
p)) -> NextArg Substitution'
-> UnresolvedType -> Maybe (NextArg UnresolvedType)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i (UnresolvedType -> Maybe (NextArg UnresolvedType))
-> UnresolvedType -> Maybe (NextArg UnresolvedType)
forall a b. (a -> b) -> a -> b
$ Prefix -> UnresolvedType
URTSubstPrefix Prefix
p
    Right (Just (SC_UnresolvedType UnresolvedType
urt)) -> NextArg Substitution'
-> UnresolvedType -> Maybe (NextArg UnresolvedType)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i UnresolvedType
urt
    Right Maybe SubsCandidate
x -> Demangler -> String -> [String] -> Maybe (NextArg UnresolvedType)
forall a b. a -> String -> [String] -> Maybe b
cannot Demangler
Demangler String
"substituteUnresolvedType"
               [ String
"Cannot convert to an unresolved type: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Maybe SubsCandidate -> String
forall a. Show a => a -> String
show Maybe SubsCandidate
x ]
    Left Substitution
s -> Next Substitution UnresolvedType
direct Next Substitution UnresolvedType
-> Maybe (NextArg Substitution) -> Maybe (NextArg UnresolvedType)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NextArg Substitution'
-> Substitution -> Maybe (NextArg Substitution)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i Substitution
s

substitutePrefix :: Next Substitution Prefix -> Next Substitution' Prefix
substitutePrefix :: Next Substitution Prefix -> Next Substitution' Prefix
substitutePrefix Next Substitution Prefix
direct NextArg Substitution'
i =
  case NextArg Substitution' -> Either Substitution (Maybe SubsCandidate)
getSubst NextArg Substitution'
i of
    Right (Just (SC_Prefix Prefix
p)) -> NextArg Substitution' -> Prefix -> Maybe (NextArg Prefix)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i Prefix
p
    Right Maybe SubsCandidate
o -> String
-> NextArg Substitution'
-> Maybe SubsCandidate
-> Maybe (NextArg Prefix)
forall a b.
Show a =>
String -> NextArg a -> Maybe SubsCandidate -> Maybe b
invalidSubst String
"Prefix" NextArg Substitution'
i Maybe SubsCandidate
o
    Left Substitution
s -> Next Substitution Prefix
direct Next Substitution Prefix
-> Maybe (NextArg Substitution) -> Maybe (NextArg Prefix)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< NextArg Substitution'
-> Substitution -> Maybe (NextArg Substitution)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i Substitution
s

substitutePrefixR :: Next Substitution PrefixR -> Next Substitution' PrefixR
substitutePrefixR :: Next Substitution PrefixR -> Next Substitution' PrefixR
substitutePrefixR Next Substitution PrefixR
direct NextArg Substitution'
i =
  case NextArg Substitution' -> Either Substitution (Maybe SubsCandidate)
getSubst NextArg Substitution'
i of
    Right o :: Maybe SubsCandidate
o@(Just (SC_Type (ClassUnionStructEnum Name
nm))) ->
      case Name -> Maybe PrefixR
name2prefix Name
nm of
        Just PrefixR
pfx -> NextArg Substitution' -> PrefixR -> Maybe (NextArg PrefixR)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i PrefixR
pfx
        Maybe PrefixR
Nothing -> String
-> NextArg Substitution'
-> Maybe SubsCandidate
-> Maybe (NextArg PrefixR)
forall a b.
Show a =>
String -> NextArg a -> Maybe SubsCandidate -> Maybe b
invalidSubst String
"PrefixR.SC_Type.ClassUnionStructEnum" NextArg Substitution'
i Maybe SubsCandidate
o
    Right (Just (SC_Prefix (Prefix PrefixR
sp))) -> NextArg Substitution' -> PrefixR -> Maybe (NextArg PrefixR)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i PrefixR
sp
    Right Maybe SubsCandidate
o -> String
-> NextArg Substitution'
-> Maybe SubsCandidate
-> Maybe (NextArg PrefixR)
forall a b.
Show a =>
String -> NextArg a -> Maybe SubsCandidate -> Maybe b
invalidSubst String
"PrefixR" NextArg Substitution'
i Maybe SubsCandidate
o
    Left Substitution
s -> NextArg Substitution'
-> Substitution -> Maybe (NextArg Substitution)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i Substitution
s Maybe (NextArg Substitution)
-> Next Substitution PrefixR -> Maybe (NextArg PrefixR)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Next Substitution PrefixR
direct
  where
    name2prefix :: Name -> Maybe PrefixR
name2prefix = \case
      NameNested NestedName
nn -> NestedName -> Maybe PrefixR
nn2prefix NestedName
nn
      UnscopedName (UnScName Bool
True UnqualifiedName
_uqn) -> Maybe PrefixR
forall a. Maybe a
Nothing
        -- Just $ PrefixUQName (SourceName (!!! "std") mempty) $ PrefixUQName uqn PrefixEnd
      UnscopedName (UnScName Bool
False UnqualifiedName
uqn) -> PrefixR -> Maybe PrefixR
forall a. a -> Maybe a
Just (PrefixR -> Maybe PrefixR) -> PrefixR -> Maybe PrefixR
forall a b. (a -> b) -> a -> b
$ UnqualifiedName -> PrefixR -> PrefixR
PrefixUQName UnqualifiedName
uqn PrefixR
PrefixEnd
      UnscopedName (UnScSubst Substitution
s) -> PrefixR -> Maybe PrefixR
forall a. a -> Maybe a
Just (PrefixR -> Maybe PrefixR) -> PrefixR -> Maybe PrefixR
forall a b. (a -> b) -> a -> b
$ UnqualifiedName -> PrefixR -> PrefixR
PrefixUQName (Substitution -> UnqualifiedName
StdSubst Substitution
s) PrefixR
PrefixEnd
      UnscopedTemplateName Name
nm TemplateArgs
_tmplArgs -> Name -> Maybe PrefixR
name2prefix Name
nm
      LocalName Encoding
_enc Name
nm Maybe Discriminator
_disc -> Name -> Maybe PrefixR
name2prefix Name
nm -- discriminators are invisible
      StringLitName Encoding
_ Maybe Discriminator
_ -> Maybe PrefixR
forall a. Maybe a
Nothing
    nn2prefix :: NestedName -> Maybe PrefixR
nn2prefix = \case
      NestedName pf :: Prefix
pf@(Prefix PrefixR
_) UnqualifiedName
uqn [CVQualifier]
_cvq Maybe RefQualifier
_mbref ->
        case Prefix -> PrefixR -> Prefix
extendPrefix Prefix
pf (PrefixR -> Prefix) -> PrefixR -> Prefix
forall a b. (a -> b) -> a -> b
$ UnqualifiedName -> PrefixR -> PrefixR
PrefixUQName UnqualifiedName
uqn PrefixR
PrefixEnd of
          Prefix PrefixR
pfr -> PrefixR -> Maybe PrefixR
forall a. a -> Maybe a
Just PrefixR
pfr
          Prefix
_ -> Maybe PrefixR
forall a. Maybe a
Nothing
      NestedName
_ -> Maybe PrefixR
forall a. Maybe a
Nothing


substituteTemplatePrefix :: (Next Substitution TemplatePrefix)
                         -> Next Substitution' TemplatePrefix
substituteTemplatePrefix :: Next Substitution TemplatePrefix
-> Next Substitution' TemplatePrefix
substituteTemplatePrefix Next Substitution TemplatePrefix
direct NextArg Substitution'
i =
  case NextArg Substitution' -> Either Substitution (Maybe SubsCandidate)
getSubst NextArg Substitution'
i of
    Right o :: Maybe SubsCandidate
o@(Just (SC_Prefix (Prefix PrefixR
p2))) ->
      let go :: PrefixR -> Maybe TemplatePrefix
go = \case
            PrefixR
PrefixEnd -> Maybe TemplatePrefix
forall a. Maybe a
Nothing
            PrefixUQName UnqualifiedName
uqn PrefixR
sp ->
              case PrefixR -> Maybe TemplatePrefix
go PrefixR
sp of
                Maybe TemplatePrefix
Nothing -> TemplatePrefix -> Maybe TemplatePrefix
forall a. a -> Maybe a
Just (TemplatePrefix -> Maybe TemplatePrefix)
-> TemplatePrefix -> Maybe TemplatePrefix
forall a b. (a -> b) -> a -> b
$ NonEmpty UnqualifiedName -> TemplatePrefix
GlobalTemplate (NonEmpty UnqualifiedName -> TemplatePrefix)
-> NonEmpty UnqualifiedName -> TemplatePrefix
forall a b. (a -> b) -> a -> b
$ UnqualifiedName
uqn UnqualifiedName -> [UnqualifiedName] -> NonEmpty UnqualifiedName
forall a. a -> [a] -> NonEmpty a
:| []
                Just (GlobalTemplate NonEmpty UnqualifiedName
uqns) ->
                  TemplatePrefix -> Maybe TemplatePrefix
forall a. a -> Maybe a
Just (TemplatePrefix -> Maybe TemplatePrefix)
-> TemplatePrefix -> Maybe TemplatePrefix
forall a b. (a -> b) -> a -> b
$ NonEmpty UnqualifiedName -> TemplatePrefix
GlobalTemplate (NonEmpty UnqualifiedName -> TemplatePrefix)
-> NonEmpty UnqualifiedName -> TemplatePrefix
forall a b. (a -> b) -> a -> b
$ UnqualifiedName
-> NonEmpty UnqualifiedName -> NonEmpty UnqualifiedName
forall a. a -> NonEmpty a -> NonEmpty a
NEL.cons UnqualifiedName
uqn NonEmpty UnqualifiedName
uqns
                Just (NestedTemplate (Prefix PrefixR
p) NonEmpty UnqualifiedName
uqns) ->
                  TemplatePrefix -> Maybe TemplatePrefix
forall a. a -> Maybe a
Just (TemplatePrefix -> Maybe TemplatePrefix)
-> TemplatePrefix -> Maybe TemplatePrefix
forall a b. (a -> b) -> a -> b
$ Prefix -> NonEmpty UnqualifiedName -> TemplatePrefix
NestedTemplate (PrefixR -> Prefix
Prefix (PrefixR -> Prefix) -> PrefixR -> Prefix
forall a b. (a -> b) -> a -> b
$ UnqualifiedName -> PrefixR -> PrefixR
PrefixUQName UnqualifiedName
uqn PrefixR
p) NonEmpty UnqualifiedName
uqns
                Maybe TemplatePrefix
_ -> Maybe TemplatePrefix
forall a. Maybe a
Nothing -- ??
            PrefixTemplateArgs TemplateArgs
ta PrefixR
sp ->
              case PrefixR -> Maybe TemplatePrefix
go PrefixR
sp of
                Maybe TemplatePrefix
Nothing -> Maybe TemplatePrefix
forall a. Maybe a
Nothing
                Just (GlobalTemplate NonEmpty UnqualifiedName
uqns) ->
                  TemplatePrefix -> Maybe TemplatePrefix
forall a. a -> Maybe a
Just (TemplatePrefix -> Maybe TemplatePrefix)
-> TemplatePrefix -> Maybe TemplatePrefix
forall a b. (a -> b) -> a -> b
$ Prefix -> NonEmpty UnqualifiedName -> TemplatePrefix
NestedTemplate (PrefixR -> Prefix
Prefix (PrefixR -> Prefix) -> PrefixR -> Prefix
forall a b. (a -> b) -> a -> b
$ TemplateArgs -> PrefixR -> PrefixR
PrefixTemplateArgs TemplateArgs
ta PrefixR
PrefixEnd) NonEmpty UnqualifiedName
uqns
                Just (NestedTemplate (Prefix PrefixR
p) NonEmpty UnqualifiedName
uqns) ->
                  TemplatePrefix -> Maybe TemplatePrefix
forall a. a -> Maybe a
Just (TemplatePrefix -> Maybe TemplatePrefix)
-> TemplatePrefix -> Maybe TemplatePrefix
forall a b. (a -> b) -> a -> b
$ Prefix -> NonEmpty UnqualifiedName -> TemplatePrefix
NestedTemplate (PrefixR -> Prefix
Prefix (PrefixR -> Prefix) -> PrefixR -> Prefix
forall a b. (a -> b) -> a -> b
$ TemplateArgs -> PrefixR -> PrefixR
PrefixTemplateArgs TemplateArgs
ta PrefixR
p) NonEmpty UnqualifiedName
uqns
                Maybe TemplatePrefix
_ -> Maybe TemplatePrefix
forall a. Maybe a
Nothing -- ??
      in case PrefixR -> Maybe TemplatePrefix
go PrefixR
p2 of
           Maybe TemplatePrefix
Nothing -> String
-> NextArg Substitution'
-> Maybe SubsCandidate
-> Maybe (NextArg TemplatePrefix)
forall a b.
Show a =>
String -> NextArg a -> Maybe SubsCandidate -> Maybe b
invalidSubst String
"Template Prefix (2)" NextArg Substitution'
i Maybe SubsCandidate
o
           Just TemplatePrefix
o' -> NextArg Substitution'
-> TemplatePrefix -> Maybe (NextArg TemplatePrefix)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i TemplatePrefix
o'
    Right (Just (SC_Prefix (PrefixTemplateParam TemplateArg
p PrefixR
PrefixEnd))) ->
      NextArg Substitution'
-> TemplatePrefix -> Maybe (NextArg TemplatePrefix)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i (TemplatePrefix -> Maybe (NextArg TemplatePrefix))
-> TemplatePrefix -> Maybe (NextArg TemplatePrefix)
forall a b. (a -> b) -> a -> b
$ TemplateArg -> TemplatePrefix
TemplateTemplateParam TemplateArg
p
    Right Maybe SubsCandidate
o -> String
-> NextArg Substitution'
-> Maybe SubsCandidate
-> Maybe (NextArg TemplatePrefix)
forall a b.
Show a =>
String -> NextArg a -> Maybe SubsCandidate -> Maybe b
invalidSubst String
"Template Prefix" NextArg Substitution'
i Maybe SubsCandidate
o
    Left Substitution
s -> NextArg Substitution'
-> Substitution -> Maybe (NextArg Substitution)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution'
i Substitution
s Maybe (NextArg Substitution)
-> Next Substitution TemplatePrefix
-> Maybe (NextArg TemplatePrefix)
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Next Substitution TemplatePrefix
direct


-- | Calls to replace a template substitution ("T[n]_") with the replacement
-- value from the original template argument specification.  Note that these
-- substitutions are independent of the normal substitutions (i.e. "S[n]_").

substituteTemplateParam :: Next (Maybe Int) TemplateParam
substituteTemplateParam :: Next (Maybe Int) TemplateArg
substituteTemplateParam NextArg (Maybe Int)
i =
  let idx :: Int
idx = Int -> (Int -> Int) -> Maybe Int -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 (Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ NextArg (Maybe Int)
i NextArg (Maybe Int)
-> Getting (Maybe Int) (NextArg (Maybe Int)) (Maybe Int)
-> Maybe Int
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Int) (NextArg (Maybe Int)) (Maybe Int)
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal
  in case Int -> Seq TemplateArg -> Maybe TemplateArg
forall a. Int -> Seq a -> Maybe a
Seq.lookup Int
idx (NextArg (Maybe Int)
i NextArg (Maybe Int)
-> Getting
     (Seq TemplateArg) (NextArg (Maybe Int)) (Seq TemplateArg)
-> Seq TemplateArg
forall s a. s -> Getting a s a -> a
^. Getting (Seq TemplateArg) (NextArg (Maybe Int)) (Seq TemplateArg)
forall a (f :: * -> *).
Functor f =>
(Seq TemplateArg -> f (Seq TemplateArg))
-> NextArg a -> f (NextArg a)
nTmplSubs) of
       Just TemplateArg
a -> NextArg (Maybe Int) -> TemplateArg -> Maybe (NextArg TemplateArg)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg (Maybe Int)
i TemplateArg
a
       Maybe TemplateArg
_ ->
#ifdef MIN_VERSION_panic
            -- Debug details
            dumpSubs i "Nothing Template Param" >>
#endif
            Demangler -> String -> [String] -> Maybe (NextArg TemplateArg)
forall a b. a -> String -> [String] -> Maybe b
cannot Demangler
Demangler String
"substituteTemplateParam"
              [ String
"Invalid Template Param substitution reference: "
              , Maybe Int -> String
forall a. Show a => a -> String
show (NextArg (Maybe Int)
i NextArg (Maybe Int)
-> Getting (Maybe Int) (NextArg (Maybe Int)) (Maybe Int)
-> Maybe Int
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Int) (NextArg (Maybe Int)) (Maybe Int)
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal)
              ]


-- | Called during parsing to add a SubsCandidate for future Substitution lookup.

canSubst :: SubsCandidate -> Next a a
canSubst :: forall a. SubsCandidate -> Next a a
canSubst SubsCandidate
what NextArg a
i = NextArg a -> Maybe (NextArg a)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NextArg a -> Maybe (NextArg a)) -> NextArg a -> Maybe (NextArg a)
forall a b. (a -> b) -> a -> b
$ NextArg a
i NextArg a -> (NextArg a -> NextArg a) -> NextArg a
forall a b. a -> (a -> b) -> b
& (Seq SubsCandidate -> Identity (Seq SubsCandidate))
-> NextArg a -> Identity (NextArg a)
forall a (f :: * -> *).
Functor f =>
(Seq SubsCandidate -> f (Seq SubsCandidate))
-> NextArg a -> f (NextArg a)
nSubs ((Seq SubsCandidate -> Identity (Seq SubsCandidate))
 -> NextArg a -> Identity (NextArg a))
-> (Seq SubsCandidate -> Seq SubsCandidate)
-> NextArg a
-> NextArg a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Seq SubsCandidate -> SubsCandidate -> Seq SubsCandidate
forall a. Seq a -> a -> Seq a
|> SubsCandidate
what)

dropLastSubst :: Next a a
dropLastSubst :: forall a. Next a a
dropLastSubst NextArg a
i = NextArg a -> Maybe (NextArg a)
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NextArg a -> Maybe (NextArg a)) -> NextArg a -> Maybe (NextArg a)
forall a b. (a -> b) -> a -> b
$ NextArg a
i NextArg a -> (NextArg a -> NextArg a) -> NextArg a
forall a b. a -> (a -> b) -> b
& (Seq SubsCandidate -> Identity (Seq SubsCandidate))
-> NextArg a -> Identity (NextArg a)
forall a (f :: * -> *).
Functor f =>
(Seq SubsCandidate -> f (Seq SubsCandidate))
-> NextArg a -> f (NextArg a)
nSubs ((Seq SubsCandidate -> Identity (Seq SubsCandidate))
 -> NextArg a -> Identity (NextArg a))
-> (Seq SubsCandidate -> Seq SubsCandidate)
-> NextArg a
-> NextArg a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Seq SubsCandidate -> Seq SubsCandidate
forall {a}. Seq a -> Seq a
dropLast
  where dropLast :: Seq a -> Seq a
dropLast Seq a
s = case Seq a -> ViewR a
forall a. Seq a -> ViewR a
Seq.viewr Seq a
s of
                       ViewR a
Seq.EmptyR -> Seq a
s
                       Seq a
s' :> a
_ -> Seq a
s'

-- | Called during parsing to add an unscoped template name for future
-- Substitution lookup.
canSubstUnscopedTemplateName :: Next Name Name
canSubstUnscopedTemplateName :: Next Name Name
canSubstUnscopedTemplateName NextArg Name
i =
  case NextArg Name
i NextArg Name -> Getting Name (NextArg Name) Name -> Name
forall s a. s -> Getting a s a -> a
^. Getting Name (NextArg Name) Name
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal of
    UnscopedName (UnScName Bool
isStd UnqualifiedName
uqn) -> SubsCandidate -> Next Name Name
forall a. SubsCandidate -> Next a a
canSubst (Bool -> UnqualifiedName -> SubsCandidate
SC_UQName Bool
isStd UnqualifiedName
uqn) NextArg Name
i
    Name
_ -> Next Name Name
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure NextArg Name
i


-- | Called during parsing to add a NamePrefix SubsCandidate for future
-- Substitution lookup.  This one is a bit different because the Prefix may
-- contain a NonEmpty list of Unqualified names: each init of that list is a
-- substitutable.
canSubstPrefix :: Next Prefix Prefix
canSubstPrefix :: Next Prefix Prefix
canSubstPrefix NextArg Prefix
i = SubsCandidate -> Next Prefix Prefix
forall a. SubsCandidate -> Next a a
canSubst (Prefix -> SubsCandidate
SC_Prefix (Prefix -> SubsCandidate) -> Prefix -> SubsCandidate
forall a b. (a -> b) -> a -> b
$ NextArg Prefix
i NextArg Prefix -> Getting Prefix (NextArg Prefix) Prefix -> Prefix
forall s a. s -> Getting a s a -> a
^. Getting Prefix (NextArg Prefix) Prefix
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal) NextArg Prefix
i

-- | Called during parsing to add an Type_ SubsCandidate for future Substitution
-- lookup.

canSubstType :: Next Type_ Type_
canSubstType :: Next Type_ Type_
canSubstType NextArg Type_
i = SubsCandidate -> Next Type_ Type_
forall a. SubsCandidate -> Next a a
canSubst (Type_ -> SubsCandidate
SC_Type (Type_ -> SubsCandidate) -> Type_ -> SubsCandidate
forall a b. (a -> b) -> a -> b
$ NextArg Type_
i NextArg Type_ -> Getting Type_ (NextArg Type_) Type_ -> Type_
forall s a. s -> Getting a s a -> a
^. Getting Type_ (NextArg Type_) Type_
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal) NextArg Type_
i

canSubstTypes :: Next (NEL.NonEmpty Type_) (NEL.NonEmpty Type_)
canSubstTypes :: Next (NonEmpty Type_) (NonEmpty Type_)
canSubstTypes NextArg (NonEmpty Type_)
i =
  let subT :: NextArg a -> Type_ -> Maybe (NextArg a)
subT NextArg a
i' Type_
ty = SubsCandidate -> Next a a
forall a. SubsCandidate -> Next a a
canSubst (Type_ -> SubsCandidate
SC_Type (Type_ -> SubsCandidate) -> Type_ -> SubsCandidate
forall a b. (a -> b) -> a -> b
$ Type_
ty) NextArg a
i'
  in (NextArg (NonEmpty Type_)
 -> Type_ -> Maybe (NextArg (NonEmpty Type_)))
-> NextArg (NonEmpty Type_)
-> NonEmpty Type_
-> Maybe (NextArg (NonEmpty Type_))
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM NextArg (NonEmpty Type_)
-> Type_ -> Maybe (NextArg (NonEmpty Type_))
forall {a}. NextArg a -> Type_ -> Maybe (NextArg a)
subT NextArg (NonEmpty Type_)
i (NextArg (NonEmpty Type_)
i NextArg (NonEmpty Type_)
-> Getting
     (NonEmpty Type_) (NextArg (NonEmpty Type_)) (NonEmpty Type_)
-> NonEmpty Type_
forall s a. s -> Getting a s a -> a
^. Getting
  (NonEmpty Type_) (NextArg (NonEmpty Type_)) (NonEmpty Type_)
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal)

canSubstUnresolvedType :: Next UnresolvedType UnresolvedType
canSubstUnresolvedType :: Next UnresolvedType UnresolvedType
canSubstUnresolvedType NextArg UnresolvedType
i = SubsCandidate -> Next UnresolvedType UnresolvedType
forall a. SubsCandidate -> Next a a
canSubst (UnresolvedType -> SubsCandidate
SC_UnresolvedType (UnresolvedType -> SubsCandidate)
-> UnresolvedType -> SubsCandidate
forall a b. (a -> b) -> a -> b
$ NextArg UnresolvedType
i NextArg UnresolvedType
-> Getting UnresolvedType (NextArg UnresolvedType) UnresolvedType
-> UnresolvedType
forall s a. s -> Getting a s a -> a
^. Getting UnresolvedType (NextArg UnresolvedType) UnresolvedType
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal) NextArg UnresolvedType
i

canSubstTemplatePrefix :: Next TemplatePrefix TemplatePrefix
canSubstTemplatePrefix :: Next TemplatePrefix TemplatePrefix
canSubstTemplatePrefix NextArg TemplatePrefix
i = SubsCandidate -> Next TemplatePrefix TemplatePrefix
forall a. SubsCandidate -> Next a a
canSubst (TemplatePrefix -> SubsCandidate
SC_TemplatePrefix (TemplatePrefix -> SubsCandidate)
-> TemplatePrefix -> SubsCandidate
forall a b. (a -> b) -> a -> b
$ NextArg TemplatePrefix
i NextArg TemplatePrefix
-> Getting TemplatePrefix (NextArg TemplatePrefix) TemplatePrefix
-> TemplatePrefix
forall s a. s -> Getting a s a -> a
^. Getting TemplatePrefix (NextArg TemplatePrefix) TemplatePrefix
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal) NextArg TemplatePrefix
i

canSubstTemplateParam :: Next TemplateParam TemplateParam
canSubstTemplateParam :: Next TemplateArg TemplateArg
canSubstTemplateParam = Next TemplateArg TemplateArg
canSubstTemplateArg

canSubstTemplateArg :: Next TemplateArg TemplateArg
canSubstTemplateArg :: Next TemplateArg TemplateArg
canSubstTemplateArg NextArg TemplateArg
i =
  if NextArg TemplateArg
i NextArg TemplateArg
-> Getting Bool (NextArg TemplateArg) Bool -> Bool
forall s a. s -> Getting a s a -> a
^. Getting Bool (NextArg TemplateArg) Bool
forall a (f :: * -> *).
Functor f =>
(Bool -> f Bool) -> NextArg a -> f (NextArg a)
nTmplSubsLock
  then Next TemplateArg TemplateArg
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure NextArg TemplateArg
i
  else Next TemplateArg TemplateArg
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Next TemplateArg TemplateArg -> Next TemplateArg TemplateArg
forall a b. (a -> b) -> a -> b
$ NextArg TemplateArg
i NextArg TemplateArg
-> (NextArg TemplateArg -> NextArg TemplateArg)
-> NextArg TemplateArg
forall a b. a -> (a -> b) -> b
& (Seq TemplateArg -> Identity (Seq TemplateArg))
-> NextArg TemplateArg -> Identity (NextArg TemplateArg)
forall a (f :: * -> *).
Functor f =>
(Seq TemplateArg -> f (Seq TemplateArg))
-> NextArg a -> f (NextArg a)
nTmplSubs ((Seq TemplateArg -> Identity (Seq TemplateArg))
 -> NextArg TemplateArg -> Identity (NextArg TemplateArg))
-> (Seq TemplateArg -> Seq TemplateArg)
-> NextArg TemplateArg
-> NextArg TemplateArg
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Seq TemplateArg -> TemplateArg -> Seq TemplateArg
forall a. Seq a -> a -> Seq a
|> (NextArg TemplateArg
i NextArg TemplateArg
-> Getting TemplateArg (NextArg TemplateArg) TemplateArg
-> TemplateArg
forall s a. s -> Getting a s a -> a
^. Getting TemplateArg (NextArg TemplateArg) TemplateArg
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal))

----------------------------------------------------------------------

stdSubstToType :: Next Substitution Type_
stdSubstToType :: Next Substitution Type_
stdSubstToType NextArg Substitution
i =
  case (NextArg Substitution
i NextArg Substitution
-> Getting Substitution (NextArg Substitution) Substitution
-> Substitution
forall s a. s -> Getting a s a -> a
^. Getting Substitution (NextArg Substitution) Substitution
forall a b (f :: * -> *).
Functor f =>
(a -> f b) -> NextArg a -> f (NextArg b)
nVal) of
    SubStdType StdType
stdTy -> NextArg Substitution -> Type_ -> Maybe (NextArg Type_)
forall (f :: * -> *) a b.
Applicative f =>
NextArg a -> b -> f (NextArg b)
ret NextArg Substitution
i (Type_ -> Maybe (NextArg Type_)) -> Type_ -> Maybe (NextArg Type_)
forall a b. (a -> b) -> a -> b
$ StdType -> Type_
StdType StdType
stdTy
    Substitution
s -> Demangler -> String -> [String] -> Maybe (NextArg Type_)
forall a b. a -> String -> [String] -> Maybe b
cannot Demangler
Demangler String
"stdSubstToType"
         [ String
"Substitution " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Substitution -> String
forall a. Show a => a -> String
show Substitution
s String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" is not a type" ]