| [module mt2mtl('http://www.eclipse.org/acceleo/mt/2.6.0')/] |
| [import ServiceUtils/] |
| |
| [comment] |
| This will be used to convert a given Acceleo.org "template" |
| (an aggregate of scripts) to an Acceleo MTL "module" (aggregate of queries, |
| templates and macros). The name of the "template"'s containing file |
| will be used as the name of the converted module. |
| |
| templ : Acceleo.org template that needs be converted. |
| [/comment] |
| [template public convertToModule(templ : Template)] |
| [comment @main /] |
| [file (fullpathName(), false)] |
| ['['/]module [templ.shortName().replaceAll('-', '')/]([for (templ.imports->select(oclIsKindOf(Metamodel))) separator (', ')]'[name/]'[/for])/] |
| [for (imported : Resource | templ.imports->reject(oclIsKindOf(Metamodel)) |
| ->reject(oclIsKindOf(Service)))] |
| ['['/]import [imported.qualifiedImportName()/]/] |
| [/for] |
| |
| [comment We'll assume that a template beginning with "is*" or "has*" is a query returning a boolean/] |
| [for (script : Script | templ.scripts) separator('\n')] |
| [if (script.isBooleanQuery())][script.convertToBooleanQuery()/][elseif (script.isCollectionQuery())][script.convertToCollectionQuery()/][else][script.convertToTemplate()/][/if] |
| [/for] |
| |
| [for (adaptCall : Call | selectUniqueCallAdapt())] |
| ['['/]query private ['adaptTo'.concat(adaptCall.getAdaptType())/](o : OclAny) : [adaptCall.inferAdaptReturnType()/] = invoke('org.eclipse.acceleo.compatibility.services.MigrationServices', '['adaptTo'.concat(adaptCall.arguments->first().convertExpressionToOCL().replaceAll('\'', ''))/](java.lang.Object)', Sequence{o})/] |
| [/for] |
| |
| [for (service : Method | templ.allCalls()->select(c | c.isServiceCall()).getTargetService()->asSet())] |
| [service.convertToQuery()/] |
| [/for] |
| [/file] |
| [/template] |
| |
| [query private selectUniqueCallAdapt(templ : Template) : OrderedSet(Call) = |
| templ.ancestors()->last().allCalls()->select(name = 'adapt') |
| ->iterate(call : Call; resSeq : Sequence(Call) = Sequence{} | |
| if resSeq->isNotTypeAdaptInCallsList(call.getAdaptType()) then |
| resSeq->append(call) |
| else |
| resSeq |
| endif)->asOrderedSet() |
| /] |
| |
| [query private isNotTypeAdaptInCallsList(callList : Sequence(Call) |
| ,str : String) : Boolean = |
| callList->collect(c:Call | getAdaptType(c))->select(s | s = str) |
| ->isEmpty() |
| /] |
| |
| [query private getAdaptType(adaptCall : Call) : String = |
| adaptCall.arguments->first().convertExpressionToOCL() |
| .replaceAll('\'', '') /] |
| |
| [comment] |
| Generate the full path name of file module |
| |
| template : Acceleo Template will be converted to an Acceleo MTL Module. |
| [/comment] |
| [query private fullpathName(templ : Template) : String = |
| templ.name.replaceAll('\\.', '/') |
| .replaceAll('-', '') |
| .concat('.mtl')/] |
| |
| [comment Test if mt Script probably return a list/] |
| [query private isCollectionQuery(script : Script) : Boolean = |
| script.descriptor.file.statements->size() = 0 and |
| script.statements->size() = 1 and |
| if script.statements->first().oclIsKindOf(mt::statements::Feature) then |
| let subFeature : mt::statements::Feature = |
| script.statements->first().oclAsType(mt::statements::Feature) |
| in |
| if subFeature.expression.oclIsKindOf(mt::expressions::CallSet) then |
| let cSet : mt::expressions::CallSet = |
| subFeature.expression.oclAsType(mt::expressions::CallSet) |
| in |
| cSet.calls->size() = 1 |
| and not cSet.calls->first().filter.oclIsUndefined() |
| else |
| false |
| endif |
| else |
| false |
| endif/] |
| |
| [comment Test if mt Script probably return a boolean /] |
| [query private isBooleanQuery(script : Script) : Boolean = |
| script.descriptor.name.matches('(is|has)[A-Z_-].*') |
| and script.descriptor.file.statements->size() = 0/] |
| |
| [query private matches(string : String, regex : String) : |
| Boolean = string.replace(regex, '') <> string/] |
| |
| [comment] |
| This will be used to convert a given Acceleo.org "script" |
| to an Acceleo MTL "template". |
| |
| script : Acceleo script that will be converted to an Acceleo MTL template. |
| [/comment] |
| [template public convertToTemplate(script : Script)] |
| ['['/]template public [genTemplateHeader()/][']'/] |
| [if (script.descriptor.file.statements->size() > 0)] |
| ['['/]comment This template is called by the main module file /] |
| ['['/]file ([genFileName()/], false))] |
| [/if] |
| [script.statements.convertStatement()/] |
| [if (script.descriptor.file.statements->size() > 0)] |
| ['[/'/]file] |
| [/if] |
| ['[/'/]template[']'/] |
| |
| [/template] |
| |
| [comment] |
| Convert the header from mt to mtl |
| |
| script : Acceleo script that will be converted to an Acceleo MTL query. |
| [/comment] |
| [query public genTemplateHeader(script : Script) : String = |
| script.descriptor.name.replaceAll('-', '') |
| .concat('(') |
| .concat(script.descriptor.type.getVariableNameForType()) |
| .concat(' : ') |
| .concat(script.descriptor.type.convertType()) |
| .concat(script.getAdditionalArguments()) |
| .concat(')') |
| .concat(script.genPostTrim()) |
| /] |
| |
| [comment] |
| Convert post trim in the header |
| |
| script : Acceleo script that will be converted to an Acceleo MTL query. |
| [/comment] |
| [query public genPostTrim(script : Script) : String = |
| if script.descriptor._post.oclIsUndefined() then |
| '' |
| else |
| let setcall : CallSet = |
| script.descriptor._post.oclAsType(CallSet) |
| in |
| if setcall.calls->select(call : Call | call.name = 'trim')->isEmpty() then |
| '' |
| else |
| ' post(trim())' |
| endif |
| endif |
| /] |
| |
| [comment] |
| Generate the content of file tag |
| |
| script : Acceleo script that will be converted to an Acceleo MTL query. |
| [/comment] |
| [query public genFileName(script : Script) : Sequence(String) = |
| let |
| stmts : OrderedSet(mt::statements::Statement) = |
| script.descriptor.file.statements, |
| size : Integer = |
| script.descriptor.file.statements->size() |
| in |
| stmts->collect(stmt : mt::statements::Statement | |
| let convertedStmt : String = |
| stmt.convertStatementToOCL() |
| in |
| if size = 1 and stmt.oclIsKindOf(mt::statements::Text) then |
| '\''.concat(convertedStmt).concat('\'') |
| else if stmt.oclIsKindOf(mt::statements::Text) then |
| convertedStmt |
| else if stmts->indexOf(stmt) = 1 then |
| convertedStmt |
| else |
| '.concat('.concat(convertedStmt).concat(')') |
| endif endif endif) |
| /] |
| |
| [comment] |
| This will be used to convert a given Acceleo.org "script" |
| to an Acceleo MTL "query" returning a boolean. |
| |
| script : Acceleo script that will be converted to an Acceleo MTL query. |
| [/comment] |
| [template public convertToBooleanQuery(script : Script)] |
| ['['/]query public [genTemplateHeader()/] : Boolean = |
| [script.statements.convertStatementToOCL()/] |
| ['/]'/] |
| |
| [/template] |
| |
| |
| [template public convertToCollectionQuery(script : Script)] |
| ['['/]query public [genTemplateHeader()/] : Collection(OclAny) = |
| [script.statements.convertStatementToOCL()/] |
| ['/]'/] |
| [/template] |
| |
| [template public convertToQuery(method : Method)] |
| ['['/]query private [method.name/]([for (param : Parameter | method.parameters) separator (', ')]arg[method.parameters->indexOf(param) - 1/] : [param.type.convertJavaTypeToOCL()/][/for]) : [method.return.convertJavaTypeToOCL()/] = invoke('[method.ancestors(Service)->first().name/]', '[method.signature()/]', Sequence{[for (param : Parameter | method.parameters) separator (', ')]arg[method.parameters->indexOf(param) - 1/][/for]})/] |
| [/template] |
| |
| [query private getAdditionalArguments(script : Script) : String = |
| let additionalArguments : OrderedSet(String) = |
| script.eAllContents(mt::expressions::Call) |
| ->select(name = 'args')->collect(name.concat(arguments->first() |
| .convertExpressionToOCL()))->asOrderedSet() |
| ->sortedBy(s|s) |
| in |
| additionalArguments->iterate(arg; res : String = '' | ( |
| if additionalArguments->first() = arg then |
| ', ' |
| else |
| res |
| endif).concat(arg).concat(' : OclAny') |
| .concat( |
| if additionalArguments->last() <> arg then |
| ', ' |
| else |
| '' |
| endif)) |
| /] |
| |
| [comment] |
| This is as placeholder for the compiler to be able to compile calls on "Statement", yet this |
| getting called means we're missing a specialized implementation of "convertStatement" for the |
| runtime class of the given statement. |
| |
| statement : Statement that is to be converted. |
| [/comment] |
| [template public convertStatement(statement : Statement)] |
| <<<FIXME : couldn't convert statement [statement/].>>> |
| [/template] |
| |
| [comment] |
| This is as placeholder for the compiler to be able to compile calls on "Statement", yet this |
| getting called means we're missing a specialized implementation of "convertStatementToOCL" for the |
| runtime class of the given statement. |
| |
| statement : Statement that is to be converted. |
| [/comment] |
| [template public convertStatementToOCL(statement : Statement)] |
| <<<FIXME : couldn't convert statement [statement/] to OCL.>>> |
| [/template] |
| |
| [template public convertStatement(cmtStmt : Comment)] |
| ['['/]comment [cmtStmt.value/]/] |
| [/template] |
| |
| [template public convertStatementToOCL(cmtStmt : Comment)] |
| [cmtStmt.convertStatement()/] |
| [/template] |
| |
| [template public convertStatement(ifStmt : If) |
| {isMultiLine : Boolean = |
| ifStmt.eAllContents(Text)->collect(value.index('\n') > 0) |
| ->includes(true);}] |
| ['['/]if [ifStmt.condition.convertExpressionToOCL()/]][if (isMultiLine)]['\n'/][/if][ifStmt.thenStatements.convertStatement()/][for (elseIf : If | ifStmt.elseIf)]['['/]elseif [elseIf.condition.convertExpressionToOCL()/]][if (isMultiLine)]['\n'/][/if][elseIf.thenStatements.convertStatement()/][/for][if (ifStmt.elseStatements->size() > 0)]['['/]else][if (isMultiLine)]['\n'/][/if][ifStmt.elseStatements.convertStatement()/][/if]['['/]/if][if (isMultiLine)]['\n'/][/if] |
| [/template] |
| |
| [template public convertStatementToOCL(ifStmt : If) |
| {isMultiLine : Boolean = |
| ifStmt.eAllContents(Text)->collect(value.index('\n') > 0) |
| ->includes(true);}] |
| if [ifStmt.condition.convertExpressionToOCL()/] then [if (isMultiLine)]['\n'/][/if][ifStmt.thenStatements.convertStatement()/][for (elseIf : If | ifStmt.elseIf)] else if [elseIf.condition.convertExpressionToOCL()/] then [if (isMultiLine)]['\n'/][/if][elseIf.thenStatements.convertStatement()/][/for][if (ifStmt.elseStatements->size() > 0)] else [if (isMultiLine)]['\n'/][/if][ifStmt.elseStatements.convertStatement()/][/if] endif[if (isMultiLine)]['\n'/][/if][for (elseIf : If | ifStmt.elseIf)] endif[/for] |
| [/template] |
| |
| [comment] |
| Converts a for loop of Acceleo.org to Acceleo MTL. There is no difference between this and its |
| converStatementToOCL counterpart. |
| |
| forLoop : The for loop that will be converted. |
| [/comment] |
| [template public convertStatement(forLoop : For) {isMultiLine : Boolean = forLoop.eAllContents(Text)->collect(value.index('\n') > 0)->includes(true);}] |
| ['['/]for [if (forLoop.iterator.oclIsKindOf(mt::expressions::Parenthesis))][forLoop.iterator.convertExpressionToOCL()/][else]([forLoop.iterator.convertExpressionToOCL()/])[/if]][if (isMultiLine)]['\n'/][/if][forLoop.statements.convertStatement()/]['['/]/for][if (isMultiLine)]['\n'/][/if] |
| [/template] |
| |
| [comment] |
| Converts a for loop of Acceleo.org to Acceleo MTL. There is no difference between this and its |
| converStatement counterpart. |
| |
| forLoop : The for loop that will be converted. |
| [/comment] |
| [template public convertStatementToOCL(forLoop : For)] |
| [forLoop.convertStatement()/] |
| [/template] |
| |
| [comment] |
| Converts a composite statement (property call, operation call, ...) to an |
| Acceleo MTL equivalent. |
| The returned expression will be nested within brackets. |
| |
| This mustn't be used for Acceleo.org "script"s' 'file' attribute : |
| file="<%name%>.txt" must be converted to name.concat('.txt') |
| and not [name/].txt. |
| |
| feature : Statement that is to be converted. |
| [/comment] |
| [template public convertStatement(feature : Feature)] |
| [if (not(isInUserCodeMarkerArea()))][expression.convertExpression()/][/if] |
| [/template] |
| |
| [comment] |
| Test if feature is in a User Code Marler Area. |
| |
| feature : Statement that is to be tested. |
| [/comment] |
| [query public isInUserCodeMarkerArea(obj : ecore::EObject) : Boolean = |
| if strInUserCodeMarkerArea(obj).endsWith('in') then |
| true |
| else |
| false |
| endif |
| /] |
| |
| [comment] |
| Retun string out if Fearture is out of UserCode Marker Area |
| and in if in the UserCode Marker Area |
| |
| in : have preceding usercode and not a text statment with NewLine |
| beteewn feature and usercode |
| |
| feature : Statement that is to be tested. |
| [/comment] |
| [query public strInUserCodeMarkerArea(obj : ecore::EObject) : String = |
| obj.precedingSiblings() |
| ->iterate( e ; acc : String = '' | |
| if e.oclIsTypeOf(mt::statements::Feature) |
| and e.oclAsType(mt::statements::Feature).isStartOfUserCode() then |
| acc.concat('in') |
| else if e.oclIsTypeOf(mt::statements::Text) |
| and e.oclAsType(mt::statements::Text).isTextEndOfAreaMarker() then |
| acc.concat('out') |
| else |
| acc |
| endif endif |
| ) |
| /] |
| |
| [comment] |
| Converts a composite statement (property call, operation call, ...) |
| to an Acceleo MTL equivalent. |
| The returned expression will not be nested within brackets. |
| |
| This must be used for Acceleo.org "script"s' 'file' attribute : |
| file="<%name%>.txt" must be converted to name.concat('.txt') |
| and not [name/].txt. |
| |
| feature : Statement that is to be converted. |
| [/comment] |
| [template public convertStatementToOCL(feature : Feature)] |
| [feature.expression.convertExpressionToOCL()/] |
| [/template] |
| |
| [comment] |
| Converts a static text part region from Acceleo.org to Acceleo MTL. With this, |
| the text will be returned as is; as opposed to convertStatementToOCL. |
| |
| text : Text that needs be converted. |
| [/comment] |
| [template public convertStatement(text : Text)] |
| [(let textValue : String = |
| if isInUserCodeMarkerArea() then |
| text.value.trimToFirstCarriageReturnOrEmplyString() |
| .convertStaticTextToAcceleo() |
| else |
| text.value |
| endif |
| in textValue.convertStaticTextToAcceleo())/] |
| [/template] |
| |
| [comment] |
| Converts a static text part region from Acceleo.org to Acceleo MTL. With this, |
| the text will be nested within simple quotes, and possibly preceded |
| by ".concat(" if we're in the middle of a composite expression. |
| |
| text : Text that needs be converted. |
| [/comment] |
| [template public convertStatementToOCL(text : Text)] |
| [(let textValue : String = |
| if isInUserCodeMarkerArea() then |
| text.value.trimToFirstCarriageReturn() |
| .convertStaticTextToAcceleo() |
| else |
| text.value.convertStaticTextToAcceleo() |
| endif |
| in |
| if oclAsType(ecore::EObject).eContainer() |
| .eContents()->indexOf(text) > 1 then |
| '.concat(\''.concat(textValue).concat('\')') |
| else |
| textValue endif) |
| /] |
| [/template] |
| |
| [query private convertStaticTextToAcceleo(value : String) : String = |
| value.replaceAll('(\\[|\\])', '\\[\'$0\'/\\]')/] |
| |
| [query private trimToFirstCarriageReturnOrEmplyString(value : String) : String = |
| if value.contains('\r\n') then |
| value.substring(value.index('\r\n') + 2, value.size()) |
| else if value.contains('\r') then |
| value.substring(value.index('\r') + 1, value.size()) |
| else if value.contains('\n') then |
| value.substring(value.index('\n') + 1, value.size()) |
| else |
| '' |
| endif endif endif/] |
| |
| [query private trimToFirstCarriageReturn(value : String) : String = |
| let textValue : String = trimToFirstCarriageReturnOrEmplyString(value) |
| in |
| if textValue = '' then |
| value |
| else |
| textValue |
| endif/] |
| |
| [comment] |
| Test if the currrent feature is an user code feature |
| |
| feature : Statement that is to be tested. |
| [/comment] |
| [query private isStartOfUserCode(feature : Feature) : Boolean = |
| if feature.expression |
| .oclIsKindOf(mt::expressions::CallSet) then |
| let cSet : mt::expressions::CallSet = |
| feature.expression |
| .oclAsType(mt::expressions::CallSet) |
| in |
| cSet.calls->size() = 1 |
| and cSet.calls->first().name = 'startUserCode' |
| else |
| false |
| endif |
| /] |
| |
| [comment] |
| This is as placeholder for the compiler to be able to compile calls on |
| "Expression", yet this getting called means we're missing a specialized |
| implementation of "convertExpression" for the runtime class |
| of the given expression. |
| |
| expression : The expression we should convert to an Acceleo equivalent. |
| [/comment] |
| [template public convertExpression(expression : Expression)] |
| <<<FIXME : couldn't convert expression [expression/].>>> |
| [/template] |
| |
| [comment] |
| This is as placeholder for the compiler to be able to compile calls on |
| "Expression", yet this getting called means we're missing a specialized |
| implementation of "convertExpressionToOCL" for the |
| runtime class of the given expression. |
| |
| expression : The expression we should convert to an Acceleo equivalent. |
| [/comment] |
| [template public convertExpressionToOCL(expression : Expression)] |
| <<<FIXME : couldn't convert expression [expression/].>>> |
| [/template] |
| |
| [comment] |
| This will recursively call for the conversion of all calls contained |
| within the given callSet. The returned expression will |
| be nests within brackets. |
| |
| For example, <%name%>.txt would be converted to [name.concat('.txt')/] |
| as opposed to convertExpressionToOCL which would return name.concat('.txt'). |
| |
| callSet : CallSet which contents are to be converted to Acceleo MTL equivalents. |
| [/comment] |
| [template public convertExpression(callSet : CallSet)] |
| [if (callSet.calls->size() = 1 and (callSet.calls->first().name = 'startUserCode' or callSet.calls->first().name = 'endUserCode'))][callSet.calls->first().convertUserCodeCall()/][else]['['/][convertExpressionToOCL()/]/][/if] |
| [/template] |
| |
| [comment] |
| This will recursively call for the conversion of all calls contained within the given callSet. The |
| returned expression will not be nested within brackets. |
| |
| For example, <%name%>.txt would be converted to name.concat('.txt') as opposed to convertExpression |
| which would return [name.concat('.txt')/]. |
| |
| callSet : CallSet which contents are to be converted to Acceleo MTL equivalents. |
| [/comment] |
| [template public convertExpressionToOCL(callSet : CallSet)] |
| [callSet.calls.convertExpressionToOCL()/] |
| [/template] |
| |
| [comment] |
| Converts a single Acceleo.org call to an Acceleo MTL equivalent. |
| The returned expression will be nested within brackets. |
| |
| call : The particular call that is to be converted to an equivalent. |
| [/comment] |
| [template public convertExpression(call : Call)] |
| ['['/][call.getSeparator()/][if (call.isOperationCall())][convertServiceCall()/][else][convertPropertyCall()/][/if][if (not call.filter.oclIsUndefined())]->select([call.filter.convertExpressionToOCL()/])[/if]/] |
| [/template] |
| |
| [comment] |
| Converts a single Acceleo.org call to an Acceleo MTL equivalent. The returned expression will not |
| be nested within brackets. |
| |
| call : The particular call that is to be converted to an equivalent. |
| [/comment] |
| [template public convertExpressionToOCL(call : Call)] |
| [call.getSeparator()/][if (call.isOperationCall())][convertServiceCall()/][else][convertPropertyCall()/][/if][if (not call.filter.oclIsUndefined())]->select([call.filter.convertExpressionToOCL()/])[/if] |
| [/template] |
| |
| [template public convertExpression(notExpr : Not)] |
| ['['/][convertExpressionToOCL()/]/] |
| [/template] |
| |
| [template public convertExpressionToOCL(notExpr : Not)] |
| not ([notExpr.expression.convertExpressionToOCL()/]) |
| [/template] |
| |
| [template public convertExpression(operator : Operator)] |
| ['['/][convertExpressionToOCL()/]/] |
| [/template] |
| |
| [template public convertExpressionToOCL(operator : Operator)] |
| [for (operand : Expression | operator.operands)][operand.convertExpressionToOCL()/][if (operator.operands->last() <> operand)][' '/][operator.operator.convertOperator()/][' '/][/if][/for] |
| [/template] |
| |
| [comment] |
| Converts Acceleo.org parenthesis expression to an Acceleo MTL equivalent. |
| The expression nested within these parenthesis will be converted |
| nested within brackets. |
| |
| parenthesis : Parenthesis expression that is to be converted to an equivalent. |
| [/comment] |
| [template public convertExpression(parenthesis : Parenthesis)] |
| ([parenthesis.expression.convertExpression()/]) |
| [/template] |
| |
| [comment] |
| Converts Acceleo.org parenthesis expression to an Acceleo MTL equivalent. |
| The expression nested within these parenthesis will not be converted |
| nested within brackets. |
| |
| parenthesis : Parenthesis expression that is to be converted to an equivalent. |
| [/comment] |
| [template public convertExpressionToOCL(parenthesis : Parenthesis)] |
| ([parenthesis.expression.convertExpressionToOCL()/]) |
| [/template] |
| |
| [template public convertExpression(stringLiteral : StringLiteral)] |
| '[value/]' |
| [/template] |
| |
| [template public convertExpressionToOCL(stringLiteral : StringLiteral)] |
| [convertExpression()/] |
| [/template] |
| |
| [template public convertExpression(intLiteral : IntegerLiteral)] |
| [value/] |
| [/template] |
| |
| [template public convertExpressionToOCL(intLiteral : IntegerLiteral)] |
| [convertExpression()/] |
| [/template] |
| |
| [template public convertExpression(doubleLiteral : DoubleLiteral)] |
| [value/] |
| [/template] |
| |
| [template public convertExpressionToOCL(doubleLiteral : DoubleLiteral)] |
| [convertExpression()/] |
| [/template] |
| |
| [template public convertExpression(booleanLiteral : BooleanLiteral)] |
| [value/] |
| [/template] |
| |
| [template public convertExpressionToOCL(booleanLiteral : BooleanLiteral)] |
| [convertExpression()/] |
| [/template] |
| |
| [template public convertExpression(nullLiteral : NullLiteral)] |
| null |
| [/template] |
| |
| [template public convertExpressionToOCL(nullLiteral : NullLiteral)] |
| [convertExpression()/] |
| [/template] |
| |
| [comment] |
| Returns the short name (without path information) of the given template. |
| |
| templ : Template which path is to be considered. |
| [/comment] |
| [query private shortName(templ : Template) : String = |
| templ.name.replaceAll('.*\\.(.*)', '$1')/] |
| |
| [comment] |
| Returns the qualified name (without path information) of the given template. |
| |
| templ : Template which path is to be considered. |
| [/comment] |
| [query private qualifiedImportName(templ : Resource) : String = |
| templ.name.replaceAll('\\.', '::') |
| .replaceAll('-', '') |
| .replaceAll('.*\\.(.*)', '$1')/] |
| |
| [comment] |
| Converts qualified type names to uml notation. |
| |
| For example, "ecore.EClass" would be converted to "ecore::EClass". |
| |
| type : name of the type that is to be converted. |
| [/comment] |
| [query private convertType(type : String) : String = |
| let converted : String = |
| type.replace('\\.', '::') |
| in |
| if converted = 'EObject' then |
| 'ecore::EObject' |
| else |
| converted |
| endif/] |
| |
| [comment] |
| This will return a suitable variable name from a given type. |
| |
| For example, this would return "eClass" for type "ecore.EClass" or |
| "_package" for type "uml.Package". |
| |
| type : name of the type we need a variable for. |
| [/comment] |
| [query private getVariableNameForType(type : String) : String = |
| let protectedNames : Sequence(String) = |
| Sequence{'template', 'query', 'macro', 'import', |
| 'module', 'private', 'protected', 'public', |
| 'for', 'if', 'let', 'else', 'then'}, |
| name : String = |
| if type.contains('.') then |
| type.substring(type.index('.') + 1, type.size()) |
| else |
| type |
| endif |
| in |
| if protectedNames->includes(name) then |
| '_'.concat(name).toLowerFirst() |
| else |
| name.toLowerFirst() |
| endif/] |
| |
| [query private convertSource(call : Call) : String = |
| let precedingCalls : Sequence(Call) = |
| call.oclAsType(ecore::EObject).eContainer().eContents() |
| .oclAsType(Call)->subSequence(1, call.oclAsType(ecore::EObject) |
| .eContainer().eContents()->indexOf(call))->excluding(call) |
| in |
| precedingCalls->iterate(element; res : String = '' |
| | res.concat(element.convertExpressionToOCL()))/] |
| |
| [query private getSeparator(call : Call) : String = |
| if call.isFirstCall() |
| or call.isIgnoredCall() then |
| '' |
| else |
| if isListOperation() then |
| '->' |
| else |
| '.' |
| endif |
| endif/] |
| |
| [query private isFirstCall(call : Call) : Boolean = |
| call.oclAsType(ecore::EObject).eContainer() |
| .eContents()->indexOf(call) = 1/] |
| |
| [query private isIgnoredCall(call : Call) : Boolean = |
| not call.isFirstCall() |
| and call.name = 'current' |
| and call.arguments->size() = 0/] |
| |
| [query private isListOperation(call : Call) : Boolean = |
| call.name = 'select' or |
| call.name = 'delete' or |
| call.name = 'cast' or |
| call.name = 'filter' or |
| call.name = 'nMinimize' or |
| call.name = 'minmize' or |
| call.name = 'nContains' or |
| call.name = 'nFirst' or |
| call.name = 'nLast' or |
| call.name = 'nGet' or |
| call.name = 'nReverse' or |
| call.name = 'reverse' or |
| call.name = 'nSize' or |
| call.name = 'nSort' or |
| call.name = 'sort' or |
| call.name = 'sep' or |
| call.name = 'sepStr'/] |
| |
| [query private convertOperator(operator : String) : String = |
| if operator = '&&' then |
| 'and' |
| else if operator = '||' then |
| 'or' |
| else if operator = '!=' then |
| '<>' |
| else if operator = '==' then |
| '=' |
| else |
| operator |
| endif endif endif endif/] |
| |
| [query private convertOperators(expression : String) : |
| String = expression.substituteAll('&&', 'and') |
| .substituteAll('||', 'or') |
| .substituteAll('!=', '<>') |
| .substituteAll('==', '=') |
| .substituteAll('!', ' not ')/] |
| |
| [query private convertPropertyCall(call : Call) : String = |
| let reservedKeywords : Sequence(String) = |
| Sequence{'and', 'body', 'context', 'def', 'derive', 'else', |
| 'endif', 'endPackage', 'if', 'implies', 'in', 'init', |
| 'inv', 'let', 'not', 'oper', 'or', 'package', 'post', |
| 'pre', 'static', 'then', 'xor'} |
| in |
| if reservedKeywords->includes(call.name) then |
| '_'.concat(call.name) |
| else |
| call.name |
| endif/] |
| |
| [query private convertServiceCall(call : Call) : String = |
| if call.name.isStringService() then |
| convertStringService() |
| else if call.name.isEObjectService() then |
| convertEObjectService() |
| else if call.name.isRequestService() then |
| convertRequestService() |
| else if call.name.isResourceService() then |
| convertResourceService() |
| else if call.name.isSystemService() then |
| convertSystemService() |
| else if call.name.isXPathService() then |
| convertXPathService() |
| else if call.isENodeService() then |
| convertENodeService() |
| else if call.name.isContextService() then |
| convertContextService() |
| else if call.name.isPropertiesService() then |
| convertPropertiesService() |
| else |
| call.name.concat(call.convertArguments()) |
| endif endif endif endif endif endif endif endif endif/] |
| |
| [query private convertUserCodeCall(call : Call) : String = |
| if call.name = 'startUserCode' then |
| '[protected('.concat(call.protectedAreaMarker()) |
| .concat(')]').concat(call.getProtectedNewLine()) |
| else |
| '[/protected]' |
| endif/] |
| |
| [query private protectedAreaMarker(call : Call) : String = |
| getSequenceAreaMarker()->iterate(e;r : String ='' | |
| r.concat(e) |
| ) |
| /] |
| |
| [query private protectedAreaMarkerText(statTxt : Text) : String = |
| let textValue : String = |
| statTxt.value |
| in |
| if textValue.contains('\r\n') |
| and textValue.index('\r\n') = textValue.index('\r') |
| and textValue.index('\r\n') < textValue.index('\n') then |
| '\''+textValue.substring(1, textValue.index('\r\n')) |
| .replaceAll('\n', '').replaceAll('\r', '') + '\'' |
| else if textValue.contains('\r') |
| and (not(textValue.contains('\n')) |
| or textValue.index('\r') < textValue.index('\n')) then |
| '\''+textValue.substring(1, textValue.index('\r')) |
| .replaceAll('\n', '').replaceAll('\r', '')+ '\'' |
| else if textValue.contains('\n') then |
| '\''+textValue.substring(1, textValue.index('\n')) |
| .replaceAll('\n', '').replaceAll('\r', '')+ '\'' |
| else |
| '\''+textValue+ '\'' |
| endif endif endif/] |
| |
| [query private getSequenceAreaMarker(call : Call) : Sequence(String) = |
| call.ancestors(mt::statements::Feature)->first() |
| .oclAsType(ecore::EObject).followingSiblings() |
| ->iterate(e;r : Sequence(String) = Sequence{}| |
| if r->last()<> '%end%' |
| and e.oclIsTypeOf(mt::statements::Feature) then |
| r->including( |
| e.oclAsType(mt::statements::Feature) |
| .convertStatementToOCL().trim() |
| )->including(' + ') |
| else if r->last() <> '%end%' |
| and e.oclIsTypeOf(mt::statements::Text) |
| and e.oclAsType(mt::statements::Text) |
| .isTextEndOfAreaMarker() then |
| r->including(e.oclAsType(mt::statements::Text) |
| .protectedAreaMarkerText()) |
| ->including('%end%') |
| else if r->last()<> '%end%' |
| and e.oclIsTypeOf(mt::statements::Text) then |
| r->including(e.oclAsType(mt::statements::Text) |
| .protectedAreaMarkerText()) |
| ->including(' + ') |
| else |
| r |
| endif endif endif |
| |
| )->reject(s | s = '%end%') |
| /] |
| |
| [query private isTextEndOfAreaMarker(txt : Text) : Boolean = |
| let textValue : String = |
| txt.value |
| in |
| if textValue.contains('\r') then |
| true |
| else if textValue.contains('\n') then |
| true |
| else |
| false |
| endif endif |
| /] |
| |
| [comment] |
| Extract the newLine after Area Marker |
| |
| call : The particular call that is to be converted to an equivalent. |
| [/comment] |
| [query private getProtectedNewLine(call : Call) : String = |
| let nextFeatureOrText : Sequence(OclAny) = |
| call.ancestors(mt::statements::Feature)->first() |
| .oclAsType(ecore::EObject).followingSiblings() |
| in |
| nextFeatureOrText->iterate(e;r : String = ''| |
| r.concat( |
| if e.oclIsTypeOf(mt::statements::Text) then |
| let textValue : String = |
| e.oclAsType(mt::statements::Text).value |
| in |
| if textValue.contains('\r\n') then |
| if r = '' then |
| '\r\n' |
| else |
| '' |
| endif |
| else if textValue.contains('\r') then |
| if r = '' then |
| '\r' |
| else |
| '' |
| endif |
| else if textValue.contains('\n') then |
| if r = '' then |
| '\n' |
| else |
| '' |
| endif |
| else |
| '' |
| endif endif endif |
| else |
| '' |
| endif |
| ) |
| ) |
| /] |
| |
| [query private followingSibling(object : ecore::EObject) : OclAny = |
| let siblings : Sequence(OclAny) = |
| object.eContainer().eContents() |
| in |
| if siblings->indexOf(object) = siblings->size() then |
| object |
| else |
| siblings->at(siblings->indexOf(object) + 1) |
| endif/] |
| |
| [query private precedingSibling(object : ecore::EObject) : OclAny = |
| let siblings : Sequence(OclAny) = |
| object.eContainer().eContents() |
| in |
| if siblings->indexOf(object) = 1 then |
| object |
| else |
| siblings->at(siblings->indexOf(object) - 1) |
| endif/] |
| |
| [query private convertArguments(call : Call) : String = |
| if call.arguments->size() = 0 then |
| '()' |
| else |
| call.arguments->iterate(arg; |
| aggregate : String = '(' | |
| aggregate.concat(arg.convertExpressionToOCL()) |
| .concat( |
| if call.arguments->last() = arg then |
| '' |
| else |
| ', ' |
| endif)).concat(')') |
| endif/] |
| |
| [query private inferAdaptReturnType(adaptCall : Call) : String = |
| let typeName : String = |
| adaptCall.arguments->first().convertExpressionToOCL().toLower() |
| in |
| if typeName = 'double' then |
| 'Real' |
| else if typeName = 'eobject' |
| or typeName = 'enode' then |
| 'ecore::EObject' |
| else if typeName = 'list' |
| or typeName = 'enodelist' then |
| 'Sequence(T)' |
| else if typeName = 'integer' then |
| 'Integer' |
| else if typeName = 'boolean' then |
| 'Boolean' |
| else |
| 'String' |
| endif endif endif endif endif/] |
| |
| [query private convertJavaTypeToOCL(typeName : String) : String = |
| if typeName = 'java.math.BigDecimal' then |
| 'Real' |
| else if typeName = 'java.lang.Double' |
| or typeName = 'double' then |
| 'Real' |
| else if typeName = 'java.math.BigInteger' then |
| 'Integer' |
| else if typeName = 'java.lang.Integer' |
| or typeName = 'int' then |
| 'Integer' |
| else if typeName = 'java.lang.Short' |
| or typeName = 'short' then |
| 'Integer' |
| else if typeName = 'boolean' then |
| 'Boolean' |
| else if typeName = 'java.lang.String' then |
| 'String' |
| else if typeName = 'java.util.List' |
| or typeName = 'java.util.ArrayList' |
| or typeName = 'java.util.LinkedList' then |
| 'Sequence(OclAny)' |
| else if typeName = 'java.util.Set' |
| or typeName = 'java.util.HashSet' then |
| 'Set(OclAny)' |
| else if typeName = 'java.util.LinkedHashSet' then |
| 'OrderedSet(OclAny)' |
| else if typeName = 'java.util.Collection' then |
| 'Collection(OclAny)' |
| else if typeName = 'fr.obeo.acceleo.gen.template.eval.ENodeList' then |
| 'Sequence(OclAny)' |
| else if typeName = 'fr.obeo.acceleo.gen.template.eval.ENode' then |
| 'OclAny' |
| else |
| typeName.replace('.*\\.', '') |
| endif endif endif endif endif endif endif endif endif |
| endif endif endif endif/] |
| |
| [query private convertStringService(call : Call) : String = |
| if call.name = 'length' then |
| 'size()' |
| else if call.name = 'toUpperCase' then |
| 'toUpper()' |
| else if call.name = 'toLowerCase' then |
| 'toLower()' |
| else if call.name = 'toU1Case' then |
| 'toUpperFirst()' |
| else if call.name = 'toL1Case' then |
| 'toLowerFirst()' |
| else if call.name = 'substring' |
| and call.arguments->size() = 1 then |
| 'substring('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(' + 1, ').concat(call.convertSource()).concat('.size())') |
| else if call.name = 'substring' |
| and call.arguments->size() = 2 then |
| 'substring('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(' + 1, ').concat(call.arguments->last() |
| .convertExpressionToOCL()).concat(')') |
| else if call.name = 'replaceAll' then |
| 'replaceAll('.concat(call.arguments->first().convertExpressionToOCL() |
| .escapeChars()).concat(', ').concat(call.arguments->last() |
| .convertExpressionToOCL().escapeChars()).concat(')') |
| else if call.name = 'trim' then |
| 'trim()' |
| else if call.name = 'startsWith' then |
| 'startsWith('.concat(call.arguments->first() |
| .convertExpressionToOCL()).concat(')') |
| else if call.name = 'endsWith' then |
| 'endsWith('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')') |
| else if call.name = 'equalsIgnoreCase' then |
| 'toLower() = '.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat('.toLower()') |
| else if call.name = 'matches' then |
| 'replace('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(', \'\') <> ').concat(call.convertSource()) |
| else if call.name = 'charAt' then |
| 'substring('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(' + 1, ').concat(call.arguments->first() |
| .convertExpressionToOCL()).concat(' + 1)') |
| else if call.name = 'indexOf' |
| and call.arguments->size() = 1 then |
| 'index('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')') |
| else if call.name = 'indexOf' |
| and call.arguments->size() = 2 then |
| 'substring('.concat(call.arguments->last().convertExpressionToOCL()) |
| .concat(' + 1, ').concat(call.convertSource()) |
| .concat('.size()).index(').concat(call.arguments->first() |
| .convertExpressionToOCL()).concat(') + ') |
| .concat(call.arguments->last().convertExpressionToOCL()) |
| else if call.name = 'lastIndexOf' |
| and call.arguments->size() = 1 then |
| '<<<FIXME "lastIndexOf" has no equivalent in Acceleo OCL. lastIndexOf(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')>>>') |
| else if call.name = 'lastIndexOf' |
| and call.arguments->size() = 2 then |
| '<<<FIXME "lastIndexOf" has no equivalent in Acceleo OCL. lastIndexOf(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(', ').concat(call.arguments->last() |
| .convertExpressionToOCL()).concat(')>>>') |
| else if call.name = 'split' then |
| '<<<FIXME "split" has no equivalent in Acceleo OCL. split(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')>>>') |
| else if call.name = 'indentSpace' then |
| 'replaceAll(\'(?!<\\r)\\n|\\r\\n|\\r(?!\\n)\', \'$0 \')' |
| else if call.name = 'indentTab'then |
| 'replaceAll(\'(?!<\\r)\\n|\\r\\n|\\r(?!\\n)\', \'$0\\t\')' |
| else |
| '<<<FIXME couldn\'t convert call '.concat(call.name) |
| .concat(' to Acceleo OCL>>>') |
| endif endif endif endif endif endif endif endif endif endif endif endif |
| endif endif endif endif endif endif endif endif endif/] |
| |
| [query private convertEObjectService(call : Call) : String = |
| if call.name = 'eAllContents' |
| and call.arguments->size() = 0 then |
| 'eAllContents()' |
| else if call.name = 'eAllContents' |
| and call.arguments->size() = 1 then |
| 'eAllContents('.concat(call.arguments->first().convertExpressionToOCL() |
| .replaceAll('\'', '')).concat(')') |
| else if call.name = 'eClass' then |
| 'eClass()' |
| else if call.name = 'eContainer' |
| and call.arguments->size() = 0 then |
| 'eContainer()' |
| else if call.name = 'eContainer' |
| and call.arguments->size() = 1 then |
| 'ancestors('.concat(call.arguments->first().convertExpressionToOCL() |
| .replaceAll('\'', '')).concat(')->first()') |
| else if call.name = 'eContainingFeature' then |
| 'eContainingFeature()' |
| else if call.name = 'eContainmentFeature' then |
| 'eContainmentFeature()' |
| else if call.name = 'eContents' then |
| 'eContents()' |
| else if call.name = 'eCrossReferences' then |
| 'eCrossReferences()' |
| else if call.name = 'eResource' then |
| 'eResource()' |
| else if call.name = 'eResourceName' then |
| '<<<FIXME "eResourceName" has no equivalent in Acceleo OCL. eResourceName()>>>' |
| else if call.name = 'getRootContainer' then |
| 'ancestors()->last()' |
| else if call.name = 'load' then |
| '<<<FIXME "load" has no equivalent in Acceleo OCL. load(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')>>>') |
| else |
| '<<<FIXME couldn\'t convert call '.concat(call.name) |
| .concat(' to Acceleo OCL>>>') |
| endif endif endif endif endif endif endif endif endif endif |
| endif endif endif/] |
| |
| [query private convertRequestService(call : Call) : String = |
| if call.name = 'select' |
| and call.arguments->size() = 1 then |
| 'select('.concat(call.arguments->first().convertExpressionToOCL() |
| .replace('^\'', '').replace('\'$', '') |
| .convertOperators()).concat(')') |
| else if call.name = 'select' |
| and call.arguments->size() = 2 then |
| 'select('.concat(call.arguments->first().convertExpressionToOCL() |
| .convertOperators()).concat(' = ') |
| .concat(call.arguments->last().convertExpressionToOCL()) |
| .concat(')') |
| else if call.name = 'delete' |
| and call.arguments->size() = 1 then |
| 'reject('.concat(call.arguments->first().convertExpressionToOCL() |
| .replaceAll('\'', '')).concat(')') |
| else if call.name = 'delete' |
| and call.arguments->size() = 2 then |
| 'reject('.concat(call.arguments->first().convertExpressionToOCL() |
| .replaceAll('\'', '')).concat(' = ') |
| .concat(call.arguments->last().convertExpressionToOCL()) |
| .concat(')') |
| else if call.name = 'evaluate' then |
| '<<<FIXME "evaluate" has no equivalent in Acceleo OCL. evaluate(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')>>>') |
| else |
| '<<<FIXME couldn\'t convert call '.concat(call.name) |
| .concat(' to Acceleo OCL>>>') |
| endif endif endif endif endif/] |
| |
| [query private convertResourceService(call : Call) : String = |
| if call.name = 'getFileContent' then |
| '<<<FIXME "getFileContent" has no equivalent in Acceleo OCL. getFileContent(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')>>>') |
| else if call.name = 'getChainPath' then |
| '<<<FIXME "getChainPath" has no equivalent in Acceleo OCL. getChainPath()>>>' |
| else |
| '<<<FIXME couldn\'t convert call ' |
| .concat(call.name).concat(' to Acceleo OCL>>>') |
| endif endif/] |
| |
| [query private convertSystemService(call : Call) : String = |
| if call.name = 'i' then |
| 'i - 1' |
| else if call.name = 'args' then |
| 'args'.concat(arguments->first().convertExpressionToOCL()) |
| else |
| '<<<FIXME couldn\'t convert call ' |
| .concat(call.name).concat(' to Acceleo OCL>>>') |
| endif endif/] |
| |
| [query private convertXPathService(call : Call) : String = |
| if call.name = 'ancestor' then |
| 'ancestors()' |
| else if call.name = 'parent' then |
| 'eContainer()' |
| else if call.name = 'self' then |
| 'self' |
| else if call.name = 'child' then |
| 'eContents()' |
| else if call.name = 'descendant' then |
| 'eAllContents()' |
| else if call.name = 'precedingSibling' then |
| 'precedingSiblings()' |
| else if call.name = 'preceding' then |
| '<<<FIXME "preceding()" has no equivalent in Acceleo OCL. preceding()>>>' |
| else if call.name = 'followingSibling' then |
| 'followingSiblings()' |
| else if call.name = 'following' then |
| '<<<FIXME "following()" has no equivalent in Acceleo OCL. following()>>>' |
| else |
| '<<<FIXME couldn\'t convert call ' |
| .concat(call.name).concat(' to Acceleo OCL>>>') |
| endif endif endif endif endif endif endif endif endif/] |
| |
| [query private convertENodeService(call : Call) : String = |
| if call.name = 'adapt' then |
| 'adaptTo'.concat(call.arguments->first() |
| .convertExpressionToOCL().replaceAll('\'', '')).concat('()') |
| else if call.name = 'cast' then |
| 'filter('.concat(call.arguments->first() |
| .convertExpressionToOCL().replaceAll('\'', '')).concat(')') |
| else if call.name = 'filter' then |
| 'filter('.concat(call.arguments->first() |
| .convertExpressionToOCL().replaceAll('\'', '')).concat(')') |
| else if call.name = 'current' |
| and call.arguments->size() = 0 then |
| if call.isFirstCall() then |
| 'self' |
| else |
| '' |
| endif |
| else if call.name = 'current' |
| and call.arguments->size() = 1 |
| and call.arguments->first().oclIsKindOf(IntegerLiteral) then |
| let contextIndex : String = |
| call.arguments->first().convertExpressionToOCL() |
| in |
| if contextIndex = '0' then |
| 'self' |
| else |
| 'current('.concat(contextIndex).concat(')') |
| endif |
| else if call.name = 'current' |
| and call.arguments->size() = 1 then |
| 'current('.concat(call.arguments->first().convertExpressionToOCL() |
| .replaceAll('\'', '')).concat(')') |
| else if call.name = 'debug' then |
| '<<<FIXME "debug()" has no equivalent in Acceleo OCL. debug()>>>' |
| else if call.name = 'trace' then |
| '<<<FIXME "trace()" has no equivalent in Acceleo OCL. trace()>>>' |
| else if call.name = 'nPut' then |
| '<<<FIXME "nPut(String)" has no equivalent in Acceleo OCL. nPut(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')>>>') |
| else if call.name = 'nPeek' then |
| '<<<FIXME "nPeek()" has no equivalent in Acceleo OCL. nPeek()>>>' |
| else if call.name = 'nPop' then |
| '<<<FIXME "nPop()" has no equivalent in Acceleo OCL. nPop()>>>' |
| else if call.name = 'nPush' then |
| '<<<FIXME "nPush()" has no equivalent in Acceleo OCL. nPush()>>>' |
| else if call.name = 'nMinimize' then |
| 'asOrderedSet()->asSequence()' |
| else if call.name = 'minimize' then |
| 'asOrderedSet()->asSequence()' |
| else if call.name = 'nContains' then |
| 'includes('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')') |
| else if call.name = 'nFirst' then |
| 'first()' |
| else if call.name = 'nLast' then |
| 'last()' |
| else if call.name = 'nGet' |
| and call.arguments->size() = 1 then |
| 'at('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')') |
| else if call.name = 'nGet' |
| and call.arguments->size() = 2 then |
| 'subSequence('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(' + 1, ').concat(call.arguments->last() |
| .convertExpressionToOCL()).concat(' + 1)') |
| else if call.name = 'nReverse' then |
| 'reverse()' |
| else if call.name = 'reverse' then |
| 'reverse()' |
| else if call.name = 'nSize' then |
| 'size()' |
| else if call.name = 'nSort' |
| and call.arguments->size() = 0 then |
| 'sortedBy(toString())' |
| else if call.name = 'nSort' |
| and call.arguments->size() = 1 then |
| 'sortedBy('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')') |
| else if call.name = 'sort' |
| and call.arguments->size() = 0 then |
| 'sortedBy(toString())->asOrderedSet()->asSequence()' |
| else if call.name = 'sort' |
| and call.arguments->size() = 1 then |
| 'sortedBy('.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')->asOrderedSet()->asSequence()') |
| else if call.name = 'sep' then |
| 'sep('.concat(arguments->first().convertExpressionToOCL() |
| .formatStringForOCL()).concat(')') |
| else if call.name = 'sepStr' then |
| 'sep(\''.concat(call.arguments->first().convertExpressionToOCL()) |
| .concat('\')') |
| else if call.name = 'toString' then |
| 'toString()' |
| else if call.name = 'until' then |
| '<<<FIXME "until(String, String)" has no equivalent in Acceleo OCL. until(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(', ').concat(call.arguments->last() |
| .convertExpressionToOCL()).concat(')>>>') |
| else |
| '<<<FIXME couldn\'t convert call ' |
| .concat(call.name).concat(' to Acceleo OCL>>>') |
| endif endif endif endif endif endif endif endif endif endif endif endif |
| endif endif endif endif endif endif endif endif endif endif endif endif |
| endif endif endif endif endif endif/] |
| |
| [query private formatStringForOCL(aString : String) : String = |
| let trimmed : String = |
| if aString.startsWith('\'') |
| and aString.endsWith('\'') then |
| aString.substring(2, aString.size() - 1) |
| else if aString.startsWith('\'') then |
| aString.substring(2, aString.size()) |
| else if aString.endsWith('\'') then |
| aString.substring(1, aString.size() - 1) |
| else |
| aString |
| endif endif endif |
| in |
| trimmed.escapeChars() |
| /] |
| |
| [query private escapeChars(toEscape : String) : String = |
| toEscape.replaceAll('\\r', '\\\\r').replaceAll('\\n', '\\\\n') |
| .replaceAll('\\t', '\\\\t').replaceAll('\\f', '\\\\f') |
| .replaceAll('\\r', '\\\\r').replaceAll('\\"', '\\\\"')/] |
| |
| [query private convertContextService(call : Call) : String = |
| if call.name = 'get' then |
| '<<<FIXME "get()" has no equivalent in Acceleo OCL. get(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')>>>') |
| else if call.name = 'peek' then |
| '<<<FIXME "peek" has no equivalent in Acceleo OCL. peek()>>>' |
| else if call.name = 'pop' then |
| '<<<FIXME "pop" has no equivalent in Acceleo OCL. pop()>>>' |
| else if call.name = 'push' then |
| '<<<FIXME "push" has no equivalent in Acceleo OCL. push()>>>' |
| else if call.name = 'put' then |
| '<<<FIXME "put(String, Object)" has no equivalent in Acceleo OCL. put(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(', ').concat(call.arguments->last() |
| .convertExpressionToOCL()).concat(')>>>') |
| else |
| '<<<FIXME couldn\'t convert call '.concat(call.name) |
| .concat(' to Acceleo OCL>>>') |
| endif endif endif endif endif/] |
| |
| [query private convertPropertiesService(call : Call) : String = |
| if call.name = 'getBestProperty' then |
| '<<<FIXME "getBestProperty(String)" has no equivalent in Acceleo OCL. getBestProperty(' |
| .concat(call.arguments->first().convertExpressionToOCL()) |
| .concat(')>>>') |
| else if call.name = 'getProperty' |
| and call.arguments->size() = 1 then |
| 'getProperty('.concat(call.arguments->first() |
| .convertExpressionToOCL()).concat(')') |
| else if call.name = 'getProperty' |
| and call.arguments->size() = 2 then |
| 'getProperty('.concat(call.arguments->first() |
| .convertExpressionToOCL()).concat(', ') |
| .concat(call.arguments->last().convertExpressionToOCL()) |
| .concat(')') |
| else |
| '<<<FIXME couldn\'t convert call '.concat(call.name) |
| .concat(' to Acceleo OCL>>>') |
| endif endif endif/] |
| |
| [comment this has been externalized here to make use of the query's caching/] |
| [query private allCalls(root : OclAny) : Sequence(Call) = |
| root.eAllContents(mt::expressions::Call)/] |