{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}

module Cubix.Language.JavaScript.Parametric.Common.Types where

#ifndef ONLY_ONE_LANGUAGE
import Data.List ( (\\) )
import Language.Haskell.TH ( mkName )

import Data.Comp.Multi ( Term, project', project, HFunctor, (:-<:), All, CxtS, AnnCxtS )
import Data.Comp.Trans ( runCompTrans, makeSumType )

import Cubix.Language.Info
import Cubix.Language.JavaScript.Parametric.Full.Types as JS
import Cubix.Language.Parametric.Derive
import Cubix.Language.Parametric.InjF
import Cubix.Language.Parametric.Syntax as P

-----------------------------------------------------------------------------------
---------------       Variable declarations and blocks     ------------------------
-----------------------------------------------------------------------------------

-- Biggest gotcha of JavaScript: Scopes are weird. See
-- https://gist.github.com/jkoppel/3f65e316ec921a90ee5228f771da4a5d for an
-- example of why. The big thing to know is that only new functions introduce
-- scopes, and a variable is local if it is in a "var" decl anywhere within the scope,
-- regardless of where that declaration is. Hence, the common "Block" fragment
-- does not model general JS blocks, but does model function bodies
--
-- The JS library we're using lets you put arbitrary expressions as LHSs. JS does not.
-- I don't like this.
--
-- Also note that it has separate "JSAssignStatement" and "JSAssign" (expression) constructors.
-- It seems to somewhat arbitrarily parse an assign as either an AssignStatement or as an ExpressionStatement.
-- The official grammar only has the latter. As an exception to my "isomorphism" rule, I am going to convert all such things
-- to the latter because that's what they should have been in the first place. (Also, strictly speaking, it's still isomorphic
-- to the original tree; it's just that the grammar's redundant)
--
createSortInclusionTypes [ ''P.IdentL,      ''JSExpressionL,   ''JSExpressionL,    ''P.MultiLocalVarDeclL, ''JSExpressionL, ''JSExpressionL, ''JSAssignOpL, ''P.AssignL,      ''P.BlockL,      ''JSStatementL, ''JSBlockL
                         ] [
                           ''JSExpressionL, ''P.LocalVarInitL, ''P.VarDeclBinderL, ''JSStatementL,         ''P.RhsL,        ''P.LhsL,        ''P.AssignOpL, ''JSExpressionL,  ''JSStatementL, ''P.BlockItemL,  ''JSASTL
                         ]
deriveAll [''IdentIsJSExpression, ''JSExpressionIsLocalVarInit, ''JSExpressionIsVarDeclBinder,
           ''MultiLocalVarDeclIsJSStatement, ''JSExpressionIsRhs, ''JSExpressionIsLhs, ''JSAssignOpIsAssignOp,
           ''AssignIsJSExpression, ''BlockIsJSStatement, ''JSStatementIsBlockItem, ''JSBlockIsJSAST]
createSortInclusionInfers [ ''P.IdentL,      ''JSExpressionL,   ''JSExpressionL,    ''P.MultiLocalVarDeclL, ''JSExpressionL, ''JSExpressionL, ''JSAssignOpL, ''P.AssignL,     ''P.BlockL,     ''JSStatementL, ''JSBlockL
                          ] [
                            ''JSExpressionL, ''P.LocalVarInitL, ''P.VarDeclBinderL, ''JSStatementL,         ''P.RhsL,        ''P.LhsL,        ''P.AssignOpL, ''JSExpressionL, ''JSStatementL, ''P.BlockItemL, ''JSASTL
                          ]

data MaybeIdentIsJSIdent e l where
  MaybeIdentIsJSIdent :: e (Maybe IdentL) -> MaybeIdentIsJSIdent e JSIdentL

deriveAll [''MaybeIdentIsJSIdent]

pattern JSIdent' :: (MaybeIdentIsJSIdent :-<: fs, Ident :-<: fs, MaybeF :-<: fs, All HFunctor fs) => String -> CxtS h fs a JSIdentL
pattern $bJSIdent' :: String -> CxtS h fs a JSIdentL
$mJSIdent' :: forall r (fs :: [(* -> *) -> * -> *]) h (a :: * -> *).
(MaybeIdentIsJSIdent :-<: fs, Ident :-<: fs, MaybeF :-<: fs,
 All HFunctor fs) =>
CxtS h fs a JSIdentL -> (String -> r) -> (Void# -> r) -> r
JSIdent' ident <- (project -> Just (MaybeIdentIsJSIdent (Just' (Ident' ident)))) where
  JSIdent' ident :: String
ident = CxtS h fs a (Maybe IdentL) -> CxtS h fs a JSIdentL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(MaybeIdentIsJSIdent :-<: fs, InjF fs JSIdentL j) =>
CxtS h fs a (Maybe IdentL) -> CxtS h fs a j
iMaybeIdentIsJSIdent (CxtS h fs a (Maybe IdentL) -> CxtS h fs a JSIdentL)
-> CxtS h fs a (Maybe IdentL) -> CxtS h fs a JSIdentL
forall a b. (a -> b) -> a -> b
$ Cxt h (Sum fs) a IdentL -> CxtS h fs a (Maybe IdentL)
forall (f :: (* -> *) -> * -> *) l h (a :: * -> *).
(MaybeF :<: f, Typeable l, HFunctor f) =>
Cxt h f a l -> Cxt h f a (Maybe l)
Just' (Cxt h (Sum fs) a IdentL -> CxtS h fs a (Maybe IdentL))
-> Cxt h (Sum fs) a IdentL -> CxtS h fs a (Maybe IdentL)
forall a b. (a -> b) -> a -> b
$ String -> Cxt h (Sum fs) a IdentL
forall (fs :: [(* -> *) -> * -> *]) h (a :: * -> *).
(Ident :-<: fs, All HFunctor fs) =>
String -> CxtS h fs a IdentL
Ident' String
ident

data JSFor e l where
  JSFor      :: e [JSExpressionL] -> e [JSExpressionL] -> e [JSExpressionL] -> e JSStatementL -> JSFor e JSStatementL
  JSForIn    :: e JSExpressionL -> e JSBinOpL -> e JSExpressionL -> e JSStatementL -> JSFor e JSStatementL
  JSForVar   :: e [SingleLocalVarDeclL] -> e [JSExpressionL] -> e [JSExpressionL] -> e JSStatementL -> JSFor e JSStatementL
  JSForVarIn :: e SingleLocalVarDeclL -> e JSBinOpL -> e JSExpressionL -> e JSStatementL -> JSFor e JSStatementL

deriveAll [''JSFor]

data BlockWithPrelude e l where
  BlockWithPrelude :: [String] -> e BlockL -> BlockWithPrelude e JSBlockL

deriveAll [''BlockWithPrelude]

-----------------------------------------------------------------------------------
---------------       Function calls, decls, defns         ------------------------
-----------------------------------------------------------------------------------


-- There are three ways to give a method call in the language-javascript AST: JSMethodCall,
-- JSCallExpression, and JSMemberExpression. In the spec, there is only one way, and it's called "CallExpression"
-- No qualms about merging these; they are identical.
--
-- For function calls, we choose not to model the receiver, because how "thisValue" works in JS is a bit complicated.
-- In omitting this, we still follow the spec for FunctionCall and ArgumentList

createSortInclusionTypes [ ''FunctionCallL, ''JSExpressionL,     ''JSExpressionL, ''FunctionDefL, ''JSBlockL
                         ] [
                           ''JSExpressionL, ''PositionalArgExpL, ''FunctionExpL,  ''JSStatementL, ''FunctionBodyL
                         ]
deriveAll [ ''FunctionCallIsJSExpression, ''JSExpressionIsPositionalArgExp, ''JSExpressionIsFunctionExp
          , ''FunctionDefIsJSStatement, ''JSBlockIsFunctionBody]
createSortInclusionInfers [ ''FunctionCallL, ''JSExpressionL,     ''JSExpressionL, ''FunctionDefL, ''JSBlockL
                          ] [
                            ''JSExpressionL, ''PositionalArgExpL, ''FunctionExpL,  ''JSStatementL, ''FunctionBodyL
                          ]


-----------------------------------------------------------------------------------
----------------------         Declaring the IPS           ------------------------
-----------------------------------------------------------------------------------

do let jsSortInjections = [''IdentIsJSExpression, ''JSExpressionIsLocalVarInit, ''JSExpressionIsVarDeclBinder,
                           ''MultiLocalVarDeclIsJSStatement, ''JSExpressionIsRhs, ''JSExpressionIsLhs, ''JSAssignOpIsAssignOp,
                           ''AssignIsJSExpression, ''BlockIsJSStatement, ''JSStatementIsBlockItem, ''BlockWithPrelude, ''JSBlockIsJSAST,
                           ''FunctionCallIsJSExpression, ''JSExpressionIsPositionalArgExp, ''JSExpressionIsFunctionExp, ''FunctionDefIsJSStatement, ''JSBlockIsFunctionBody]
   let names = (jsSigNames \\ [mkName "JSIdent", mkName "JSVarInitializer"])
                    ++ jsSortInjections
                    ++ [''MaybeIdentIsJSIdent, ''JSFor]
                    ++ [ ''OptLocalVarInit, ''SingleLocalVarDecl, ''P.Ident
                       , ''AssignOpEquals, ''Assign, ''P.Block, ''P.TupleBinder
                       , ''EmptyLocalVarDeclAttrs, ''MultiLocalVarDecl
                       , ''EmptyBlockEnd, ''EmptyMultiLocalVarDeclCommonAttrs
                       , ''FunctionCall, ''EmptyFunctionCallAttrs, ''FunctionArgumentList, ''PositionalArgument
                       , ''FunctionDef, ''EmptyFunctionDefAttrs, ''PositionalParameter, ''EmptyParameterAttrs
                       ]

   sumDec <- runCompTrans $ makeSumType "MJSSig" names
   return sumDec

type instance InjectableSorts MJSSig AssignL = [JSExpressionL, BlockItemL]
type instance InjectableSorts MJSSig MultiLocalVarDeclL = [JSStatementL, BlockItemL]

type MJSTerm = Term MJSSig
type MJSTermLab = TermLab MJSSig

type MJSCxt h a = CxtS h MJSSig a
type MJSCxtA h a p = AnnCxtS p h MJSSig a


-----------------------------------------------------------------------------------
----------------------         Sort injections             ------------------------
-----------------------------------------------------------------------------------

instance InjF MJSSig (Maybe IdentL) JSIdentL where
  injF :: CxtS h MJSSig a (Maybe IdentL) -> CxtS h MJSSig a JSIdentL
injF = CxtS h MJSSig a (Maybe IdentL) -> CxtS h MJSSig a JSIdentL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(MaybeIdentIsJSIdent :-<: fs, InjF fs JSIdentL j) =>
CxtS h fs a (Maybe IdentL) -> CxtS h fs a j
iMaybeIdentIsJSIdent
  projF' :: Cxt h (Sum MJSSig :&: p) a JSIdentL
-> Maybe (Cxt h (Sum MJSSig :&: p) a (Maybe IdentL))
projF' (Cxt h (Sum MJSSig :&: p) a JSIdentL
-> Maybe
     (MaybeIdentIsJSIdent (Cxt h (Sum MJSSig :&: p) a) JSIdentL)
forall (f :: (* -> *) -> * -> *) (f' :: (* -> *) -> * -> *)
       (s :: (* -> *) -> * -> *) h (a :: * -> *) i.
(RemA f f', s :<: f') =>
Cxt h f a i -> Maybe (s (Cxt h f a) i)
project' -> Just (MaybeIdentIsJSIdent x :: Cxt h (Sum MJSSig :&: p) a (Maybe IdentL)
x)) = Cxt h (Sum MJSSig :&: p) a (Maybe IdentL)
-> Maybe (Cxt h (Sum MJSSig :&: p) a (Maybe IdentL))
forall a. a -> Maybe a
Just Cxt h (Sum MJSSig :&: p) a (Maybe IdentL)
x
  projF' _                                         = Maybe (Cxt h (Sum MJSSig :&: p) a (Maybe IdentL))
forall a. Maybe a
Nothing

instance InjF MJSSig MultiLocalVarDeclL BlockItemL where
  injF :: CxtS h MJSSig a MultiLocalVarDeclL -> CxtS h MJSSig a BlockItemL
injF = CxtS h MJSSig a JSStatementL -> CxtS h MJSSig a BlockItemL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(JSStatementIsBlockItem :-<: fs, InjF fs BlockItemL j) =>
CxtS h fs a JSStatementL -> CxtS h fs a j
iJSStatementIsBlockItem (CxtS h MJSSig a JSStatementL -> CxtS h MJSSig a BlockItemL)
-> (CxtS h MJSSig a MultiLocalVarDeclL
    -> CxtS h MJSSig a JSStatementL)
-> CxtS h MJSSig a MultiLocalVarDeclL
-> CxtS h MJSSig a BlockItemL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CxtS h MJSSig a MultiLocalVarDeclL -> CxtS h MJSSig a JSStatementL
forall (fs :: [(* -> *) -> * -> *]) l l' h (a :: * -> *).
InjF fs l l' =>
CxtS h fs a l -> CxtS h fs a l'
injF
  projF' :: Cxt h (Sum MJSSig :&: p) a BlockItemL
-> Maybe (Cxt h (Sum MJSSig :&: p) a MultiLocalVarDeclL)
projF' x :: Cxt h (Sum MJSSig :&: p) a BlockItemL
x = do
    (MJSCxtA h a p JSStatementL
y :: MJSCxtA h a _ JSStatementL) <- Cxt h (Sum MJSSig :&: p) a BlockItemL
-> Maybe (MJSCxtA h a p JSStatementL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a BlockItemL
x
    MJSCxtA h a p JSStatementL
-> Maybe (Cxt h (Sum MJSSig :&: p) a MultiLocalVarDeclL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' MJSCxtA h a p JSStatementL
y

instance InjF MJSSig SingleLocalVarDeclL BlockItemL where
  injF :: CxtS h MJSSig a SingleLocalVarDeclL -> CxtS h MJSSig a BlockItemL
injF x :: CxtS h MJSSig a SingleLocalVarDeclL
x = CxtS h MJSSig a MultiLocalVarDeclL -> CxtS h MJSSig a BlockItemL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(MultiLocalVarDeclIsJSStatement :-<: fs, InjF fs JSStatementL j) =>
CxtS h fs a MultiLocalVarDeclL -> CxtS h fs a j
iMultiLocalVarDeclIsJSStatement (CxtS h MJSSig a MultiLocalVarDeclL -> CxtS h MJSSig a BlockItemL)
-> CxtS h MJSSig a MultiLocalVarDeclL -> CxtS h MJSSig a BlockItemL
forall a b. (a -> b) -> a -> b
$ CxtS h MJSSig a MultiLocalVarDeclCommonAttrsL
-> CxtS h MJSSig a [SingleLocalVarDeclL]
-> CxtS h MJSSig a MultiLocalVarDeclL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(MultiLocalVarDecl :-<: fs, InjF fs MultiLocalVarDeclL j) =>
CxtS h fs a MultiLocalVarDeclCommonAttrsL
-> CxtS h fs a [SingleLocalVarDeclL] -> CxtS h fs a j
iMultiLocalVarDecl CxtS h MJSSig a MultiLocalVarDeclCommonAttrsL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(EmptyMultiLocalVarDeclCommonAttrs :-<: fs,
 InjF fs MultiLocalVarDeclCommonAttrsL j) =>
CxtS h fs a j
iEmptyMultiLocalVarDeclCommonAttrs (CxtS h MJSSig a SingleLocalVarDeclL
-> CxtS h MJSSig a [SingleLocalVarDeclL]
forall (f :: (* -> *) -> * -> *) l h (a :: * -> *).
(ListF :<: f, Typeable l, HFunctor f) =>
Cxt h f a l -> Cxt h f a [l]
SingletonF' CxtS h MJSSig a SingleLocalVarDeclL
x)
  projF' :: Cxt h (Sum MJSSig :&: p) a BlockItemL
-> Maybe (Cxt h (Sum MJSSig :&: p) a SingleLocalVarDeclL)
projF' x :: Cxt h (Sum MJSSig :&: p) a BlockItemL
x = do
    (MJSCxtA h a p JSStatementL
y :: MJSCxtA h a _ JSStatementL) <- Cxt h (Sum MJSSig :&: p) a BlockItemL
-> Maybe (MJSCxtA h a p JSStatementL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a BlockItemL
x
    (MJSCxtA h a p MultiLocalVarDeclL
z :: MJSCxtA h a _ MultiLocalVarDeclL) <- MJSCxtA h a p JSStatementL
-> Maybe (MJSCxtA h a p MultiLocalVarDeclL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' MJSCxtA h a p JSStatementL
y
    MultiLocalVarDecl _ (SingletonFA' r :: Cxt h (Sum MJSSig :&: p) a SingleLocalVarDeclL
r) <- MJSCxtA h a p MultiLocalVarDeclL
-> Maybe
     (MultiLocalVarDecl (Cxt h (Sum MJSSig :&: p) a) MultiLocalVarDeclL)
forall (f :: (* -> *) -> * -> *) (f' :: (* -> *) -> * -> *)
       (s :: (* -> *) -> * -> *) h (a :: * -> *) i.
(RemA f f', s :<: f') =>
Cxt h f a i -> Maybe (s (Cxt h f a) i)
project' MJSCxtA h a p MultiLocalVarDeclL
z
    Cxt h (Sum MJSSig :&: p) a SingleLocalVarDeclL
-> Maybe (Cxt h (Sum MJSSig :&: p) a SingleLocalVarDeclL)
forall (m :: * -> *) a. Monad m => a -> m a
return Cxt h (Sum MJSSig :&: p) a SingleLocalVarDeclL
r

instance InjF MJSSig AssignL BlockItemL where
  injF :: CxtS h MJSSig a AssignL -> CxtS h MJSSig a BlockItemL
injF x :: CxtS h MJSSig a AssignL
x = CxtS h MJSSig a JSExpressionL
-> CxtS h MJSSig a JSSemiL -> CxtS h MJSSig a BlockItemL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(JSStatement :-<: fs, InjF fs JSStatementL j) =>
CxtS h fs a JSExpressionL -> CxtS h fs a JSSemiL -> CxtS h fs a j
iJSExpressionStatement (CxtS h MJSSig a AssignL -> CxtS h MJSSig a JSExpressionL
forall (fs :: [(* -> *) -> * -> *]) l l' h (a :: * -> *).
InjF fs l l' =>
CxtS h fs a l -> CxtS h fs a l'
injF CxtS h MJSSig a AssignL
x) (CxtS h MJSSig a JSAnnotL -> CxtS h MJSSig a JSSemiL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(JSSemi :-<: fs, InjF fs JSSemiL j) =>
CxtS h fs a JSAnnotL -> CxtS h fs a j
iJSSemi CxtS h MJSSig a JSAnnotL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(JSAnnot :-<: fs, InjF fs JSAnnotL j) =>
CxtS h fs a j
iJSNoAnnot)
  projF' :: Cxt h (Sum MJSSig :&: p) a BlockItemL
-> Maybe (Cxt h (Sum MJSSig :&: p) a AssignL)
projF' x :: Cxt h (Sum MJSSig :&: p) a BlockItemL
x = do
    (MJSCxtA h a p JSStatementL
y :: MJSCxtA _ _ _ JSStatementL) <- Cxt h (Sum MJSSig :&: p) a BlockItemL
-> Maybe (MJSCxtA h a p JSStatementL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a BlockItemL
x
    JSExpressionStatement e :: Cxt h (Sum MJSSig :&: p) a JSExpressionL
e _ <- MJSCxtA h a p JSStatementL
-> Maybe (JSStatement (Cxt h (Sum MJSSig :&: p) a) JSStatementL)
forall (f :: (* -> *) -> * -> *) (f' :: (* -> *) -> * -> *)
       (s :: (* -> *) -> * -> *) h (a :: * -> *) i.
(RemA f f', s :<: f') =>
Cxt h f a i -> Maybe (s (Cxt h f a) i)
project' MJSCxtA h a p JSStatementL
y
    Cxt h (Sum MJSSig :&: p) a JSExpressionL
-> Maybe (Cxt h (Sum MJSSig :&: p) a AssignL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a JSExpressionL
e

instance InjF MJSSig AssignL JSStatementL where
  injF :: CxtS h MJSSig a AssignL -> CxtS h MJSSig a JSStatementL
injF x :: CxtS h MJSSig a AssignL
x = CxtS h MJSSig a JSExpressionL
-> CxtS h MJSSig a JSSemiL -> CxtS h MJSSig a JSStatementL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(JSStatement :-<: fs, InjF fs JSStatementL j) =>
CxtS h fs a JSExpressionL -> CxtS h fs a JSSemiL -> CxtS h fs a j
iJSExpressionStatement (CxtS h MJSSig a AssignL -> CxtS h MJSSig a JSExpressionL
forall (fs :: [(* -> *) -> * -> *]) l l' h (a :: * -> *).
InjF fs l l' =>
CxtS h fs a l -> CxtS h fs a l'
injF CxtS h MJSSig a AssignL
x) (CxtS h MJSSig a JSAnnotL -> CxtS h MJSSig a JSSemiL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(JSSemi :-<: fs, InjF fs JSSemiL j) =>
CxtS h fs a JSAnnotL -> CxtS h fs a j
iJSSemi CxtS h MJSSig a JSAnnotL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(JSAnnot :-<: fs, InjF fs JSAnnotL j) =>
CxtS h fs a j
iJSNoAnnot)
  projF' :: Cxt h (Sum MJSSig :&: p) a JSStatementL
-> Maybe (Cxt h (Sum MJSSig :&: p) a AssignL)
projF' x :: Cxt h (Sum MJSSig :&: p) a JSStatementL
x = do
    JSExpressionStatement e :: Cxt h (Sum MJSSig :&: p) a JSExpressionL
e _ <- Cxt h (Sum MJSSig :&: p) a JSStatementL
-> Maybe (JSStatement (Cxt h (Sum MJSSig :&: p) a) JSStatementL)
forall (f :: (* -> *) -> * -> *) (f' :: (* -> *) -> * -> *)
       (s :: (* -> *) -> * -> *) h (a :: * -> *) i.
(RemA f f', s :<: f') =>
Cxt h f a i -> Maybe (s (Cxt h f a) i)
project' Cxt h (Sum MJSSig :&: p) a JSStatementL
x
    Cxt h (Sum MJSSig :&: p) a JSExpressionL
-> Maybe (Cxt h (Sum MJSSig :&: p) a AssignL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a JSExpressionL
e

instance InjF MJSSig IdentL VarDeclBinderL where
  injF :: CxtS h MJSSig a IdentL -> CxtS h MJSSig a VarDeclBinderL
injF = CxtS h MJSSig a IdentL -> CxtS h MJSSig a VarDeclBinderL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(IdentIsJSExpression :-<: fs, InjF fs JSExpressionL j) =>
CxtS h fs a IdentL -> CxtS h fs a j
iIdentIsJSExpression
  projF' :: Cxt h (Sum MJSSig :&: p) a VarDeclBinderL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
projF' x :: Cxt h (Sum MJSSig :&: p) a VarDeclBinderL
x = do
    (MJSCxtA h a p JSExpressionL
y :: MJSCxtA _ _ _ JSExpressionL) <- Cxt h (Sum MJSSig :&: p) a VarDeclBinderL
-> Maybe (MJSCxtA h a p JSExpressionL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a VarDeclBinderL
x
    MJSCxtA h a p JSExpressionL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' MJSCxtA h a p JSExpressionL
y

instance InjF MJSSig IdentL LhsL where
  injF :: CxtS h MJSSig a IdentL -> CxtS h MJSSig a LhsL
injF x :: CxtS h MJSSig a IdentL
x = CxtS h MJSSig a JSExpressionL -> CxtS h MJSSig a LhsL
forall (fs :: [(* -> *) -> * -> *]) l l' h (a :: * -> *).
InjF fs l l' =>
CxtS h fs a l -> CxtS h fs a l'
injF (CxtS h MJSSig a JSExpressionL -> CxtS h MJSSig a LhsL)
-> CxtS h MJSSig a JSExpressionL -> CxtS h MJSSig a LhsL
forall a b. (a -> b) -> a -> b
$ (CxtS h MJSSig a IdentL -> CxtS h MJSSig a JSExpressionL
forall (fs :: [(* -> *) -> * -> *]) l l' h (a :: * -> *).
InjF fs l l' =>
CxtS h fs a l -> CxtS h fs a l'
injF CxtS h MJSSig a IdentL
x :: MJSCxt _ _ JSExpressionL)

  projF' :: Cxt h (Sum MJSSig :&: p) a LhsL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
projF' x :: Cxt h (Sum MJSSig :&: p) a LhsL
x
   | Just (Cxt h (Sum MJSSig :&: p) a JSExpressionL
y :: MJSCxtA _ _ _ JSExpressionL) <- Cxt h (Sum MJSSig :&: p) a LhsL
-> Maybe (Cxt h (Sum MJSSig :&: p) a JSExpressionL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a LhsL
x
   , Just z :: Cxt h (Sum MJSSig :&: p) a IdentL
z <- Cxt h (Sum MJSSig :&: p) a JSExpressionL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a JSExpressionL
y
   = Cxt h (Sum MJSSig :&: p) a IdentL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
forall a. a -> Maybe a
Just Cxt h (Sum MJSSig :&: p) a IdentL
z
  projF' _ = Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
forall a. Maybe a
Nothing

instance InjF MJSSig IdentL FunctionExpL where
  injF :: CxtS h MJSSig a IdentL -> CxtS h MJSSig a FunctionExpL
injF = CxtS h MJSSig a IdentL -> CxtS h MJSSig a FunctionExpL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(IdentIsJSExpression :-<: fs, InjF fs JSExpressionL j) =>
CxtS h fs a IdentL -> CxtS h fs a j
iIdentIsJSExpression

  projF' :: Cxt h (Sum MJSSig :&: p) a FunctionExpL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
projF' x :: Cxt h (Sum MJSSig :&: p) a FunctionExpL
x = do
    JSExpressionIsFunctionExp e :: Cxt h (Sum MJSSig :&: p) a JSExpressionL
e <- Cxt h (Sum MJSSig :&: p) a FunctionExpL
-> Maybe
     (JSExpressionIsFunctionExp
        (Cxt h (Sum MJSSig :&: p) a) FunctionExpL)
forall (f :: (* -> *) -> * -> *) (f' :: (* -> *) -> * -> *)
       (s :: (* -> *) -> * -> *) h (a :: * -> *) i.
(RemA f f', s :<: f') =>
Cxt h f a i -> Maybe (s (Cxt h f a) i)
project' Cxt h (Sum MJSSig :&: p) a FunctionExpL
x
    Cxt h (Sum MJSSig :&: p) a JSExpressionL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a JSExpressionL
e

instance InjF MJSSig IdentL PositionalArgExpL where
  injF :: CxtS h MJSSig a IdentL -> CxtS h MJSSig a PositionalArgExpL
injF = CxtS h MJSSig a IdentL -> CxtS h MJSSig a PositionalArgExpL
forall h (fs :: [(* -> *) -> * -> *]) (a :: * -> *) j.
(IdentIsJSExpression :-<: fs, InjF fs JSExpressionL j) =>
CxtS h fs a IdentL -> CxtS h fs a j
iIdentIsJSExpression

  projF' :: Cxt h (Sum MJSSig :&: p) a PositionalArgExpL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
projF' x :: Cxt h (Sum MJSSig :&: p) a PositionalArgExpL
x
   | Just (JSExpressionIsPositionalArgExp e :: Cxt h (Sum MJSSig :&: p) a JSExpressionL
e) <- Cxt h (Sum MJSSig :&: p) a PositionalArgExpL
-> Maybe
     (JSExpressionIsPositionalArgExp
        (Cxt h (Sum MJSSig :&: p) a) PositionalArgExpL)
forall (f :: (* -> *) -> * -> *) (f' :: (* -> *) -> * -> *)
       (s :: (* -> *) -> * -> *) h (a :: * -> *) i.
(RemA f f', s :<: f') =>
Cxt h f a i -> Maybe (s (Cxt h f a) i)
project' Cxt h (Sum MJSSig :&: p) a PositionalArgExpL
x = Cxt h (Sum MJSSig :&: p) a JSExpressionL
-> Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
forall (fs :: [(* -> *) -> * -> *]) l l' h p (a :: * -> *).
InjF fs l l' =>
Cxt h (Sum fs :&: p) a l' -> Maybe (Cxt h (Sum fs :&: p) a l)
projF' Cxt h (Sum MJSSig :&: p) a JSExpressionL
e
  projF' _ = Maybe (Cxt h (Sum MJSSig :&: p) a IdentL)
forall a. Maybe a
Nothing

#endif