blob: 74a38c75278e03c0d3c24ff9013c26d21742bf79 [file] [log] [blame]
-- @atlcompiler emftvm
-- @path ATL=/org.eclipse.m2m.atl.common/model/ATL.ecore
-- @path Problem=/org.eclipse.m2m.atl.common/model/Problem.ecore
module ATLWFR;
create OUT : Problem from IN : ATL;
-------------------------------------------------------------------------------
-- HELPERS --------------------------------------------------------------------
-------------------------------------------------------------------------------
-- This helper provides a set containing the name of the IteratorExp elements
-- that accepts a single Iterator.
-- CONTEXT: thisModule
-- RETURN: Set(String)
helper def: singleIteratorExps : Set(String) =
Set{
'isUnique', 'any', 'one', 'collect', 'select',
'reject', 'collectNested', 'sortedBy'
};
-- This helper provides a set containing the name of the IteratorExp elements
-- for which several Iterators may be declared according to the OCL spec.
-- CONTEXT: thisModule
-- RETURN: Set(String)
helper def: multiIteratorExps : Set(String) = Set{'exists', 'forAll'};
-- This helper computes the set of existing CollectionType elements within the
-- input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Set(ATL!CollectionType)
helper def: collectionTypes : Set(ATL!CollectionType) =
ATL!CollectionType.allInstances();
-- This helper computes a sequence containing all the OclModel elements that
-- are used in the input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!OclModel)
helper def: allModels : Set(ATL!OclModel) =
let atlModules : Sequence(ATL!Module) =
ATL!Module.allInstances()
in
if atlModules->notEmpty() then
atlModules->iterate(m; acc : Set(ATL!OclModel) = Set{} |
acc->union(m.inModels->asSet())->union(m.outModels->asSet()))
else
Set{}
endif;
-- This helper computes the Query element that corresponds to the input ATL
-- Unit. If the input ATL Unit corresponds to a Module (eg a transformation),
-- the computed value is OclUndefined.
-- CONTEXT: thisModule
-- RETURN: ATL!Query
helper def: queryElt : ATL!Query =
let atlQueries : Sequence(ATL!Query) = ATL!Query.allInstances() in
if atlQueries->isEmpty() then OclUndefined else atlQueries->first() endif;
-- This helper computes a sequence containing all the Binding elements that
-- are defined in the input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!Binding)
helper def: allBindings : Sequence(ATL!Binding) =
ATL!Binding.allInstances()->asSequence();
-- This helper computes a sequence containing all the Pattern elements that
-- are defined in the input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!InPattern)
helper def: allInPatterns : Sequence(ATL!InPattern) =
ATL!InPattern.allInstances()->asSequence();
-- This helper computes a sequence containing all the InPatternElement elements
-- that are defined in the input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!InPatternElement)
helper def: allInPatternElts : Sequence(ATL!InPatternElement) =
ATL!InPatternElement.allInstances()->asSequence();
-- This helper computes a sequence containing all the OutPatternElement
-- elements that are defined in the input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!OutPatternElement)
helper def: allOutPatternElts : Sequence(ATL!OutPatternElement) =
ATL!OutPatternElement.allInstances()->asSequence();
-- This helper computes a sequence containing all the Rule elements that are
-- defined in the input ATL Unit. If the input Unit is a query, the computed
-- sequence is empty.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!Rule)
helper def: allRules : Sequence(ATL!Rule) =
ATL!Rule.allInstances()->asSequence();
-- This helper computes a sequence containing all the Helper elements that are
-- defined in the input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!Helper)
helper def: allHelpers : Sequence(ATL!Helper) =
ATL!Helper.allInstances()->asSequence();
-- This helper computes a sequence containing all the LoopExp elements that are
-- defined in the input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!LoopExp)
helper def: allLoopExps : Sequence(ATL!LoopExp) =
ATL!LoopExp.allInstances()->asSequence();
-- This helper computes a sequence containing all the IterateExp elements that
-- are defined in the input ATL Unit.
-- CONTEXT: thisModule
-- RETURN: Sequence(ATL!IterateExp)
helper def: allIterateExps : Sequence(ATL!IterateExp) =
ATL!IterateExp.allInstances()->asSequence();
-- This helper computes a sequence containing all the VariableDeclaration
-- elements that are associated with the contextual Rule. These declarations
-- can be of 3 different kinds:
-- * the variables declared for the rule;
-- * the OutPatternElements of the rule;
-- * the InPatternElements of the rule if this last is a MatchedRule.
-- CONTEXT: ATL!Rule
-- RETURN: Sequence(ATL!VariableDeclaration)
helper context ATL!Rule
def: namedElements : Sequence(ATL!VariableDeclaration) =
Sequence{
if self.oclIsTypeOf(ATL!MatchedRule)
then
if not self.inPattern.oclIsUndefined() then
self.inPattern.elements->asSequence()
else
Sequence{}
endif
else
Sequence{}
endif,
self.variables->asSequence(),
if not self.outPattern.oclIsUndefined() then
self.outPattern.elements->asSequence()
else
Sequence{}
endif
}->flatten();
-- This helper computes the Rule element in which the contextual PatterElement
-- is declared. This is achieved by returning the Rule referred by the "rule"
-- reference of the Pattern that conatins the contexual PatternElement. This
-- last one is accessed through the "outPattern" reference if the contextual
-- PatternElement is an OutPatternElement, throught the "inPattern" if it is
-- an InPatternElement.
-- CONTEXT: ATL!PatternElement
-- RETURN: ATL!Rule
helper context ATL!PatternElement def: "rule" : ATL!Rule =
if self.oclIsKindOf(ATL!OutPatternElement)
then
self.outPattern."rule"
else
self.inPattern."rule"
endif;
-- This helper computes a sequence containing the VariableDeclarations that
-- precede the contextual VariableDeclaration in its namespace.
-- If the contextual VariableDeclaration is a PatternElement, the helper only
-- returns this VD.
-- Otherwise, it computes the container of the contextual VD. If the container
-- is a LetExp, it returns a Sequence composed of the VD, and the results of
-- the calls of the getUpD helper on the calculated container.
-- If the container is an IteratorExp, the helper returns a Sequence composed
-- of the VD and the results of the call of getUpD on the computed container.
-- If the container is an IterateExp, the helper a Sequence containing the same
-- elements that the one computed for an IteratorExp.
-- Otherwise, the helper returns the only contextual VD as default value.
-- CONTEXT: ATL!VariableDeclaration
-- RETURN: Sequence(ATL!VariableDeclaration)
helper context ATL!VariableDeclaration
def: getDeclarations() : Sequence(ATL!VariableDeclaration) =
if self.oclIsKindOf(ATL!PatternElement)
then
Sequence{self}
else
let container : OclAny = self.refImmediateComposite() in
if container.oclIsTypeOf(ATL!LetExp)
then
Sequence{
self,
container.getUpD()
}->flatten()
else
if container.oclIsTypeOf(ATL!IteratorExp)
then
Sequence{
self,
container.getUpD()
}->flatten()
else
if container.oclIsTypeOf(ATL!IterateExp)
then
Sequence{
self,
container.getUpD()
}->flatten()
else
Sequence{
self
}->flatten()
endif
endif
endif
endif;
-- This helper computes a sequence containing the VariableDeclarations that are
-- defined higher than the contextual OclExpression in its namespace tree.
-- The helper first computes the container of the contextual OclExp. If this
-- container is undefined, it retuns an empty sequence.
-- Otherwise, if this container is not an OclExpression:
-- * If the container is a RuleVariableDeclaration, the helper returns a
-- sequence containing all the named elements of the rule that contains this
-- InPattern.
-- * If the container is a Binding, the helper returns a sequence containing
-- all the named elements of the rule that contains this Binding.
-- Otherwise, if the computed container is an OclExpression:
-- * If the container is a LetExp, the helper returns a sequence composed of
-- the LetExp variable and the result of its recursive call on the LetExp.
-- * If the container is an IfExp, the helper returns a sequence composed of
-- the result of its recursive call on the IfExp.
-- * If the container is an IteratorExp, if the contextual OclExp is the
-- source of the IteratorExp then the helper returns the result of its
-- recursive call on the IteratorExp, else it returns this result with the
-- "iterators" elements of the IteratorExp.
-- * If the container is an IterateExp, the helper returns the same sequences
-- that for an IteratorExp, with the additional "result" element in case the
-- contextual OclExp is not the source of the IterateExp.
-- Otherwise, the helper returns an empty sequence as default value.
-- CONTEXT: ATL!OclExpression
-- RETURN: Sequence(ATL!VariableDeclaration)
helper context ATL!OclExpression
def: getUpD() : Sequence(ATL!VariableDeclaration) =
let container : ATL!Element = self.refImmediateComposite() in
if container.oclIsUndefined() then
Sequence{}
else if not container.oclIsKindOf(ATL!OclExpression) then
if container.oclIsTypeOf(ATL!RuleVariableDeclaration)
then
Sequence{
container."rule".namedElements
}->flatten()
else
if container.oclIsTypeOf(ATL!Binding)
then
Sequence{
container.outPatternElement."rule".namedElements
}->flatten()
else
Sequence{}
endif
endif
else if container.oclIsTypeOf(ATL!LetExp) then
Sequence{
container.variable,
container.getUpD()
}->flatten()
else if container.oclIsTypeOf(ATL!IfExp) then
Sequence{
container.getUpD()
}->flatten()
else if container.oclIsTypeOf(ATL!IteratorExp) then
if container.source = self
then
Sequence{
container.getUpD()
}->flatten()
else
Sequence{
container.iterators,
container.getUpD()
}->flatten()
endif
else if container.oclIsTypeOf(ATL!IterateExp) then
if container.source = self
then
Sequence{
container.getUpD()
}->flatten()
else
Sequence{
container.iterators,
container.result,
container.getUpD()
}->flatten()
endif
else Sequence{}
endif endif endif endif endif endif;
-- This helper computes a sequence containing the VariableDeclarations that are
-- defined lower than the contextual OclExpression in its namespace tree.
-- If the contextual OclExpression is a LetExp, the helper returns a sequence
-- composed of the LetExp variable and the result of its recursive call on the
-- "in_" reference of the LetExp.
-- Otherwise, if the contextual OclExpression is a IfExp, the helper returns a
-- sequence composed of the results of its recursive calls on the "condition",
-- "thenExpression" and "elseExpression" references of the IfExp.
-- Otherwise, if the contextual OclExpression is an IteratorExp, the helper
-- returns a sequence composed of the IteratorExp iterators along with the
-- results of its recursive calls on the "source" and the "body" references
-- of the IteratorExp.
-- Otherwise, if the contextual OclExpression is an IterateExp, the helper
-- returns the sequence returned for an IteratorExp with its additional result
-- element.
-- Otherwise, the helper returns an empty sequence as default value.
-- CONTEXT: ATL!OclExpression
-- RETURN: Sequence(ATL!VariableDeclaration)
--helper context ATL!OclExpression
-- def: getDownD() : Sequence(ATL!VariableDeclaration) =
-- if self.oclIsTypeOf(ATL!LetExp) then
-- Sequence{
-- self.variable,
-- self.in_.getDownD()
-- }->flatten()
-- else if self.oclIsTypeOf(ATL!IfExp) then
-- Sequence{
-- self.condition.getDownD(),
-- self.thenExpression.getDownD(),
-- self.elseExpression.getDownD()
-- }->flatten()
-- else if self.oclIsTypeOf(ATL!IteratorExp) then
-- Sequence{
-- self.iterators,
-- self.source.getDownD(),
-- self.body.getDownD()
-- }->flatten()
-- else if self.oclIsTypeOf(ATL!IterateExp) then
-- Sequence{
-- self.iterators,
-- self.result,
-- self.source.getDownD(),
-- self.body.getDownD()
-- }->flatten()
-- else Sequence{}
-- endif endif endif endif;
-- This helper returns the root composite (container) of the contextual
-- OclExpression. For this purpose, the helper first computes the immediate
-- composite of the contextual OclExpression.
-- If this container is undefined, the helper returns OclUndefined.
-- Otherwise, if it is a kind of OclExpression, the helper returns the value
-- provided by its recursive call on the computed container.
-- Finally, if this container is not an OclExpression, the root composite has
-- been reached (Binding/InPattern/Operation/Query/Attribute) and is returned.
-- CONTEXT: ATL!LocatedElement
-- RETURN: OclAny
helper context ATL!LocatedElement def: getRootComposite() : OclAny =
let container : OclAny = self.refImmediateComposite()
in
if container.oclIsUndefined()
then
OclUndefined
else
if container.oclIsKindOf(ATL!OclExpression) or
container.oclIsKindOf(ATL!Statement) or
container.oclIsKindOf(ATL!VariableDeclaration)
then
container.getRootComposite()
else
container
endif
endif;
-- These helpers check for value equality of OclTypes.
-- The base case evaluates to "false", and covers the case of
-- comparing to OclUndefined.
-- CONTEXT: ATL!OclType
-- RETURN: Boolean
helper context ATL!"OclType" def: equals(o : OclAny) : Boolean =
false;
helper context ATL!"OclType" def: equals(o : ATL!"OclType") : Boolean =
self.name = o.name and self.oclType() = o.oclType();
helper context ATL!OclModelElement def: equals(o : ATL!OclModelElement) : Boolean =
super.equals(o) and
self.model.equals(o.model);
-- These helpers check for value equality of OclModels.
-- The base case evaluates to "false", and covers the case of
-- comparing to OclUndefined.
-- CONTEXT: ATL!OclModel
-- RETURN: Boolean
helper context ATL!OclModel def: equals(o : OclAny) : Boolean =
false;
helper context ATL!OclModel def: equals(o : ATL!OclModel) : Boolean =
self.name = o.name;
--- Returns 'true' if all types in the sequence are equal to the types in 'os'.
helper context Sequence(ATL!"OclType") def: allTypesEquals(os : Sequence(ATL!"OclType")) : Boolean =
if self->isEmpty() then
os->isEmpty()
else if os->isEmpty() then
self->isEmpty()
else
let s : ATL!"OclType" = self->first() in
let o : ATL!"OclType" = os->first() in
s.equals(o) and
self->subSequence(2, self->size()).allTypesEquals(os->subSequence(2, os->size()))
endif endif;
-------------------------------------------------------------------------------
-- RULES ----------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Rule 'FreeVariableIsSelfOrThisModule'
-- This rule generates an 'error' Problem for each VariableDeclaration that has
-- no composite, and whose name is different from both 'self' and 'thisModule'.
-- The VariableExps that have not been previously declared in an ATL file are
-- associated with a new VariableDeclaration without any composite in the
-- correspoding ATL model.
nodefault rule FreeVariableIsSelfOrThisModule {
from
s : ATL!VariableDeclaration (
s.refImmediateComposite().oclIsUndefined() and
s.varName <> 'self' and s.varName <> 'thisModule'
)
to
t : Problem!Problem (
severity <- #error,
location <-
if s.variableExp->isEmpty()
then
s.location
else
s.variableExp->first().location
endif,
description <- 'variable \'' + s.varName + '\' undefined'
)
}
-- Rule 'ModelNameIsUnique'
-- This rule generates an 'error' Problem when there exists models that have
-- the same name that the checked model.
nodefault rule ModelNameIsUnique {
from
s : ATL!OclModel (
thisModule.allModels->exists(e | e.name = s.name and e <> s)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'model \'' + s.name + '\' already defined'
)
}
-- Rule 'RuleNameIsUnique'
-- This rule generates an 'error' Problem when there exists rules that have
-- the same name that the checked rule.
nodefault rule RuleNameIsUnique {
from
s : ATL!Rule (
thisModule.allRules->exists(e | e.name = s.name and e <> s)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'rule \'' + s.name + '\' already defined'
)
}
-- Rule 'HelperSignatureIsUnique'
-- This rule generates an 'error' Problem when there exists helpers that have
-- the same signature that the checked helper.
-- Note that in current implementation, the helper signature corresponds to the
-- name and the context of the helper.
nodefault rule HelperSignatureIsUnique {
from
s : ATL!Helper (
thisModule.allHelpers
->exists(e | e <> s
and
-- name check
s.definition.feature.name = e.definition.feature.name
and
-- helper type check
s.definition.feature.oclType() = e.definition.feature.oclType()
and
-- context check
(
if not s.definition.context_.oclIsUndefined()
then
if not e.definition.context_.oclIsUndefined()
then
s.definition.context_.context_.equals(e.definition.context_.context_)
and
if s.definition.feature.oclIsTypeOf(ATL!Operation) and e.definition.feature.oclIsTypeOf(ATL!Operation)
then
-- parameters check
if not s.definition.feature.parameters.oclIsUndefined()
then
if not e.definition.feature.parameters.oclIsUndefined()
then
if s.definition.feature.parameters.size() = e.definition.feature.parameters.size()
then
s.definition.feature.parameters -> collect(param | param.type) -> allTypesEquals(
e.definition.feature.parameters -> collect(param | param.type)
)
else
false
endif
else
false
endif
else
false
endif
else
true
endif
else
false
endif
else
e.definition.context_.oclIsUndefined()
endif
)
)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'helper \'' + s.definition.feature.name
+ '\' already defined'
)
}
-- DISABLED
---- Rule 'BindingNameIsUniqueInPattern'
---- This rule generates an 'error' Problem when there exists, in a same pattern,
---- bindings that have the same name that the checked binding.
--rule BindingNameIsUniqueInPattern {
-- from
-- s : ATL!Binding (
-- s.outPatternElement.bindings
-- ->exists(e | e.propertyName = s.propertyName and e <> s)
-- )
-- to
-- t : Problem!Problem (
-- severity <- #error,
-- location <- s.location,
-- description <-
-- 'binding \'' + s.propertyName + '\' already defined in pattern'
-- )
--}
-- Rule 'PatternNameIsUniqueInRule'
-- This rule generates an 'error' Problem when there exists, in a same rule,
-- some named elements (InPatternElement/OutPatternElement/
-- RuleVariableDeclaration) that have the same name that the checked pattern.
nodefault rule PatternNameIsUniqueInRule {
from
s : ATL!PatternElement (
s."rule".namedElements
->exists(e | e.varName = s.varName and e <> s)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'pattern or variable named \''
+ s.varName + '\' already defined in rule'
)
}
-- Rule 'VariableNameIsUniqueInRule'
-- This rule generates an 'error' Problem when there exists, in a same rule,
-- some named elements (InPatternElement/OutPatternElement/
-- RuleVariableDeclaration) that have the same name that the checked rule
-- variable declaration.
nodefault rule VariableNameIsUniqueInRule {
from
s : ATL!RuleVariableDeclaration (
s."rule".namedElements
->exists(e | e.varName = s.varName and e <> s)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'pattern or variable named \'' + s.varName
+ '\' already defined in rule'
)
}
-- Rule 'NoSelfOrThisModuleVariableDeclaration'
-- This rule generates an 'error' Problem for each declaration of a variable
-- named 'self' or 'thisModule' in the ATL program.
-- Considered variable declarations must have a non-undefined immediate
-- composite since the input ATL model may already include a 'self' and a
-- 'thisModule' VD without any immediate composite that correspond to the
-- global declarations of the 'self' and 'thisModule' variables.
nodefault rule NoSelfOrThisModuleVariableDeclaration {
from
s : ATL!VariableDeclaration (
not s.refImmediateComposite().oclIsUndefined() and
(s.varName = 'self' or s.varName = 'thisModule')
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'helper \'' + s.varName + '\' is not valid variable name'
)
}
-- Rule 'NoSelfVariableInRule'
-- This rule generates an 'error' Problem for each 'self' variable expression
-- that is contained by a rule element.
nodefault rule NoSelfVariableInRule {
from
s : ATL!VariableExp (
if s.referredVariable.oclIsUndefined()
then
false
else
s.referredVariable.varName = 'self' and
(
let rComp : OclAny = s.getRootComposite() in
rComp.oclIsTypeOf(ATL!Binding) or
rComp.oclIsTypeOf(ATL!InPattern) or
rComp.oclIsTypeOf(ATL!ActionBlock)
)
endif
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'rule \'' + s.referredVariable.varName
+ '\': use of the \'self\' variable prohibited in rules'
)
}
-- Rule 'NoSelfVariableInRule'
-- This rule generates an 'error' Problem for each 'self' variable expression
-- that is contained by a helper without context declaration.
nodefault rule NoSelfVariableInContextlessHelper {
from
s : ATL!VariableExp (
if s.referredVariable.oclIsUndefined()
then
false
else
s.referredVariable.varName = 'self' and
(
let rComp : OclAny = s.getRootComposite() in
rComp.oclIsKindOf(ATL!OclFeature) and
rComp.definition.context_.oclIsUndefined()
)
endif
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'Use of the \'self\' variable prohibited in helpers without context declaration'
)
}
-- Rule 'NoResolveTempInSourcePattern'
-- This rule generates an 'error' Problem for each call of the
-- 'thisModule.resolveTemp()' operation within a source pattern of a rule.
nodefault rule NoResolveTempInSourcePattern {
from
s : ATL!OperationCallExp (
s.operationName = 'resolveTemp' and
(
if s.source.oclIsTypeOf(ATL!VariableExp)
then
if s.source.referredVariable.oclIsUndefined()
then
false
else
s.source.referredVariable.varName = 'thisModule'
endif
else
false
endif
) and
s.getRootComposite().oclIsTypeOf(ATL!InPattern)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'rule \'' + s.getRootComposite()."rule".name
+ '\': use of \'thisModule.resolveTemp()\' function '
+ 'is prohibited in source patterns'
)
}
-- Rule 'ProhibitedMultiIteratorCollectionOperation'
-- This rule generates an 'error' Problem for each IteratorExp of the
-- singleIteratorExps set that is associated with several Iterators.
nodefault rule ProhibitedMultiIteratorCollectionOperation {
from
s : ATL!IteratorExp (
thisModule.singleIteratorExps->exists(e | s.name = e) and
s.iterators->size() > 1
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'iterator \'' + s.name
+ '\' may have at most one iterator variable'
)
}
---- Rule 'UnsupportedMultiIteratorCollectionOperation'
---- This rule generates an 'error' Problem for each IteratorExp of the
---- multiIteratorExps set that is associated with several Iterators.
---- Note that this problem is due to limitations of the current implementation.
--nodefault rule UnsupportedMultiIteratorCollectionOperation {
-- from
-- s : ATL!IteratorExp (
-- thisModule.multiIteratorExps->exists(e | s.name = e) and
-- s.iterators->size() > 1
-- )
-- to
-- t : Problem!Problem (
-- severity <- #error,
-- location <- s.location,
-- description <-
-- 'with current implementation, iterator \'' + s.name
-- + '\' may have at most one iterator variable'
-- )
--}
-- Rule 'ParameterNameIsUniqueInOperation'
-- This rule generates an 'error' Problem for each parameter for which there
-- exists another parameter of the same name in the operation declaration.
nodefault rule ParameterNameIsUniqueInOperation {
from
s : ATL!Parameter (
if not s.operation.oclIsUndefined() then
(s.operation.parameters
->exists(e | s.varName = e.varName and s <> e)) and not(
s.refImmediateComposite().oclIsUndefined() and
s.varName <> 'self' and s.varName <> 'thisModule'
)
else false endif
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'a parameter named \'' + s.varName
+ '\' is already declared in this operation'
)
}
-- Rule 'IteratorNameIsUniqueInLoop'
-- This rule generates an 'error' Problem for each Iterator declaration for
-- which there exists either another Iterator or a result variable declaration
-- (for Iterate loop only) of the same name within the same loop definition.
nodefault rule VariableNameIsUniqueInLoop {
from
s : ATL!Iterator (
if not s.loopExpr.oclIsUndefined() then
s.loopExpr.iterators
->exists(e | s.varName = e.varName and s <> e)
or
if s.loopExpr.oclIsTypeOf(ATL!IterateExp)
then
s.loopExpr.result.varName = s.varName
else
false
endif
else false endif
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'a variable named \'' + s.varName
+ '\' is already declared in this loop'
)
}
-- Rule 'ResultNameIsUniqueInIterate'
-- This rule generates an 'error' Problem for each 'result' variable
-- declaration of an IterateExp for which there exists an Iterator variable of
-- the same name in the Iterate loop definition.
nodefault rule ResultNameIsUniqueInIterate {
from
s : ATL!VariableDeclaration (
if s.baseExp.oclIsUndefined()
then
false
else
s.baseExp.iterators
->exists(e | s.varName = e.varName and s <> e)
endif
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <-
'a variable named \'' + s.varName
+ '\' is already declared in this loop'
)
}
-- Rule 'VariableNameIsUniqueInContainer'
-- This rule generates a 'warning' Problem for each declaration of a variable
-- for which there exists another variable declaration of the same name in the
-- same namespace (except multiple intances of an Iterator name in a same loop
-- which handle 'error' Problems).
nodefault rule VariableNameIsUniqueInContainer {
from
s : ATL!VariableDeclaration (
s.getDeclarations()->exists(e | s.varName = e.varName and s <> e)
)
to
t : Problem!Problem (
severity <- #warning,
location <- s.location,
description <-
'a variable named \'' + s.varName
+ '\' is already declared in this container'
)
}
nodefault rule NoSuperOutsideHelper {
from s : ATL!SuperExp (
not s.getRootComposite().oclIsKindOf(ATL!OclFeature)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'Cannot access "super" outside operations or attributes'
)
}
nodefault rule NoSuperInContextlessHelper {
from s : ATL!SuperExp (
let rComp : OclAny = s.getRootComposite() in
rComp.oclIsKindOf(ATL!OclFeature) and
rComp.definition.context_.oclIsUndefined()
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'Cannot access "super" from a helper without context declaration'
)
}
nodefault rule OutputElementUsesOutputMetamodel {
from s : ATL!OutPatternElement (
not s.outPattern."rule"."module".outModels
->exists(m|s.type.model.name = m.metamodel.name)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'Cannot instantiate metaclasses that are not related to an output model'
)
}
nodefault rule BindingStatAssignsToNavigationOrAttributeCallExpOrVariable {
from s : ATL!BindingStat (
(
not s.source.oclIsKindOf(ATL!NavigationOrAttributeCallExp)
) and (
not s.source.oclIsKindOf(ATL!VariableExp) or
s.source.referredVariable.varName = 'self' or
s.source.referredVariable.varName = 'thisModule'
)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'Can only assign to model element features, helper attributes, or local variables'
)
}
nodefault rule RefiningRuleInRegularMode {
from
s : ATL!MatchedRule (
s.isRefining and
not s."module".isRefining
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'Refining rules are only allowed in refining mode'
)
}
nodefault rule NoOutPatternElementReferenceInInPattern {
from
s : ATL!VariableExp (
s.referredVariable.oclIsKindOf(ATL!OutPatternElement) and
s.getRootComposite().oclIsKindOf(ATL!InPattern)
)
to
t : Problem!Problem (
severity <- #error,
location <- s.location,
description <- 'Cannot refer to target element \'' + s.referredVariable.varName + '\' in a \'from\' clause'
)
}