-- @name Variables -- @version 1.0 -- @authors Robert Tairas -- @date 2007/07/11 -- @description This transformation is based on "variables" commands. module Transform; create OUT : Variables from IN1 : Clones, IN2 : Commands; -- Determine if clone group is included in variables report helper context Clones!CloneGroup def: isIncluded() : Boolean = if Commands!CloneCommand.allInstancesFrom('IN2')->select(e | e.command = #VARIABLES)->collect(e | e.instanceName)->includes(self.cloneName) then true else false endif; helper context Clones!DeclarationStat def: isSimple : Boolean = self.initExp.oclIsUndefined(); helper def: processBox1(t: String): Sequence(OclAny) = Clones!CloneInstance.allInstancesFrom('IN1') ->select(e | e.cloneName.cloneName = t) ->iterate(f; test : Sequence(OclAny) = Sequence{} | test->including( if f.boxes->size() = 0 then Sequence{} else f.boxes ->collect(g | g.statements) ->flatten() ->collect(h | if h.oclIsKindOf(Clones!DeclarationStat) then h.variable.varName + ' (in ' + f.instanceName + ')' else Sequence{} endif ) endif ) ); helper def: processBox2(t: String): Sequence(OclAny) = Clones!CloneInstance.allInstancesFrom('IN1') ->select(e | e.cloneName.cloneName = t) ->iterate(f; test : Sequence(OclAny) = Sequence{} | test->including( if f.boxes->size() = 0 then Sequence{} else f.boxes ->collect(h | h.statements) ->flatten() ->collect(i | if i.oclIsKindOf(Clones!AssignStat) then if f.boxes ->collect(j | j.statements) ->flatten() ->select(k | k.oclIsKindOf(Clones!DeclarationStat)) ->collect(l | l.variable.varName) ->includes(i.variable.varName) then Sequence{} else if Clones!CloneGroup.allInstancesFrom('IN1') ->select(m | m.cloneName = t) ->collect(n | n.statements) ->first() ->select(o | o.oclIsKindOf(Clones!DeclarationStat)) ->collect(p | p.variable.varName) ->includes(i.variable.varName) then Sequence{} else i.variable.varName + ' (in ' + f.instanceName + ')' endif endif else Sequence{} endif ) endif ) ); helper def: processBox3(t: String): Sequence(OclAny) = Clones!CloneInstance.allInstancesFrom('IN1') ->select(e | e.cloneName.cloneName = t) ->iterate(f; test : Sequence(OclAny) = Sequence{} | test->including( if f.boxes->size() = 0 then Sequence{} else f.boxes ->collect(h | h.statements) ->flatten() ->collect(i | if i.oclIsKindOf(Clones!AssignStat) then thisModule.processExp2(i.initExp, Clones!CloneGroup.allInstancesFrom('IN1')->select(e | e.cloneName = t)->first(), f) else if i.oclIsKindOf(Clones!DeclarationStat) then if i.isSimple then Sequence{} else thisModule.processExp2(i.initExp, Clones!CloneGroup.allInstancesFrom('IN1')->select(e | e.cloneName = t)->first(), f) endif else Sequence{} endif endif ) endif ) ); helper def: processExp(t: Clones!Expression, u: Clones!CloneGroup): Sequence(OclAny) = if t.oclIsKindOf(Clones!IntegerExp) then Sequence{} else if t.oclIsKindOf(Clones!VariableExp) then if u.statements->select(f | f.oclIsKindOf(Clones!DeclarationStat))->collect(g | g.variable.varName)->includes(t.value.varName) then Sequence{} else if u.statements->select(f | f.oclIsKindOf(Clones!AssignStat))->collect(g | g.variable.varName)->includes(t.value.varName) then Sequence{} else t.value.varName endif endif else if t.oclIsKindOf(Clones!UnaryOperatorCallExp) then thisModule.processExp(t.operand, u) else if t.oclIsKindOf(Clones!BinaryOperatorCallExp) then Sequence { thisModule.processExp(t.left, u), thisModule.processExp(t.right, u) } else Sequence{} endif endif endif endif; helper def: processExp2(t: Clones!Expression, u: Clones!CloneGroup, s: Clones!CloneInstance): Sequence(OclAny) = if t.oclIsKindOf(Clones!IntegerExp) then Sequence{} else if t.oclIsKindOf(Clones!VariableExp) then if u.statements->select(f | f.oclIsKindOf(Clones!DeclarationStat))->collect(g | g.variable.varName)->includes(t.value.varName) then Sequence{} else if u.statements->select(f | f.oclIsKindOf(Clones!AssignStat))->collect(g | g.variable.varName)->includes(t.value.varName) then Sequence{} else if s.boxes ->collect(j | j.statements) ->flatten() ->select(k | k.oclIsKindOf(Clones!DeclarationStat)) ->collect(l | l.variable.varName) ->includes(t.value.varName) then Sequence{} else if s.boxes ->collect(j | j.statements) ->flatten() ->select(k | k.oclIsKindOf(Clones!DeclarationStat)) ->collect(l | l.variable.varName) ->includes(t.value.varName) then Sequence{} else t.value.varName + ' (in ' + s.instanceName + ')' endif endif endif endif else if t.oclIsKindOf(Clones!UnaryOperatorCallExp) then thisModule.processExp2(t.operand, u, s) else if t.oclIsKindOf(Clones!BinaryOperatorCallExp) then Sequence { thisModule.processExp2(t.left, u, s), thisModule.processExp2(t.right, u, s) } else Sequence{} endif endif endif endif; -- Process all "variables" commmands rule Root { from s : Clones!Root to t : Variables!Root ( cloneGroup <- s.cloneGroup ) } rule CloneGroup { from s : Clones!CloneGroup (s.isIncluded()) to t : Variables!CloneGroup ( cloneName <- s.cloneName, declaredVar <- thisModule.DeclaredVar(s), assignedVar <- thisModule.AssignedVar(s), nonAssignedVar <- thisModule.NonAssignedVar(s) ) } lazy rule DeclaredVar { from s : Clones!CloneGroup to t : Variables!DeclaredVar ( variables <- Sequence { s.statements->collect(e | if e.oclIsKindOf(Clones!DeclarationStat) then e.variable.varName else Sequence{} endif ) , thisModule.processBox1(s.cloneName) } ) } lazy rule AssignedVar { from s : Clones!CloneGroup to t : Variables!AssignedVar ( variables <- Sequence { s.statements->collect(e | if e.oclIsKindOf(Clones!AssignStat) then if s.statements->select(f | f.oclIsKindOf(Clones!DeclarationStat))->collect(g | g.variable.varName)->includes(e.variable.varName) then Sequence{} else e.variable.varName endif else Sequence{} endif ), thisModule.processBox2(s.cloneName) } ) } lazy rule NonAssignedVar { from s : Clones!CloneGroup to t : Variables!NonAssignedVar ( variables <- Sequence { s.statements->collect(e | if e.oclIsKindOf(Clones!AssignStat) then thisModule.processExp(e.initExp, s) else if e.oclIsKindOf(Clones!DeclarationStat) then if e.isSimple then Sequence{} else thisModule.processExp(e.initExp, s) endif else Sequence{} endif endif ), thisModule.processBox3(s.cloneName) } ) }