HaRe-0.6: StrategyLib-4.0-beta/examples/joos-rule02/Instance.hs
module Instance where
import Prelude
import Monad
import Control.Monad.Identity
import Data.List
import StrategyLib
import Datatypes
import DatatypesTermInstances
-- Datatype for types of relevant JOOS identifiers
data TypeJoos = ExprType Type
-- not needed for the present refactorings
| MethodType (Maybe Type) Formals
-- Declared names (with type)
declaredJoos :: TU [(Identifier,TypeJoos)] Identity
declaredJoos = adhocTU (adhocTU (constTU [])
(Identity . declaredBlock))
(Identity . declaredMeth)
where
declaredBlock (Block vds _)
= map (\(VarDecl t i) -> (i,ExprType t)) vds
declaredMeth (MethodDecl r i f@(Formals fps) _)
= map (\(Formal t i) -> (i,ExprType t)) fps
-- Defined names (without type)
definedJoos :: TU [Identifier] Identity
definedJoos = adhocTU (constTU []) (Identity . definedAssignment)
where
definedAssignment (Assignment i _) = [i]
-- Used names (without type)
usedJoos :: TU [Identifier] Identity
usedJoos = adhocTU (adhocTU (constTU [])
(Identity . usedExpression))
(Identity . usedInvocation)
where
-- needed for extract
usedExpression (Identifier i) = [i]
usedExpression _ = []
-- needed for eliminate but not for introduce and extract
usedInvocation (ExpressionInvocation _ i _) = [i]
usedInvocation (SuperInvocation i _) = [i]
-- Referenced names (without type)
referencedJoos :: TU [Identifier] Identity
referencedJoos = op2TU (++) definedJoos usedJoos
-- Method abstractions as needed for method extraction
instance Abstraction
MethodDecl -- abstr
Identifier -- name
TypeJoos -- tpe
Statement -- apply
where
getAbstrName (MethodDecl _ i _ _) = Just i
getAbstrParas (MethodDecl _ _ (Formals fps) _) =
Just (map (\(Formal t i) -> (i,ExprType t)) fps)
getAbstrBody (MethodDecl _ _ _ b) = Just (BlockStat b)
getApplyName (MethodInvocationStat
(ExpressionInvocation This n _)) = Just n
getApplyParas = undefined
constrAbstr n l a =
maybe Nothing
(\fps -> Just (MethodDecl Nothing n (Formals fps) (toBlock a)))
(mapM toFormal l)
where
toBlock a = Block [] [a]
toFormal (i,tpe) = case tpe of
ExprType t -> Just (Formal t i)
_ -> Nothing
constrApply n l =
maybe Nothing
(\aps -> Just (MethodInvocationStat
(ExpressionInvocation This n (Arguments aps))))
(mapM toActual l)
where
toActual (i,tpe) = case tpe of
ExprType _ -> Just (Identifier i)
_ -> Nothing
-- Focus on statements
wrapStatement = StatementFocus
unwrapStatement (StatementFocus x) = Just x
unwrapStatement _ = Nothing
-- Focus on a list of method declarations
wrapMethods xs = [MethodDeclFocus xs]
unwrapMethods [MethodDeclFocus xs] = Just xs
unwrapMethods _ = Nothing
-- Focus on a single method declaration
wrapMethod x = MethodDeclFocus [x]
unwrapMethod (MethodDeclFocus [x]) = Just x
unwrapMethod _ = Nothing
-- Type of transformation on JOOS programs
type TrafoJoos = Program -> Maybe Program
-- Introduction of a method declaration
introduceJoos :: MethodDecl -> TrafoJoos
introduceJoos = introduce declaredJoos referencedJoos unwrapMethods
-- Extraction of a statement to constitute a new method declaration
extractJoos :: Identifier -> TrafoJoos
extractJoos = extract
declaredJoos
referencedJoos
unwrapStatement
wrapMethods
unwrapMethods
check
where
check _ f = and [noReturns f, noFrees f]
noReturns = maybe True (const False) .
applyTU (once_tdTU (adhocTU failTU
(\s -> case s of
ReturnStat _ -> Just ()
_ -> Nothing)))
noFrees = (==) [] . freeNames declaredJoos definedJoos
-- Elimination of JOOS method declarations
eliminateJoos :: TrafoJoos
eliminateJoos = eliminate declaredJoos referencedJoos unwrapMethod