module EVM.StorageLayout where

-- Figures out the layout of storage slots for Solidity contracts.

import EVM.Dapp (DappInfo, dappAstSrcMap, dappAstIdMap)
import EVM.Solidity (SolcContract, creationSrcmap, SlotType(..))
import EVM.ABI (AbiType (..), parseTypeName)

import Data.Aeson (Value (Number))
import Data.Aeson.Lens

import Control.Lens

import Data.Text (Text, unpack, pack, words)

import Data.Foldable (toList)
import Data.Maybe (fromMaybe, isJust)
import qualified Data.List.NonEmpty as NonEmpty

import qualified Data.Sequence as Seq

import Prelude hiding (words)

-- A contract has all the slots of its inherited contracts.
--
-- The slot order is determined by the inheritance linearization order,
-- so we first have to calculate that.
--
-- This information is available in the abstract syntax tree.

findContractDefinition :: DappInfo -> SolcContract -> Maybe Value
findContractDefinition :: DappInfo -> SolcContract -> Maybe Value
findContractDefinition dapp :: DappInfo
dapp solc :: SolcContract
solc =
  -- The first source mapping in the contract's creation code
  -- corresponds to the source field of the contract definition.
  case Seq SrcMap -> ViewL SrcMap
forall a. Seq a -> ViewL a
Seq.viewl (Getting (Seq SrcMap) SolcContract (Seq SrcMap)
-> SolcContract -> Seq SrcMap
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (Seq SrcMap) SolcContract (Seq SrcMap)
Lens' SolcContract (Seq SrcMap)
creationSrcmap SolcContract
solc) of
    firstSrcMap :: SrcMap
firstSrcMap Seq.:< _ ->
      (Getting (SrcMap -> Maybe Value) DappInfo (SrcMap -> Maybe Value)
-> DappInfo -> SrcMap -> Maybe Value
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting (SrcMap -> Maybe Value) DappInfo (SrcMap -> Maybe Value)
Lens' DappInfo (SrcMap -> Maybe Value)
dappAstSrcMap DappInfo
dapp) SrcMap
firstSrcMap
    _ ->
      Maybe Value
forall a. Maybe a
Nothing

storageLayout :: DappInfo -> SolcContract -> [Text]
storageLayout :: DappInfo -> SolcContract -> [Text]
storageLayout dapp :: DappInfo
dapp solc :: SolcContract
solc =
  let
    root :: Value
    root :: Value
root =
      Value -> Maybe Value -> Value
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> Value
forall a. HasCallStack => [Char] -> a
error "no contract definition AST")
        (DappInfo -> SolcContract -> Maybe Value
findContractDefinition DappInfo
dapp SolcContract
solc)
  in
    case Getting (First (Vector Value)) Value (Vector Value)
-> Value -> Maybe (Vector Value)
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview ( Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "attributes"
                 ((Value -> Const (First (Vector Value)) Value)
 -> Value -> Const (First (Vector Value)) Value)
-> Getting (First (Vector Value)) Value (Vector Value)
-> Getting (First (Vector Value)) Value (Vector Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "linearizedBaseContracts"
                 ((Value -> Const (First (Vector Value)) Value)
 -> Value -> Const (First (Vector Value)) Value)
-> Getting (First (Vector Value)) Value (Vector Value)
-> Getting (First (Vector Value)) Value (Vector Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First (Vector Value)) Value (Vector Value)
forall t. AsValue t => Prism' t (Vector Value)
_Array
                 ) Value
root of
      Nothing ->
        []
      Just (([Value] -> [Value]
forall a. [a] -> [a]
reverse ([Value] -> [Value])
-> (Vector Value -> [Value]) -> Vector Value -> [Value]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Value -> [Value]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList) -> [Value]
linearizedBaseContracts) ->
        ((Value -> [Text]) -> [Value] -> [Text])
-> [Value] -> (Value -> [Text]) -> [Text]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Value -> [Text]) -> [Value] -> [Text]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [Value]
linearizedBaseContracts
          (\case
             Number i :: Scientific
i -> [Text] -> Maybe [Text] -> [Text]
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> [Text]
forall a. HasCallStack => [Char] -> a
error "malformed AST JSON") (Maybe [Text] -> [Text]) -> Maybe [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$
               Value -> Maybe [Text]
storageVariablesForContract (Value -> Maybe [Text]) -> Maybe Value -> Maybe [Text]
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
                 Getting (First Value) DappInfo Value -> DappInfo -> Maybe Value
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview ((Map Int Value -> Const (First Value) (Map Int Value))
-> DappInfo -> Const (First Value) DappInfo
Lens' DappInfo (Map Int Value)
dappAstIdMap ((Map Int Value -> Const (First Value) (Map Int Value))
 -> DappInfo -> Const (First Value) DappInfo)
-> ((Value -> Const (First Value) Value)
    -> Map Int Value -> Const (First Value) (Map Int Value))
-> Getting (First Value) DappInfo Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index (Map Int Value)
-> Traversal' (Map Int Value) (IxValue (Map Int Value))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix (Scientific -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Scientific
i)) DappInfo
dapp
             _ ->
               [Char] -> [Text]
forall a. HasCallStack => [Char] -> a
error "malformed AST JSON")

storageVariablesForContract :: Value -> Maybe [Text]
storageVariablesForContract :: Value -> Maybe [Text]
storageVariablesForContract node :: Value
node = do
  Text
name <- Getting (First Text) Value Text -> Value -> Maybe Text
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Index Value -> Traversal' Value (IxValue Value)
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix "attributes" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "name" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Text) Value Text
forall t. AsPrimitive t => Prism' t Text
_String) Value
node
  [Value]
vars <-
    (Vector Value -> [Value]) -> Maybe (Vector Value) -> Maybe [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
      ((Value -> Bool) -> [Value] -> [Value]
forall a. (a -> Bool) -> [a] -> [a]
filter Value -> Bool
isStorageVariableDeclaration ([Value] -> [Value])
-> (Vector Value -> [Value]) -> Vector Value -> [Value]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Value -> [Value]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList)
      (Getting (First (Vector Value)) Value (Vector Value)
-> Value -> Maybe (Vector Value)
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Index Value -> Traversal' Value (IxValue Value)
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix "children" ((Value -> Const (First (Vector Value)) Value)
 -> Value -> Const (First (Vector Value)) Value)
-> Getting (First (Vector Value)) Value (Vector Value)
-> Getting (First (Vector Value)) Value (Vector Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First (Vector Value)) Value (Vector Value)
forall t. AsValue t => Prism' t (Vector Value)
_Array) Value
node)

  [Text] -> Maybe [Text]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Text] -> Maybe [Text])
-> ((Value -> Text) -> [Text]) -> (Value -> Text) -> Maybe [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Value -> Text) -> [Value] -> [Text])
-> [Value] -> (Value -> Text) -> [Text]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Value -> Text) -> [Value] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map [Value]
vars ((Value -> Text) -> Maybe [Text])
-> (Value -> Text) -> Maybe [Text]
forall a b. (a -> b) -> a -> b
$
    \x :: Value
x ->
      case Getting (First Text) Value Text -> Value -> Maybe Text
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "attributes" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "name" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Text) Value Text
forall t. AsPrimitive t => Prism' t Text
_String) Value
x of
        Just variableName :: Text
variableName ->
          [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
            [ Text
variableName
            , " (", Text
name, ")"
            , "\n", "  Type: "
            , [Char] -> Text
pack ([Char] -> Text) -> [Char] -> Text
forall a b. (a -> b) -> a -> b
$ SlotType -> [Char]
forall a. Show a => a -> [Char]
show (Value -> SlotType
slotTypeForDeclaration Value
x)
            ]
        Nothing ->
          [Char] -> Text
forall a. HasCallStack => [Char] -> a
error "malformed variable declaration"

nodeIs :: Text -> Value -> Bool
nodeIs :: Text -> Value -> Bool
nodeIs t :: Text
t x :: Value
x = Bool
isSourceNode Bool -> Bool -> Bool
&& Bool
hasRightName
  where
    isSourceNode :: Bool
isSourceNode =
      Maybe Value -> Bool
forall a. Maybe a -> Bool
isJust (Getting (First Value) Value Value -> Value -> Maybe Value
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "src") Value
x)
    hasRightName :: Bool
hasRightName =
      Text -> Maybe Text
forall a. a -> Maybe a
Just Text
t Maybe Text -> Maybe Text -> Bool
forall a. Eq a => a -> a -> Bool
== Getting (First Text) Value Text -> Value -> Maybe Text
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "name" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Text) Value Text
forall t. AsPrimitive t => Prism' t Text
_String) Value
x

isStorageVariableDeclaration :: Value -> Bool
isStorageVariableDeclaration :: Value -> Bool
isStorageVariableDeclaration x :: Value
x =
  Text -> Value -> Bool
nodeIs "VariableDeclaration" Value
x
    Bool -> Bool -> Bool
&& Getting (First Bool) Value Bool -> Value -> Maybe Bool
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "attributes" ((Value -> Const (First Bool) Value)
 -> Value -> Const (First Bool) Value)
-> Getting (First Bool) Value Bool
-> Getting (First Bool) Value Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "constant" ((Value -> Const (First Bool) Value)
 -> Value -> Const (First Bool) Value)
-> Getting (First Bool) Value Bool
-> Getting (First Bool) Value Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Bool) Value Bool
forall t. AsPrimitive t => Prism' t Bool
_Bool) Value
x Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
/= Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True

slotTypeForDeclaration :: Value -> SlotType
slotTypeForDeclaration :: Value -> SlotType
slotTypeForDeclaration node :: Value
node =
  case Vector Value -> [Value]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Vector Value -> [Value]) -> Maybe (Vector Value) -> Maybe [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting (First (Vector Value)) Value (Vector Value)
-> Value -> Maybe (Vector Value)
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "children" ((Value -> Const (First (Vector Value)) Value)
 -> Value -> Const (First (Vector Value)) Value)
-> Getting (First (Vector Value)) Value (Vector Value)
-> Getting (First (Vector Value)) Value (Vector Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First (Vector Value)) Value (Vector Value)
forall t. AsValue t => Prism' t (Vector Value)
_Array) Value
node of
    Just (x :: Value
x:_) ->
      Value -> SlotType
grokDeclarationType Value
x
    _ ->
      [Char] -> SlotType
forall a. HasCallStack => [Char] -> a
error "malformed AST"

grokDeclarationType :: Value -> SlotType
grokDeclarationType :: Value -> SlotType
grokDeclarationType x :: Value
x =
  case Getting (First Text) Value Text -> Value -> Maybe Text
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "name" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Text) Value Text
forall t. AsPrimitive t => Prism' t Text
_String) Value
x of
    Just "Mapping" ->
      case Getting (First (Vector Value)) Value (Vector Value)
-> Value -> Maybe (Vector Value)
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "children" ((Value -> Const (First (Vector Value)) Value)
 -> Value -> Const (First (Vector Value)) Value)
-> Getting (First (Vector Value)) Value (Vector Value)
-> Getting (First (Vector Value)) Value (Vector Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First (Vector Value)) Value (Vector Value)
forall t. AsValue t => Prism' t (Vector Value)
_Array) Value
x of
        Just (Vector Value -> [Value]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [Value]
xs) ->
          [Value] -> SlotType
grokMappingType [Value]
xs
        _ ->
          [Char] -> SlotType
forall a. HasCallStack => [Char] -> a
error "malformed AST"
    Just _ ->
      AbiType -> SlotType
StorageValue (Value -> AbiType
grokValueType Value
x)
    _ ->
      [Char] -> SlotType
forall a. HasCallStack => [Char] -> a
error ("malformed AST " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Value -> [Char]
forall a. Show a => a -> [Char]
show Value
x)

grokMappingType :: [Value] -> SlotType
grokMappingType :: [Value] -> SlotType
grokMappingType [s :: Value
s, t :: Value
t] =
  case (Value -> SlotType
grokDeclarationType Value
s, Value -> SlotType
grokDeclarationType Value
t) of
    (StorageValue s' :: AbiType
s', StorageMapping t' :: NonEmpty AbiType
t' x :: AbiType
x) ->
      NonEmpty AbiType -> AbiType -> SlotType
StorageMapping (AbiType -> NonEmpty AbiType -> NonEmpty AbiType
forall a. a -> NonEmpty a -> NonEmpty a
NonEmpty.cons AbiType
s' NonEmpty AbiType
t') AbiType
x
    (StorageValue s' :: AbiType
s', StorageValue t' :: AbiType
t') ->
      NonEmpty AbiType -> AbiType -> SlotType
StorageMapping (AbiType -> NonEmpty AbiType
forall (f :: * -> *) a. Applicative f => a -> f a
pure AbiType
s') AbiType
t'
    (StorageMapping _ _, _) ->
      [Char] -> SlotType
forall a. HasCallStack => [Char] -> a
error "unexpected mapping as mapping key"
grokMappingType _ =
  [Char] -> SlotType
forall a. HasCallStack => [Char] -> a
error "unexpected AST child count for mapping"

grokValueType :: Value -> AbiType
grokValueType :: Value -> AbiType
grokValueType x :: Value
x =
  case ( Getting (First Text) Value Text -> Value -> Maybe Text
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "name" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Text) Value Text
forall t. AsPrimitive t => Prism' t Text
_String) Value
x
       , Getting (First (Vector Value)) Value (Vector Value)
-> Value -> Maybe (Vector Value)
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "children" ((Value -> Const (First (Vector Value)) Value)
 -> Value -> Const (First (Vector Value)) Value)
-> Getting (First (Vector Value)) Value (Vector Value)
-> Getting (First (Vector Value)) Value (Vector Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First (Vector Value)) Value (Vector Value)
forall t. AsValue t => Prism' t (Vector Value)
_Array) Value
x
       , Getting (First Text) Value Text -> Value -> Maybe Text
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "attributes" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "type" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Text) Value Text
forall t. AsPrimitive t => Prism' t Text
_String) Value
x
       ) of
    (Just "ElementaryTypeName", _, Just typeName :: Text
typeName) ->
      AbiType -> Maybe AbiType -> AbiType
forall a. a -> Maybe a -> a
fromMaybe ([Char] -> AbiType
forall a. HasCallStack => [Char] -> a
error ("ungrokked value type: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
forall a. Show a => a -> [Char]
show Text
typeName))
        (Vector AbiType -> Text -> Maybe AbiType
parseTypeName Vector AbiType
forall a. Monoid a => a
mempty ([Text] -> Text
forall a. [a] -> a
head (Text -> [Text]
words Text
typeName)))
    (Just "UserDefinedTypeName", _, _) ->
      AbiType
AbiAddressType
    (Just "ArrayTypeName", (Vector Value -> [Value]) -> Maybe (Vector Value) -> Maybe [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector Value -> [Value]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> Just [t :: Value
t], _)->
      AbiType -> AbiType
AbiArrayDynamicType (Value -> AbiType
grokValueType Value
t)
    (Just "ArrayTypeName", (Vector Value -> [Value]) -> Maybe (Vector Value) -> Maybe [Value]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Vector Value -> [Value]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> Just [t :: Value
t, n :: Value
n], _)->
      case ( Getting (First Text) Value Text -> Value -> Maybe Text
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "name" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Text) Value Text
forall t. AsPrimitive t => Prism' t Text
_String) Value
n
           , Getting (First Text) Value Text -> Value -> Maybe Text
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview (Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "attributes" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Traversal' Value Value
forall t. AsValue t => Text -> Traversal' t Value
key "value" ((Value -> Const (First Text) Value)
 -> Value -> Const (First Text) Value)
-> Getting (First Text) Value Text
-> Getting (First Text) Value Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (First Text) Value Text
forall t. AsPrimitive t => Prism' t Text
_String) Value
n
           ) of
        (Just "Literal", Just (([Char] -> Int
forall a. Read a => [Char] -> a
read ([Char] -> Int) -> (Text -> [Char]) -> Text -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
unpack) -> Int
i)) ->
          Int -> AbiType -> AbiType
AbiArrayType Int
i (Value -> AbiType
grokValueType Value
t)
        _ ->
          [Char] -> AbiType
forall a. HasCallStack => [Char] -> a
error "malformed AST"
    _ ->
      [Char] -> AbiType
forall a. HasCallStack => [Char] -> a
error ("unknown value type " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Value -> [Char]
forall a. Show a => a -> [Char]
show Value
x)