paragon-0.1.3: src/Language/Java/Paragon/Compile.hs
{-# LANGUAGE QuasiQuotes #-}
module Language.Java.Paragon.Compile where
import Language.Java.Paragon.Syntax
import Language.Java.Paragon.QuasiQuoter
import Language.Java.Paragon.TypeCheck.TcEnv
import Data.Generics.Uniplate.Data
import Control.Applicative
import Language.Java.Paragon.TypeCheck.Monad
import qualified Data.Map as Map
-- shouldn't we add 'final' modifier to the actor fields?
-- what about other declarations using primtype of policy and actor? not in method-body, not in class
-- should be called for one class/interface only
compileTransform :: CompilationUnit -> CompilationUnit
compileTransform cu = foldl (.) id [transformBi removePolicyDecls
, transformBi removeParagonModifiers
, transformBi removePolicyDecls
, transformBi removeLocalPolicyDecls
, transformBi removePolicyExpressions
, transformBi removeParagonTypeParams
, transformBi removeParagonNWTypeArguments
, transformBi removeParagonTypeArguments
, transformBi translateTypemethodModifier
, transformBi translateFieldActorDecl
, transformBi translateLocalActorDecl
, transformBi translateLockDecl
, transformBi translateLockExp
, transformBi translateLockStmt
, transformBi translateLockBlockStmt
, transformBi translateLocalLockDecl
] cu
---
translateTypemethodModifier :: Modifier -> Modifier
translateTypemethodModifier Typemethod = Static
translateTypemethodModifier x = x
isParagonModifier :: Modifier -> Bool
isParagonModifier m = case m of
Reflexive -> True
Transitive -> True
Commutative -> True
Reads _ -> True
Writes _ -> True
Opens _ -> True
Closes _ -> True
Expects _ -> True
_ -> False
---
removeParagonModifiers :: [Modifier] -> [Modifier]
removeParagonModifiers mods = filter (not.isParagonModifier) mods
---
removePolicyDecls :: [MemberDecl] -> [MemberDecl]
removePolicyDecls membs = [m | m <- membs,
not $ case m of
PolicyDecl _ _ _ -> True
FieldDecl _ (PrimType PolicyT) _ -> True
_ -> False
]
---
removeLocalPolicyDecls :: [BlockStmt] -> [BlockStmt]
removeLocalPolicyDecls bstms
= [ b | b <- bstms,
not $ case b of
LocalPolicy _ _ _ -> True
LocalVars _ (PrimType PolicyT) _ -> True
_ -> False ]
---
removePolicyExpressions :: [Exp] -> [Exp]
removePolicyExpressions es = [ e | e <- es,
not $ case e of
PolicyExp _ -> True
_ -> False
]
---
translateFieldActorDecl :: MemberDecl -> MemberDecl
translateFieldActorDecl (FieldDecl mods [typeQQ|actor|] varDecls)
= FieldDecl mods [typeQQ|Actor|] (translateVarDecl<$>varDecls)
translateFieldActorDecl x = x
---
translateLocalActorDecl :: BlockStmt -> BlockStmt
translateLocalActorDecl (LocalVars mods [typeQQ|actor|] varDecls )
= LocalVars mods [typeQQ|Actor|] (translateVarDecl<$>varDecls)
translateLocalActorDecl x = x
translateVarDecl :: VarDecl -> VarDecl
translateVarDecl (VarDecl i Nothing)
= VarDecl i ( Just $ InitExp [expQQ|ActorFactory.generate()|] )
translateVarDecl x = x
---
translateLockDecl :: MemberDecl -> MemberDecl
translateLockDecl (LockDecl mods iden maybeIdents maybeLockprops)
= (FieldDecl mods [typeQQ|Lock|] [ VarDecl (VarId iden) (Just$ InitExp [expQQ|new Lock()|])]) -- Lock iden=new Lock();
-- I chose a new class named Lock to represent the lock type, because the contain/elem has special meaning
translateLockDecl x = x
---
translateLockExp :: Exp -> Exp
translateLockExp (LockExp (Lock (Name idnts) paramNames))
= (MethodInv (MethodCall (Name (idnts++[Ident "check"])) (ExpName . aNameToName <$>paramNames) ))
-- ex:l.check(a,b,c)
translateLockExp x = x
aNameToName :: ActorName -> Name
aNameToName (ActorName n) = n
aNameToName (ActorTypeVar i) = Name [i]
---
translateLockStmt :: Stmt -> Stmt
translateLockStmt (Open (Lock (Name idnts) paramNames))
= ExpStmt (MethodInv (MethodCall (Name (idnts++ [Ident "allow"])) (ExpName . aNameToName <$>paramNames)))
-- l.allow(a,b,c)
-- what about empty open? ex: open l;
translateLockStmt (Close (Lock (Name idnts) paramNames))
= ExpStmt (MethodInv (MethodCall (Name (idnts++ [Ident "disAllow"])) (ExpName . aNameToName <$>paramNames)))
-- l.disAllow(a,b,c)
-- what about empty close? ex: close l;
translateLockStmt x = x
---
-- Should be called before translate lock Stmts
translateLockBlockStmt :: Stmt -> Stmt
translateLockBlockStmt (OpenBlock l b@(Block bstmts))
= IfThenElse (LockExp l)
(StmtBlock b)
(StmtBlock (Block( [ BlockStmt (Open l)]
++ bstmts
++ [ BlockStmt (Close l)])))
translateLockBlockStmt x = x
-- if (L) { b} else {open l; b ; close l}
--translateLockStmt (CloseBlock l b) = undefined not implemented yet
---
translateLocalLockDecl :: BlockStmt -> BlockStmt
translateLocalLockDecl (LocalLock mods iden maybeIdents maybeLockprops)
= (LocalVars mods [typeQQ|Lock|] [ VarDecl (VarId iden) (Just$InitExp [expQQ|new Lock()|])]) -- Lock iden=new Lock();
translateLocalLockDecl x = x
-----
removeParagonTypeParams :: [TypeParam] -> [TypeParam]
removeParagonTypeParams tps = [tp | tp@(TypeParam _ _)<-tps]
removeParagonNWTypeArguments :: [NonWildTypeArgument] -> [NonWildTypeArgument]
removeParagonNWTypeArguments tas = [ ta | ta @ ActualType {} <- tas ]
removeParagonTypeArguments :: [TypeArgument] -> [TypeArgument]
removeParagonTypeArguments [] = []
removeParagonTypeArguments (a@(ActualArg (ActualType {})) : as) = a : removeParagonTypeArguments as
removeParagonTypeArguments (ActualArg _ : as) = removeParagonTypeArguments as
removeParagonTypeArguments (a:as) = a : removeParagonTypeArguments as
{-- not supported
translateConstructorTypeArguments :: TypeMap -> ExplConstrInv -> ExplConstrInv
translateConstructorTypeArguments env (ThisInvoke targs args)
= ThisInvoke (translateTypeArguments undefined targs) args
translateConstructorTypeArguments env (SuperInvoke targs args)
= SuperInvoke (translateTypeArguments undefined targs) args
translateConstructorTypeArguments env (PrimarySuperInvoke e targs args)
=PrimarySuperInvoke e (translateTypeArguments undefined targs) args
translateConstructorTypeArguments _ x = x
-}
{-- some are not supported
translateMethodCallTypeArguments :: TypeMap -> MethodInvocation -> MethodInvocation
--translateMethodCallTypeArguments env (PrimaryMethodCall e tnargs iden args)=(PrimaryMethodCall e (translateTypeArguments undefined tnargs) iden args)
--translateMethodCallTypeArguments env (SuperMethodCall tnargs iden args) =(SuperMethodCall (translateTypeArguments undefined tnargs) iden args)
--translateMethodCallTypeArguments env (ClassMethodCall n tnargs iden args) =(ClassMethodCall n (translateTypeArguments undefined tnargs) iden args)
translateMethodCallTypeArguments env (TypeMethodCall n tnargs iden args)
= {-let nameOfType (ClassType iargs) = Name $ map fst iargs
(_,tm) = lookupNamed types (nameOfType ctype) env
(tps, cti) = Map.lookup pTys (constrs tm)
in -} TypeMethodCall n (translateTypeArguments undefined tnargs) iden args
translateMethodCallTypeArguments env x = x
---
translateInstanceTypeArguments :: TypeMap -> Exp -> Exp
translateInstanceTypeArguments env (InstanceCreation targs ctype args mb)
= let pTys = [ fromSrcType env t | FormalParam _ms t _ <- args ]
nameOfType (ClassType iargs) = Name $ map fst iargs
(_,tm) = lookupNamed types (nameOfType ctype) env
(tps, cti) = Map.lookup pTys (constrs tm)
in InstanceCreation (translateTypeArguments tps targs) ctype args mb
--translateInstanceTypeArguments env (QualInstanceCreation e targs iden args mb)
-- = QualInstanceCreation e (translateTypeArguments undefined targs) iden args mb
translateInstanceTypeArguments _ x = x
---
translateParagonTypeArguments :: TypeMap -> ClassType -> ClassType
translateParagonTypeArguments env (ClassType iargs) =
let (is, as) = unzip iargs in
case lookupNamed types (Name is) env of
Just (tps,tm) -> let args = map (translateTypeArguments tps) as
in ClassType $ zip is args
translateParagonTypeArguments _ x = x
-- length of parameter1 and 2 should be the same
-}