11{-# LANGUAGE FlexibleContexts #-}
22{-# LANGUAGE FlexibleInstances #-}
3+ {-# LANGUAGE FunctionalDependencies #-}
34{-# LANGUAGE GADTs #-}
45{-# LANGUAGE GeneralizedNewtypeDeriving #-}
56{-# LANGUAGE LambdaCase #-}
@@ -58,7 +59,7 @@ import Data.Traversable (for)
5859import System.Locale
5960
6061import qualified Pact.Types.Hash as Pact
61- import Pact.Types.Lang (Parsed )
62+ import Pact.Types.Lang (Info )
6263import Pact.Types.Runtime (PrimType (TyBool , TyDecimal , TyInteger , TyKeySet , TyString , TyTime ),
6364 Type (TyPrim ), tShow )
6465import qualified Pact.Types.Runtime as Pact
@@ -73,11 +74,12 @@ import Pact.Analyze.Util
7374
7475data AnalyzeEnv
7576 = AnalyzeEnv
76- { _aeScope :: Map VarId AVal -- used as a stack
77- , _aeKeySets :: SFunArray KeySetName KeySet -- read-only
78- , _aeKsAuths :: SFunArray KeySet Bool -- read-only
79- , _invariants :: TableMap [(Parsed , Invariant Bool )]
80- , _aeModelTags :: ModelTags
77+ { _aeScope :: ! (Map VarId AVal ) -- used as a stack
78+ , _aeKeySets :: ! (SFunArray KeySetName KeySet ) -- read-only
79+ , _aeKsAuths :: ! (SFunArray KeySet Bool ) -- read-only
80+ , _invariants :: ! (TableMap [(Info , Invariant Bool )])
81+ , _aeModelTags :: ! ModelTags
82+ , _aeInfo :: ! Info
8183 }
8284 deriving Show
8385
@@ -122,7 +124,7 @@ data LatticeAnalyzeState
122124 -- finer-grained tracking, so that we can test whether a single
123125 -- invariant is being maintained
124126 --
125- , _lasMaintainsInvariants :: TableMap (ZipList (Parsed , SBV Bool ))
127+ , _lasMaintainsInvariants :: TableMap (ZipList (Info , SBV Bool ))
126128 , _lasTablesRead :: SFunArray TableName Bool
127129 , _lasTablesWritten :: SFunArray TableName Bool
128130 , _lasIntCellDeltas :: TableMap (ColumnMap (SFunArray RowKey Integer ))
@@ -221,7 +223,7 @@ data AnalyzeFailureNoLoc
221223 deriving (Eq , Show )
222224
223225data AnalyzeFailure = AnalyzeFailure
224- { _analyzeFailureParsed :: ! Parsed
226+ { _analyzeFailureParsed :: ! Info
225227 , _analyzeFailure :: ! AnalyzeFailureNoLoc
226228 }
227229
@@ -336,9 +338,6 @@ mkSymbolicCells tables = TableMap $ Map.fromList cellsList
336338mkSVal :: SBV a -> SBVI. SVal
337339mkSVal (SBVI. SBV v) = v
338340
339- throwErrorNoLoc :: MonadError AnalyzeFailure m => AnalyzeFailureNoLoc -> m a
340- throwErrorNoLoc = throwError . AnalyzeFailure dummyParsed
341-
342341describeAnalyzeFailureNoLoc :: AnalyzeFailureNoLoc -> Text
343342describeAnalyzeFailureNoLoc = \ case
344343 -- these are internal errors. not quite as much care is taken on the messaging
@@ -395,8 +394,8 @@ newtype Query a
395394 deriving (Functor , Applicative , Monad , MonadReader QueryEnv ,
396395 MonadError AnalyzeFailure )
397396
398- mkAnalyzeEnv :: [Table ] -> ModelTags -> AnalyzeEnv
399- mkAnalyzeEnv tables tags =
397+ mkAnalyzeEnv :: [Table ] -> ModelTags -> Info -> AnalyzeEnv
398+ mkAnalyzeEnv tables tags info =
400399 let keySets' = mkFreeArray " keySets"
401400 keySetAuths = mkFreeArray " keySetAuths"
402401
@@ -407,7 +406,7 @@ mkAnalyzeEnv tables tags =
407406 argMap :: Map VarId AVal
408407 argMap = view (located. _2. _2) <$> _mtArgs tags
409408
410- in AnalyzeEnv argMap keySets' keySetAuths invariants' tags
409+ in AnalyzeEnv argMap keySets' keySetAuths invariants' tags info
411410
412411instance (Mergeable a ) => Mergeable (Analyze a ) where
413412 symbolicMerge force test left right = Analyze $ RWST $ \ r s -> ExceptT $ Identity $
@@ -444,26 +443,36 @@ class HasAnalyzeEnv a where
444443instance HasAnalyzeEnv AnalyzeEnv where analyzeEnv = id
445444instance HasAnalyzeEnv QueryEnv where analyzeEnv = qeAnalyzeEnv
446445
447- class (MonadError AnalyzeFailure m ) => Analyzer m term where
448- analyze :: (Show a , SymWord a ) => term a -> m (S a )
446+ class (MonadError AnalyzeFailure m ) => Analyzer m term | m -> term where
447+ analyze :: (Show a , SymWord a ) => term a -> m (S a )
448+ throwErrorNoLoc :: AnalyzeFailureNoLoc -> m a
449449
450450class Analyzer m term => ObjectAnalyzer m term where
451451 analyzeO :: term Object -> m Object
452452
453453instance Analyzer Analyze Term where
454454 analyze = analyzeTerm
455+ throwErrorNoLoc err = do
456+ info <- view (analyzeEnv . aeInfo)
457+ throwError $ AnalyzeFailure info err
455458
456459instance ObjectAnalyzer Analyze Term where
457460 analyzeO = analyzeTermO
458461
459462instance Analyzer Query Prop where
460463 analyze = analyzeProp
464+ throwErrorNoLoc err = do
465+ info <- view (analyzeEnv . aeInfo)
466+ throwError $ AnalyzeFailure info err
461467
462468instance ObjectAnalyzer Query Prop where
463469 analyzeO = analyzePropO
464470
465471instance Analyzer InvariantCheck Invariant where
466472 analyze = checkInvariant
473+ throwErrorNoLoc err = do
474+ info <- view _1
475+ throwError $ AnalyzeFailure info err
467476
468477class SymbolicTerm term where
469478 injectS :: S a -> term a
@@ -544,7 +553,7 @@ tagVarBinding vid av = do
544553succeeds :: Lens' AnalyzeState (S Bool )
545554succeeds = latticeState. lasSucceeds. sbv2S
546555
547- maintainsInvariants :: Lens' AnalyzeState (TableMap (ZipList (Parsed , SBool )))
556+ maintainsInvariants :: Lens' AnalyzeState (TableMap (ZipList (Info , SBool )))
548557maintainsInvariants = latticeState. lasMaintainsInvariants
549558
550559tableRead :: TableName -> Lens' AnalyzeState (S Bool )
@@ -685,7 +694,7 @@ ksAuthorized sKs = do
685694 fmap sansProv $ readArray <$> view ksAuths <*> pure (_sSbv sKs)
686695
687696aval
688- :: MonadError AnalyzeFailure m
697+ :: Analyzer m term
689698 => (Maybe Provenance -> SBVI. SVal -> m a )
690699 -> (Object -> m a )
691700 -> AVal
@@ -695,17 +704,17 @@ aval elimVal elimObj = \case
695704 AnObj obj -> elimObj obj
696705 OpaqueVal -> throwErrorNoLoc OpaqueValEncountered
697706
698- expectVal :: MonadError AnalyzeFailure m => AVal -> m (S a )
707+ expectVal :: Analyzer m term => AVal -> m (S a )
699708expectVal = aval (pure ... mkS) (throwErrorNoLoc . AValUnexpectedlyObj )
700709
701- expectObj :: MonadError AnalyzeFailure m => AVal -> m Object
710+ expectObj :: Analyzer m term => AVal -> m Object
702711expectObj = aval ((throwErrorNoLoc . AValUnexpectedlySVal ) ... getSVal) pure
703712 where
704713 getSVal :: Maybe Provenance -> SBVI. SVal -> SBVI. SVal
705714 getSVal = flip const
706715
707716lookupObj
708- :: (MonadReader r m , HasAnalyzeEnv r , MonadError AnalyzeFailure m )
717+ :: (Analyzer m term , MonadReader r m , HasAnalyzeEnv r )
709718 => Text
710719 -> VarId
711720 -> m Object
@@ -718,7 +727,7 @@ lookupObj name vid = do
718727 Just (OpaqueVal ) -> throwErrorNoLoc OpaqueValEncountered
719728
720729lookupVal
721- :: (MonadReader r m , HasAnalyzeEnv r , MonadError AnalyzeFailure m )
730+ :: (Analyzer m term , MonadReader r m , HasAnalyzeEnv r )
722731 => Text
723732 -> VarId
724733 -> m (S a )
@@ -745,10 +754,10 @@ applyInvariants tn sValFields addInvariants = do
745754 case mInvariants of
746755 Nothing -> pure ()
747756 Just invariants' -> do
748- invariants'' <- for invariants' $ \ (parsed , invariant) ->
749- case runReaderT (checkInvariant invariant) sValFields of
757+ invariants'' <- for invariants' $ \ (info , invariant) ->
758+ case runReaderT (checkInvariant invariant) (info, sValFields) of
750759 -- Use the location of the invariant
751- Left (AnalyzeFailure _ err) -> throwError $ AnalyzeFailure parsed err
760+ Left (AnalyzeFailure _ err) -> throwError $ AnalyzeFailure info err
752761 Right inv -> pure inv
753762 addInvariants invariants''
754763
@@ -974,14 +983,14 @@ analyzeUnaryArithOp op term = do
974983 Signum -> pure $ signum x
975984
976985analyzeModOp
977- :: Analyzer m term
986+ :: ( Analyzer m term )
978987 => term Integer
979988 -> term Integer
980989 -> m (S Integer )
981990analyzeModOp xT yT = sMod <$> analyze xT <*> analyze yT
982991
983992analyzeRoundingLikeOp1
984- :: Analyzer m term
993+ :: ( Analyzer m term )
985994 => RoundingLikeOp
986995 -> term Decimal
987996 -> m (S Integer )
@@ -1069,7 +1078,7 @@ analyzeIntAddTime timeT secsT = do
10691078 pure $ time + fromIntegralS (secs * 1000000 )
10701079
10711080analyzeDecAddTime
1072- :: Analyzer m term
1081+ :: ( Analyzer m term )
10731082 => term Time
10741083 -> term Decimal
10751084 -> m (S Time )
@@ -1200,9 +1209,8 @@ analyzeTerm = \case
12001209 sValFields = Map. mapMaybe id mValFields
12011210
12021211 applyInvariants tn sValFields $ \ invariants' ->
1203- let fs :: ZipList ((Parsed , SBV Bool ) -> (Parsed , SBV Bool ))
1212+ let fs :: ZipList ((Info , SBV Bool ) -> (Info , SBV Bool ))
12041213 fs = ZipList $ (\ s (p, s') -> (p, _sSbv s &&& s')) <$> invariants'
1205- -- fs = ZipList $ (\s (p, s') -> (p, sSbv s &&& s')) <$> invariants'
12061214 in maintainsInvariants . at tn . _Just %= (fs <*> )
12071215
12081216 --
@@ -1289,7 +1297,7 @@ analyzeTerm = \case
12891297 Hash value -> do
12901298 let sHash = literalS . T. unpack . Pact. asString . Pact. hash
12911299 notStaticErr :: AnalyzeFailure
1292- notStaticErr = AnalyzeFailure dummyParsed " We can only analyze calls to `hash` with statically determined contents"
1300+ notStaticErr = AnalyzeFailure dummyInfo " We can only analyze calls to `hash` with statically determined contents"
12931301 case value of
12941302 -- Note that strings are hashed in a different way from the other types
12951303 ETerm tm TStr -> analyze tm <&> unliteralS >>= \ case
@@ -1340,13 +1348,13 @@ format s tms = do
13401348 if plen == 1
13411349 then Right (literalS s)
13421350 else if plen - length tms > 1
1343- then Left (AnalyzeFailure dummyParsed " format: not enough arguments for template" )
1351+ then Left (AnalyzeFailure dummyInfo " format: not enough arguments for template" )
13441352 else Right $ foldl'
13451353 (\ r (e, t) -> r .++ rep e .++ t)
13461354 (head parts)
13471355 (zip tms (tail parts))
13481356
1349- type InvariantCheck = ReaderT (Map Text SBVI. SVal ) (Either AnalyzeFailure )
1357+ type InvariantCheck = ReaderT (Info , Map Text SBVI. SVal ) (Either AnalyzeFailure )
13501358
13511359checkInvariant :: Invariant a -> InvariantCheck (S a )
13521360checkInvariant = \ case
@@ -1362,7 +1370,7 @@ checkInvariant = \case
13621370
13631371 -- variables
13641372 IVar name -> do
1365- mVal <- view (at name)
1373+ mVal <- view (_2 . at name)
13661374 case mVal of
13671375 Just val -> pure (sansProv (SBVI. SBV val))
13681376 Nothing -> throwErrorNoLoc $ fromString $
@@ -1564,7 +1572,7 @@ analyzeCheck = fmap Identity . \case
15641572
15651573-- | A convenience to treat a nested 'TableMap', '[]', and tuple as a single
15661574-- functor instead of three.
1567- newtype InvariantsF a = InvariantsF { unInvariantsF :: TableMap [(Parsed , a )] }
1575+ newtype InvariantsF a = InvariantsF { unInvariantsF :: TableMap [(Info , a )] }
15681576
15691577instance Functor InvariantsF where
15701578 fmap f (InvariantsF a) = InvariantsF (f <$$$> a)
@@ -1577,7 +1585,7 @@ analyzeInvariants = assumingSuccess =<< invariantsHold'
15771585 success <- view (qeAnalyzeState. succeeds)
15781586 pure $ (success ==> ) <$> ps
15791587
1580- invariantsHold :: Query (TableMap (ZipList (Parsed , S Bool )))
1588+ invariantsHold :: Query (TableMap (ZipList (Info , S Bool )))
15811589 invariantsHold = sansProv <$$$$> view (qeAnalyzeState. maintainsInvariants)
15821590
15831591 invariantsHold' :: Query (InvariantsF (S Bool ))
@@ -1590,10 +1598,11 @@ runAnalysis'
15901598 -> [Table ]
15911599 -> ETerm
15921600 -> ModelTags
1601+ -> Info
15931602 -> ExceptT AnalyzeFailure Symbolic (f AnalysisResult )
1594- runAnalysis' query tables tm tags = do
1603+ runAnalysis' query tables tm tags info = do
15951604 let act = analyzeETerm tm >>= \ res -> tagResult res >> pure res
1596- aEnv = mkAnalyzeEnv tables tags
1605+ aEnv = mkAnalyzeEnv tables tags info
15971606 state0 = mkInitialAnalyzeState tables
15981607
15991608 (funResult, state1, () ) <- hoist generalize $
@@ -1612,14 +1621,16 @@ runPropertyAnalysis
16121621 -> [Table ]
16131622 -> ETerm
16141623 -> ModelTags
1624+ -> Info
16151625 -> ExceptT AnalyzeFailure Symbolic AnalysisResult
1616- runPropertyAnalysis check tables tm tags =
1617- runIdentity <$> runAnalysis' (analyzeCheck check) tables tm tags
1626+ runPropertyAnalysis check tables tm tags info =
1627+ runIdentity <$> runAnalysis' (analyzeCheck check) tables tm tags info
16181628
16191629runInvariantAnalysis
16201630 :: [Table ]
16211631 -> ETerm
16221632 -> ModelTags
1623- -> ExceptT AnalyzeFailure Symbolic (TableMap [(Parsed , AnalysisResult )])
1624- runInvariantAnalysis tables tm tags =
1625- unInvariantsF <$> runAnalysis' analyzeInvariants tables tm tags
1633+ -> Info
1634+ -> ExceptT AnalyzeFailure Symbolic (TableMap [(Info , AnalysisResult )])
1635+ runInvariantAnalysis tables tm tags info =
1636+ unInvariantsF <$> runAnalysis' analyzeInvariants tables tm tags info
0 commit comments