From 0b2b27ff218f08178536cdb41136e1dffe8619b4 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 16:40:56 -0400 Subject: [PATCH 01/18] Stub in an AppMerge semigroup. --- semantic.cabal | 1 + src/Data/Semigroup/App.hs | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 src/Data/Semigroup/App.hs diff --git a/semantic.cabal b/semantic.cabal index 132722e06..9b8c4b9af 100644 --- a/semantic.cabal +++ b/semantic.cabal @@ -72,6 +72,7 @@ library , Data.Patch , Data.Range , Data.Record + , Data.Semigroup.App , Data.Source , Data.Span , Data.SplitDiff diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs new file mode 100644 index 000000000..7f183d5eb --- /dev/null +++ b/src/Data/Semigroup/App.hs @@ -0,0 +1,7 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +module Data.Semigroup.App where + +import Control.Applicative + +newtype AppMerge f a = AppMerge { runAppMerge :: f a } + deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) From 541e23043148cc626c15de951c6eb16c80b60eb7 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 16:41:32 -0400 Subject: [PATCH 02/18] Define a Semigroup instance for AppMerge. --- src/Data/Semigroup/App.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 7f183d5eb..07d5c0ec0 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -2,6 +2,10 @@ module Data.Semigroup.App where import Control.Applicative +import Data.Semigroup newtype AppMerge f a = AppMerge { runAppMerge :: f a } deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) + +instance (Applicative f, Semigroup a) => Semigroup (AppMerge f a) where + AppMerge a <> AppMerge b = AppMerge ((<>) <$> a <*> b) From 794a03a49c124887ff3b3a172386d76688fda05b Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 16:41:41 -0400 Subject: [PATCH 03/18] :memo: AppMerge. --- src/Data/Semigroup/App.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 07d5c0ec0..9b393f126 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -4,6 +4,7 @@ module Data.Semigroup.App where import Control.Applicative import Data.Semigroup +-- | 'Semigroup' under '<*>' and '<>'. newtype AppMerge f a = AppMerge { runAppMerge :: f a } deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) From 88230df1fe910acd5c7cf4840313b488413f90b5 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 16:41:49 -0400 Subject: [PATCH 04/18] Define a Monoid instance for AppMerge. --- src/Data/Semigroup/App.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 9b393f126..639c1c87c 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -10,3 +10,7 @@ newtype AppMerge f a = AppMerge { runAppMerge :: f a } instance (Applicative f, Semigroup a) => Semigroup (AppMerge f a) where AppMerge a <> AppMerge b = AppMerge ((<>) <$> a <*> b) + +instance (Applicative f, Monoid a, Semigroup a) => Monoid (AppMerge f a) where + mempty = AppMerge (pure mempty) + mappend = (<>) From 8f22cb26f885e9a302a0233de71cc5bea62cc724 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 16:44:35 -0400 Subject: [PATCH 05/18] Explicitly list the exports. --- src/Data/Semigroup/App.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 639c1c87c..875d3319d 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -1,5 +1,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} -module Data.Semigroup.App where +module Data.Semigroup.App +( AppMerge(..) +) where import Control.Applicative import Data.Semigroup From 6399cb3c58a3d0963b58331f266e2d36c7a452d8 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:07:49 -0400 Subject: [PATCH 06/18] Define an App semigroup. --- src/Data/Semigroup/App.hs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 875d3319d..6fec42eb1 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -1,6 +1,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Data.Semigroup.App ( AppMerge(..) +, App(..) ) where import Control.Applicative @@ -16,3 +17,7 @@ instance (Applicative f, Semigroup a) => Semigroup (AppMerge f a) where instance (Applicative f, Monoid a, Semigroup a) => Monoid (AppMerge f a) where mempty = AppMerge (pure mempty) mappend = (<>) + + +newtype App f a = App { runApp :: f a } + deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) From 5ea6482e96571f026780686f0c7d1068f3460ea1 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:07:55 -0400 Subject: [PATCH 07/18] :memo: App. --- src/Data/Semigroup/App.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 6fec42eb1..4708edb27 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -19,5 +19,6 @@ instance (Applicative f, Monoid a, Semigroup a) => Monoid (AppMerge f a) where mappend = (<>) +-- | 'Semigroup' under '*>'. newtype App f a = App { runApp :: f a } deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) From 3329bd0a5176ca5d17f39b9e39497368895d6ddd Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:08:06 -0400 Subject: [PATCH 08/18] Define a Semigroup instance for App. --- src/Data/Semigroup/App.hs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 4708edb27..4218a110c 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -22,3 +22,6 @@ instance (Applicative f, Monoid a, Semigroup a) => Monoid (AppMerge f a) where -- | 'Semigroup' under '*>'. newtype App f a = App { runApp :: f a } deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) + +instance Applicative f => Semigroup (App f a) where + App a <> App b = App (a *> b) From e0245ed7524cbfbbb0021769a2642d037ced7680 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:08:14 -0400 Subject: [PATCH 09/18] Define a Monoid instance for App. --- src/Data/Semigroup/App.hs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 4218a110c..414ce1c9b 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -25,3 +25,7 @@ newtype App f a = App { runApp :: f a } instance Applicative f => Semigroup (App f a) where App a <> App b = App (a *> b) + +instance (Applicative f, Monoid a) => Monoid (App f a) where + mempty = App (pure mempty) + mappend = (<>) From 256623a81816f02703d336d246febe8fd50a8f90 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:08:25 -0400 Subject: [PATCH 10/18] eval lists in App. --- src/Data/Abstract/Evaluatable.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Data/Abstract/Evaluatable.hs b/src/Data/Abstract/Evaluatable.hs index adf41de29..21d7c6a98 100644 --- a/src/Data/Abstract/Evaluatable.hs +++ b/src/Data/Abstract/Evaluatable.hs @@ -16,6 +16,7 @@ import Data.Abstract.Value import Data.Functor.Classes import Data.Proxy import Data.Semigroup.Foldable +import Data.Semigroup.App import Data.Term import Prelude hiding (fail) import Prologue @@ -51,7 +52,7 @@ instance Evaluatable s => Evaluatable (TermF s a) where -- 3. Only the last statement’s return value is returned. instance Evaluatable [] where -- 'nonEmpty' and 'foldMap1' enable us to return the last statement’s result instead of 'unit' for non-empty lists. - eval = maybe unit (runImperative . foldMap1 (Imperative . subtermValue)) . nonEmpty + eval = maybe unit (runApp . foldMap1 (App . subtermValue)) . nonEmpty -- | A 'Semigroup' providing an imperative context which extends the local environment with new bindings. newtype Imperative m a = Imperative { runImperative :: m a } From 69a4e4cc2eff281725274f3bff8018e0bb8e9fa8 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:08:52 -0400 Subject: [PATCH 11/18] :fire: Imperative. --- src/Data/Abstract/Evaluatable.hs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Data/Abstract/Evaluatable.hs b/src/Data/Abstract/Evaluatable.hs index 21d7c6a98..c4cb0ff63 100644 --- a/src/Data/Abstract/Evaluatable.hs +++ b/src/Data/Abstract/Evaluatable.hs @@ -53,13 +53,3 @@ instance Evaluatable s => Evaluatable (TermF s a) where instance Evaluatable [] where -- 'nonEmpty' and 'foldMap1' enable us to return the last statement’s result instead of 'unit' for non-empty lists. eval = maybe unit (runApp . foldMap1 (App . subtermValue)) . nonEmpty - --- | A 'Semigroup' providing an imperative context which extends the local environment with new bindings. -newtype Imperative m a = Imperative { runImperative :: m a } - -instance MonadEnvironment value m => Semigroup (Imperative m a) where - Imperative a <> Imperative b = Imperative (a *> b) - -instance (MonadEnvironment value m, MonadValue value m) => Monoid (Imperative m value) where - mempty = Imperative unit - mappend = (<>) From c6148c6cad3f5322ab5a6bcc54f6319fb1815859 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:16:09 -0400 Subject: [PATCH 12/18] Test the associativity of the semigroup instances. --- src/Data/Semigroup/App.hs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 414ce1c9b..78922f68c 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -7,10 +7,17 @@ module Data.Semigroup.App import Control.Applicative import Data.Semigroup +-- $setup +-- >>> import Test.QuickCheck +-- >>> instance Arbitrary (f a) => Arbitrary (App f a) where arbitrary = App <$> arbitrary +-- >>> instance Arbitrary (f a) => Arbitrary (AppMerge f a) where arbitrary = AppMerge <$> arbitrary + -- | 'Semigroup' under '<*>' and '<>'. newtype AppMerge f a = AppMerge { runAppMerge :: f a } deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) +-- $ Associativity: +-- prop> \ a b c -> a <> (b <> c) == (a <> b) <> (c :: AppMerge Maybe String) instance (Applicative f, Semigroup a) => Semigroup (AppMerge f a) where AppMerge a <> AppMerge b = AppMerge ((<>) <$> a <*> b) @@ -23,6 +30,8 @@ instance (Applicative f, Monoid a, Semigroup a) => Monoid (AppMerge f a) where newtype App f a = App { runApp :: f a } deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) +-- $ Associativity: +-- prop> \ a b c -> a <> (b <> c) == (a <> b) <> (c :: App Maybe Integer) instance Applicative f => Semigroup (App f a) where App a <> App b = App (a *> b) From 6be056bd9ad6ac5fdce2b38754932d77a2b43255 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:16:31 -0400 Subject: [PATCH 13/18] Swap the order of the types. --- src/Data/Semigroup/App.hs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 78922f68c..8292024e7 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -1,7 +1,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Data.Semigroup.App -( AppMerge(..) -, App(..) +( App(..) +, AppMerge(..) ) where import Control.Applicative @@ -12,20 +12,6 @@ import Data.Semigroup -- >>> instance Arbitrary (f a) => Arbitrary (App f a) where arbitrary = App <$> arbitrary -- >>> instance Arbitrary (f a) => Arbitrary (AppMerge f a) where arbitrary = AppMerge <$> arbitrary --- | 'Semigroup' under '<*>' and '<>'. -newtype AppMerge f a = AppMerge { runAppMerge :: f a } - deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) - --- $ Associativity: --- prop> \ a b c -> a <> (b <> c) == (a <> b) <> (c :: AppMerge Maybe String) -instance (Applicative f, Semigroup a) => Semigroup (AppMerge f a) where - AppMerge a <> AppMerge b = AppMerge ((<>) <$> a <*> b) - -instance (Applicative f, Monoid a, Semigroup a) => Monoid (AppMerge f a) where - mempty = AppMerge (pure mempty) - mappend = (<>) - - -- | 'Semigroup' under '*>'. newtype App f a = App { runApp :: f a } deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) @@ -38,3 +24,17 @@ instance Applicative f => Semigroup (App f a) where instance (Applicative f, Monoid a) => Monoid (App f a) where mempty = App (pure mempty) mappend = (<>) + + +-- | 'Semigroup' under '<*>' and '<>'. +newtype AppMerge f a = AppMerge { runAppMerge :: f a } + deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) + +-- $ Associativity: +-- prop> \ a b c -> a <> (b <> c) == (a <> b) <> (c :: AppMerge Maybe String) +instance (Applicative f, Semigroup a) => Semigroup (AppMerge f a) where + AppMerge a <> AppMerge b = AppMerge ((<>) <$> a <*> b) + +instance (Applicative f, Monoid a, Semigroup a) => Monoid (AppMerge f a) where + mempty = AppMerge (pure mempty) + mappend = (<>) From b55010c2c1e5339bd311287a28dd10ec329a98a7 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:22:34 -0400 Subject: [PATCH 14/18] Define shrinking. --- src/Data/Semigroup/App.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 8292024e7..506fafe80 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -9,8 +9,8 @@ import Data.Semigroup -- $setup -- >>> import Test.QuickCheck --- >>> instance Arbitrary (f a) => Arbitrary (App f a) where arbitrary = App <$> arbitrary --- >>> instance Arbitrary (f a) => Arbitrary (AppMerge f a) where arbitrary = AppMerge <$> arbitrary +-- >>> instance Arbitrary (f a) => Arbitrary (App f a) where arbitrary = App <$> arbitrary ; shrink = map App . shrink . runApp +-- >>> instance Arbitrary (f a) => Arbitrary (AppMerge f a) where arbitrary = AppMerge <$> arbitrary ; shrink = map AppMerge . shrink . runAppMerge -- | 'Semigroup' under '*>'. newtype App f a = App { runApp :: f a } From aab509cf63ea1d858e39b64f75f00c79a2a2c6f2 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:26:07 -0400 Subject: [PATCH 15/18] Test the identity properties. --- src/Data/Semigroup/App.hs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 506fafe80..ccd10f4f5 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -21,6 +21,9 @@ newtype App f a = App { runApp :: f a } instance Applicative f => Semigroup (App f a) where App a <> App b = App (a *> b) +-- $ Identity: +-- prop> \ a -> mempty <> a == (a :: App Maybe String) +-- prop> \ a -> a <> mempty == (a :: App Maybe String) instance (Applicative f, Monoid a) => Monoid (App f a) where mempty = App (pure mempty) mappend = (<>) @@ -35,6 +38,9 @@ newtype AppMerge f a = AppMerge { runAppMerge :: f a } instance (Applicative f, Semigroup a) => Semigroup (AppMerge f a) where AppMerge a <> AppMerge b = AppMerge ((<>) <$> a <*> b) +-- $ Identity: +-- prop> \ a -> mempty <> a == (a :: AppMerge Maybe String) +-- prop> \ a -> a <> mempty == (a :: AppMerge Maybe String) instance (Applicative f, Monoid a, Semigroup a) => Monoid (AppMerge f a) where mempty = AppMerge (pure mempty) mappend = (<>) From 6a785e0b30beb64d8feda6666f54a36c7816b8d4 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:26:32 -0400 Subject: [PATCH 16/18] =?UTF-8?q?Remove=20the=20Monoid=20instance=20for=20?= =?UTF-8?q?App,=20as=20it=E2=80=99s=20unlawful.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Data/Semigroup/App.hs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index ccd10f4f5..58d666076 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -21,13 +21,6 @@ newtype App f a = App { runApp :: f a } instance Applicative f => Semigroup (App f a) where App a <> App b = App (a *> b) --- $ Identity: --- prop> \ a -> mempty <> a == (a :: App Maybe String) --- prop> \ a -> a <> mempty == (a :: App Maybe String) -instance (Applicative f, Monoid a) => Monoid (App f a) where - mempty = App (pure mempty) - mappend = (<>) - -- | 'Semigroup' under '<*>' and '<>'. newtype AppMerge f a = AppMerge { runAppMerge :: f a } From d645481dcfd182b2d3fbd5d68359087d3bd4838b Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Wed, 21 Mar 2018 17:29:48 -0400 Subject: [PATCH 17/18] :memo: AppMerge is a Monoid too. --- src/Data/Semigroup/App.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Data/Semigroup/App.hs b/src/Data/Semigroup/App.hs index 58d666076..4ed13ff3c 100644 --- a/src/Data/Semigroup/App.hs +++ b/src/Data/Semigroup/App.hs @@ -22,7 +22,7 @@ instance Applicative f => Semigroup (App f a) where App a <> App b = App (a *> b) --- | 'Semigroup' under '<*>' and '<>'. +-- | 'Semigroup' and 'Monoid' under '<*>' and '<>'. newtype AppMerge f a = AppMerge { runAppMerge :: f a } deriving (Alternative, Applicative, Bounded, Enum, Eq, Foldable, Functor, Monad, Ord, Show, Traversable) From 9a91728d4e7edd2c4375ad54627e2762a3398e74 Mon Sep 17 00:00:00 2001 From: Timothy Clem Date: Thu, 22 Mar 2018 09:28:11 -0700 Subject: [PATCH 18/18] Only one require/load Co-Authored-By: Josh Vera --- src/Analysis/Abstract/Evaluating.hs | 23 ++++------------------- src/Data/Syntax/Declaration.hs | 6 +++--- src/Language/PHP/Syntax.hs | 4 ++-- src/Language/Ruby/Syntax.hs | 4 ++-- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/Analysis/Abstract/Evaluating.hs b/src/Analysis/Abstract/Evaluating.hs index 01d47c0b1..ad21ae6ec 100644 --- a/src/Analysis/Abstract/Evaluating.hs +++ b/src/Analysis/Abstract/Evaluating.hs @@ -4,9 +4,7 @@ module Analysis.Abstract.Evaluating , evaluate , evaluates , require -, require' , load -, load' ) where import Control.Abstract.Evaluator @@ -74,34 +72,21 @@ withModules Blob{..} pairs = localModuleTable (const moduleTable) _ -> toName path toName str = qualifiedName (fmap BC.pack (splitWhen (== pathSeparator) str)) - --- | Require/import another module by name and return it's environment +-- | Require/import another module by name and return it's environment and value. -- -- Looks up the term's name in the cache of evaluated modules first, returns if found, otherwise loads/evaluates the module. require :: (MonadAnalysis term value m, MonadValue value m) - => ModuleName - -> m (EnvironmentFor value) -require name = fst <$> require' name - --- | Require/import another module by name and return it's environment and value. -require' :: (MonadAnalysis term value m, MonadValue value m) => ModuleName -> m (EnvironmentFor value, value) -require' name = getModuleTable >>= maybe (load' name) pure . moduleTableLookup name +require name = getModuleTable >>= maybe (load name) pure . moduleTableLookup name --- | Load another module by name and return it's environment +-- | Load another module by name and return it's environment and value. -- -- Always loads/evaluates. load :: (MonadAnalysis term value m, MonadValue value m) - => ModuleName - -> m (EnvironmentFor value) -load name = fst <$> load' name - --- | Load another module by name and return it's environment and value. -load' :: (MonadAnalysis term value m, MonadValue value m) => ModuleName -> m (EnvironmentFor value, value) -load' name = askModuleTable >>= maybe notFound evalAndCache . moduleTableLookup name +load name = askModuleTable >>= maybe notFound evalAndCache . moduleTableLookup name where notFound = fail ("cannot load module: " <> show name) evalAndCache :: (MonadAnalysis term value m, MonadValue value m) => [term] -> m (EnvironmentFor value, value) diff --git a/src/Data/Syntax/Declaration.hs b/src/Data/Syntax/Declaration.hs index 9c622b29b..d5abbdde4 100644 --- a/src/Data/Syntax/Declaration.hs +++ b/src/Data/Syntax/Declaration.hs @@ -244,7 +244,7 @@ instance Show1 QualifiedExportFrom where liftShowsPrec = genericLiftShowsPrec instance Evaluatable QualifiedExportFrom where eval (QualifiedExportFrom from exportSymbols) = do let moduleName = freeVariable (subterm from) - importedEnv <- isolate (require moduleName) + (importedEnv, _) <- isolate (require moduleName) -- Look up addresses in importedEnv and insert the aliases with addresses into the exports. for_ exportSymbols $ \(name, alias) -> do let address = Env.lookup name importedEnv @@ -277,7 +277,7 @@ instance Show1 QualifiedImport where liftShowsPrec = genericLiftShowsPrec instance Evaluatable QualifiedImport where eval (QualifiedImport from alias xs) = do - importedEnv <- isolate (require moduleName) + (importedEnv, _) <- isolate (require moduleName) modifyEnv (mappend (Env.overwrite (renames importedEnv) importedEnv)) unit where @@ -300,7 +300,7 @@ instance Show1 Import where liftShowsPrec = genericLiftShowsPrec instance Evaluatable Import where eval (Import from xs _) = do - importedEnv <- isolate (require moduleName) + (importedEnv, _) <- isolate (require moduleName) modifyEnv (mappend (renamed importedEnv)) unit where diff --git a/src/Language/PHP/Syntax.hs b/src/Language/PHP/Syntax.hs index 2361a5a30..116565cef 100644 --- a/src/Language/PHP/Syntax.hs +++ b/src/Language/PHP/Syntax.hs @@ -36,14 +36,14 @@ instance Evaluatable VariableName doInclude :: (MonadValue value m, MonadAnalysis term value m) => Subterm t (m value) -> m value doInclude path = do name <- toQualifiedName <$> (subtermValue path >>= asString) - (importedEnv, v) <- isolate (load' name) + (importedEnv, v) <- isolate (load name) modifyEnv (mappend importedEnv) pure v doIncludeOnce :: (MonadValue value m, MonadAnalysis term value m) => Subterm t (m value) -> m value doIncludeOnce path = do name <- toQualifiedName <$> (subtermValue path >>= asString) - (importedEnv, v) <- isolate (require' name) + (importedEnv, v) <- isolate (require name) modifyEnv (mappend importedEnv) pure v diff --git a/src/Language/Ruby/Syntax.hs b/src/Language/Ruby/Syntax.hs index 04a6792ad..0da7d083d 100644 --- a/src/Language/Ruby/Syntax.hs +++ b/src/Language/Ruby/Syntax.hs @@ -34,7 +34,7 @@ doRequire :: (MonadAnalysis term value m, MonadValue value m) doRequire name = do moduleTable <- getModuleTable case moduleTableLookup name moduleTable of - Nothing -> (,) <$> load name <*> boolean True + Nothing -> (,) <$> (fst <$> load name) <*> boolean True Just (env, _) -> (,) <$> pure env <*> boolean False @@ -57,7 +57,7 @@ instance Evaluatable Load where doLoad :: (MonadAnalysis term value m, MonadValue value m) => ByteString -> Bool -> m value doLoad path shouldWrap = do - importedEnv <- isolate (load (toName path)) + (importedEnv, _) <- isolate (load (toName path)) unless shouldWrap $ modifyEnv (mappend importedEnv) boolean Prelude.True -- load always returns true. http://ruby-doc.org/core-2.5.0/Kernel.html#method-i-load where