packages feed

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

-}