Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » M2M (model-to-model transformation) » [QVTO] CST, Pretty Printer
[QVTO] CST, Pretty Printer [message #658048] Sat, 05 March 2011 15:17 Go to next message
Al  is currently offline Al Friend
Messages: 8
Registered: August 2010
Junior Member
I understand that under the current release of QVTO, it's possible to parse a given source file as an instance of http://www.eclipse.org/QVT/1.0.0/Operational, and dump it as xmi AST subsequently.
I am wondering if the same is possible with the CST model, i.e.,
http://www.eclipse.org/QVT2/1.0.0/Operational/cst.
Or is there any other way of obtaining the CST of a qvto source file?

I am also wondering if there is any pretty printer available for QVT.


Thanks
Al
Re: [QVTO] CST, Pretty Printer [message #659920 is a reply to message #658048] Wed, 16 March 2011 06:59 Go to previous message
Al  is currently offline Al Friend
Messages: 8
Registered: August 2010
Junior Member
I ended up writing one. It's pretty inchoate, but serves it's purpose for me.Hope it can help others too

modeltype QVT uses qvtoperational::expressions('http://www.eclipse.org/QVT/1.0.0/Operational');
modeltype ImpOCL uses ImperativeOCL('http://www.eclipse.org/qvt/1.0/ImperativeOCL');

modeltype OCL uses 'http://www.eclipse.org/ocl/1.1.0/OCL';

modeltype ECORE uses 'http://www.eclipse.org/emf/2002/Ecore';

transformation QvtPrettyPrinter(in qvtSrc : QVT);

property _tab_ : String = '    ';

main() {
	var s := qvtSrc.rootObjects()[OperationalTransformation]->asOrderedSet()->first();
	log(s.print(0));
}

helper printTabs(tabs : Integer) : String {
	var i := 0;
	var code := '';
	while (i < tabs) {
		code := code + _tab_;
		i := i + 1;
	}; 
	return code;
}

helper printArgs(list : OrderedSet(ecore::EObject)) : String {
	if (list->isEmpty()) then
		return ""
	endif;
	var code : String := list->first().print(0);	
	var rest := list->subOrderedSet(2, list->size());
	rest->forEach(expr) {
		code := code + ', ' + expr.print(0);
	};
	return code;
}

helper printArgs(list : OrderedSet(ecore::EModelElement)) : String {
	if (list->isEmpty()) then
		return ""
	endif;
	var code : String := list->first().print(0);	
	var rest := list->subOrderedSet(2, list->size());
	rest->forEach(expr) {
		code := code + ', ' + expr.print(0);
	};
	return code;
}


helper printArgs(list : OrderedSet(ocl::utilities::ASTNode)) : String {
	if (list->isEmpty()) then
		return ""
	endif;
	var code : String := list->first().print(0);	
	var rest := list->subOrderedSet(2, list->size());
	rest->forEach(expr) {
		code := code + ', ' + expr.print(0);
	};
	return code;
}

helper printExpressions(exprList : OrderedSet(ocl::ecore::OCLExpression), tabs : Integer) : String {
	var code : String;
	exprList->forEach(expr) {
		code := code + printTabs(tabs) + expr.print(tabs) + ';\n';
	};
	return code;
}

helper ecore::EObject::print(tabs : Integer) : String {
	var nameFeature := self.eClass().getEStructuralFeature('name');
	return self.eGet(nameFeature).oclAsType(String);
}

helper ecore::EStructuralFeature::print(tabs : Integer) : String {
	var code : String := self.name;
	return code;
}

helper ecore::EModelElement::print(tabs : Integer) : String {
	assert(true);
	return "";
}

helper ocl::utilities::ASTNode::print(tabs : Integer) : String {
	assert(true);
	return "";
}


helper OperationalTransformation::print(tabs : Integer) : String {
	var code : String := "";
	self.usedModelType->forEach(mt) {
		code := code + printTabs(tabs) + mt.print(0);
	};
    code := code + '\n' + printTabs(tabs) + 'transformation ' + self.name + '(';
    code := code + printArgs(self.modelParameter);
  	  	
    code := code + ');\n';
    
    self.configProperty->forEach(p) {
    	code := code + '\nconfiguration property ' + p.name + ' : ' + p.eType.name + ';\n';
    };
    
    var set := self.eAllStructuralFeatures - self.configProperty;
    
    set->forEach(p|p.oclIsKindOf(EAttribute)) {
    	var pa := p.oclAsType(EAttribute);
    	code := code + '\nproperty ' + pa.name + ' : ' + pa.eType.name;
    	code := code + ' = ' + pa.eAnnotations.contents->first().oclAsType(ocl::ecore::OCLExpression).print(0) + ';\n'; 
    };

    code := code + '\n' + self.entry.print(tabs);
    self.eOperations->forEach(op | op.oclIsKindOf(MappingOperation)) {
    	code := code + '\n' + op.oclAsType(MappingOperation).print(tabs);	
    };
    self.eOperations->forEach(op | op.oclIsKindOf(Helper)) {
    	code := code + '\n' + op.oclAsType(Helper).print(tabs);
    };
	return code;
}

helper ModelType::print(tabs : Integer) : String {
	var code : String := 'modeltype ' + self.name;
	if (self.conformanceKind != null) then {	
			code := code + ' "' + self.conformanceKind + '"';
	}
	endif;
	code := code + ' uses ';
	var package := self._metamodel->first();
	var meta : String := package.name;
	package := package.eSuperPackage;
	while (package != null) {
		meta := package.name + '::' + meta;
		package := package.eSuperPackage;
	};
	code := code + meta + '(' + self._metamodel->first().nsURI.quotify('\'') + ');' + '\n';
	return code;
}

helper ModelParameter::print(tabs : Integer) : String {
	var code : String := self.kind.repr() + ' ' + self.name + ': ' + self.eType.name;
	return code;
}

helper VarParameter::print(tabs : Integer) : String {
	var code : String := self.name + ' : ' + self.eType.name;
	return code;
}

helper EntryOperation::print(tabs : Integer) : String {
	var code : String = printTabs(tabs) + 'main() {\n';
	code := code + self.body.print(tabs + 1) + printTabs(tabs) + '}\n';
	return code;
}

helper Helper::print(tabs : Integer) : String {
	var code : String = printTabs(tabs) + 'helper ';
	if (self.context != null) then { 
		code := code + self.context.eType.name + '::';
	}
	endif;
	code := code + self.name;
	code := code + '(' + printArgs(self.eParameters) + ')';
	code := code + ' : ' + printArgs(self._result) + ' {\n';
	code := code + self.body.print(tabs + 1); 
	code := code + printTabs(tabs) + '}\n';
	return code;
}

helper MappingParameter::print(tabs : Integer) : String {
	var code : String := self.name + ' : ' + self.eType.name;
	return code;
}

helper MappingOperation::print(tabs : Integer) : String {
	var code : String = printTabs(tabs) + 'mapping ' + self.context.eType.name + '::' + self.name;
	code := code + '(' + printArgs(self.eParameters) + ')';
	code := code + ' : ' + printArgs(self._result);
	if (self._when->notEmpty()) then {
		code := code + '\n' + printTabs(tabs) + 'when { ' + self._when->first().print(0);
		var rest := self._when->asSequence()->subSequence(2, self._when->size());
		rest->forEach(expr) {
			code := code + '; ' + expr.print(0);
		};
		code := code + ' }';
	}
	endif;
	code := code + '\n' + printTabs(tabs) + '{\n';
	code := code + self.body.print(tabs + 1);
	code := code + printTabs(tabs) + '}\n'; 
	return code;
}

helper OperationBody::print(tabs : Integer) : String {
	var code : String := printExpressions(self.content, tabs);
	return code;
}

helper MappingBody::print(tabs : Integer) : String {
	var code : String;
	var needsPopulation := self.initSection->notEmpty();	
	if self.initSection->notEmpty() then {
		code := printTabs(tabs) + 'init {\n';
		code := code + printExpressions(self.initSection, tabs + 1);
		code := code + printTabs(tabs) + '}\n';
	} 
	endif;
	if needsPopulation then {
		code := code + printTabs(tabs) + 'population {\n';
		code := code + printExpressions(self.content, tabs + 1);
		code := code + printTabs(tabs) + '}\n';
	}
	else {
		code := code + printExpressions(self.content, tabs);
	}
	endif;
	if self.endSection->notEmpty() then {
		code := code + printTabs(tabs) + 'end {\n';
		code := code + printExpressions(self.endSection,tabs + 1);
		code := code + printTabs(tabs) + '}\n';
	}
	endif;
	
	return code;
}

helper MappingCallExp::print(tabs : Integer) : String {
	var code : String := self.source.print(0) + '.' + 'map ';
	code := code + self.referredOperation.print(0) + '(' + printArgs(self.argument) + ')';
	return code;
}


helper ImperativeIterateExp::print(tabs : Integer) : String {
	var code : String := self.source.print(0) + '->' + 
						 self.name + 
						 '(';
	var iter := self.iterator->first().repr();
	code := code + iter; 
	/*						 						  
	var iter := self.iterator->first().oclAsType(ocl::ecore::Variable);
	code := code + iter.name + ' : ' + iter.eType.name;
	self.iterator->subOrderedSet(2,self.iterator->size())->forEach(it) {
		iter := it.oclAsType(ocl::ecore::Variable);
		code := code + ', ' + iter.name + iter.eType.name;
	};
	*/
	if (self.body != null) then  
		code := code + '|' + self.body.print(0) 
	endif;
	if (self.condition != null) then  
		code := code + '|' + self.condition.print(0) 
	endif;
	code := code + ')';
	return code;
}

helper ImperativeLoopExp::print(tabs : Integer) : String {
	var code : String := self.source.print(0) + '->' + 
						 self.name + 
						 '(';
	var iter := self.iterator->first().repr();
	code := code + iter; 
	/*						 						  
	var iter := self.iterator->first().oclAsType(ocl::ecore::Variable);
	code := code + iter.name + ' : ' + iter.eType.name;
	self.iterator->subOrderedSet(2,self.iterator->size())->forEach(it) {
		iter := it.oclAsType(ocl::ecore::Variable);
		code := code + ', ' + iter.name + iter.eType.name;
	};
	*/
	if (self.condition != null) then {  
		code := code + '|' + self.condition.print(0)
	} 
	endif;
	
	code := code + ')';
	
	if (self.body != null) then  {
		code := code + self.body.print(tabs); 
	} 
	endif;
	
	return code;
}



helper ObjectExp::print(tabs : Integer) : String {
	var code : String := 'object ' + self.referredObject.name;
	code := code  + ' : ' + self.eType.name + ' {\n';
	code := code + self.body.print(tabs + 1);
	code := code + printTabs(tabs) + '}';
	return code;
}

helper SwitchExp::print(tabs : Integer) : String {
	var code : String := 'switch {\n';
	code := code + printExpressions(self.alternativePart, tabs + 1);
	if (self.elsePart != null) then {
		code := code + '\n' + printTabs(tabs + 1) + 'else ' + self.elsePart.print(tabs + 1);
	} 
	endif;
	code := code + '\n' + printTabs(tabs) + '}';
	return code;
}

helper AltExp::print(tabs : Integer) : String {
	var code : String := 'case ' + ' (' + self.condition.print(0) + ')\n';
	code :=  code + printTabs(tabs) + self.body.print(tabs);
	return code;
}

helper AssertExp::print(tabs : Integer) : String {
	var code : String := 'assert(' + self.assertion.print(0) + ')';
	return code;
}

helper AssignExp::print(tabs : Integer) : String {
	var code : String := self.left.print(0);
	code := code  + ' := ';
	self.value->forEach(expr) {
		code := code  + expr.print(0);
	};
	return code;
}

helper BlockExp::print(tabs : Integer) : String {
	var code : String := '{\n'; 
	code := code + printExpressions(self.body,tabs + 1);
	code := code + printTabs(tabs) + '}'; 	
	return code
}

helper BreakExp::print(tabs : Integer) : String {
	var code : String := 'break';
	return code;
}

helper CatchExp::print(tabs : Integer) : String {
	var code : String := 'catch';
	return code;
}

helper ComputeExp::print(tabs : Integer) : String {
	var code : String := 'compute(' + self.returnedElement.repr() + ') ';
	code := code + self.body.print(tabs);
	return code;
}

helper ContinueExp::print(tabs : Integer) : String {
	var code : String := 'continue';
	return code;
}

/*
helper ForExp::print(tabs : Integer) : String {
	var code : String := self.source
	return code;
}
*/


helper InstantiationExp::print(tabs : Integer) : String {
	var code : String := 'InstantiationExpNotImpl';
	return code;
}

helper DictLiteralPart::print(tabs : Integer) : String {
	var code : String := self.key.print(tabs) + ' = ' + self.value.print(tabs);
	return code;
}

helper DictLiteralExp::print(tabs : Integer) : String {
	var code : String := 'Dict { ';
	code := code + printArgs(self.part->asOrderedSet());
	code := code + ' }';
	return code;
}

helper ListLiteralExp::print(tabs : Integer) : String {
	var code : String := 'ListLiteralExpNotImpl';
	return code;
}

helper LogExp::print(tabs : Integer) : String {
	var code : String := 'log(' + printArgs(self.argument) + ')';
	return code;
}


helper RaiseExp::print(tabs : Integer) : String {
	var code : String := 'raise';
	return code;
}

helper ReturnExp::print(tabs : Integer) : String {
	var code : String := 'return ' + self.value.print(tabs); 
	return code;
}


helper TryExp::print(tabs : Integer) : String {
	var code : String := 'try';
	return code;
}

helper Typedef::print(tabs : Integer) : String {
	var code : String := 'typedef';
	return code;
}



helper UnlinkExp::print(tabs : Integer) : String {
	var code : String := 'unlink';
	return code;
}

helper UnpackExp::print(tabs : Integer) : String {
	var code : String := 'unpack';
	return code;
}

helper VariableInitExp::print(tabs : Integer) : String {
	var code := 'var ' + self.referredVariable.name + ' : ' + self.referredVariable.eType.name;
	if (self.referredVariable.initExpression != null) then {
		var iexp := self.referredVariable.initExpression;
		code := code + ' := ' + iexp.print(tabs);
	}
	endif;
	return code;
}

helper WhileExp::print(tabs : Integer) : String {
	var code : String := 'while (' + self.condition.print(0) + ') ';
	code := code + self.body.print(tabs);
	return code;
}

/*
helper ocl::ecore::VariableExp::print(tabs : Integer) : String {
	var code := self.name;
	return code;
}

helper ocl::expressions::VariableExp::print(tabs : Integer) : String {
	var code := self.referredVariable.print(0);
	return code;	
}

helper ocl::ecore::Variable::print(tabs : Integer) : String {
	var code := self.name;
	return code;
}

helper ocl::expressions::Variable::print(tabs : Integer) : String {
	var code : String;
	return code;
}




helper ocl::expressions::PropertyCallExp::print(tabs : Integer) : String {
	return null;
}

helper ocl::ecore::TypeExp::print(tabs : Integer) : String {
	var code : String := self.referredType.print(0);
	return code;	
}




helper ocl::ecore::CollectionLiteralExp::print(tabs : Integer) : String {
	var code := self.part->first().oclAsType(ocl::ecore::CollectionItem).item.print(0);
	return code;
}

helper ocl::expressions::CollectionLiteralExp::print(tabs : Integer) : String {
	var code := self.part->first().oclAsType(ocl::ecore::CollectionItem).item.print(0);
	return code;
}


helper ocl::expressions::StringLiteralExp::print(tabs : Integer) : String {
	var code : String := '\'' + self.stringSymbol + '\'';
	return code;
}

helper ocl::ecore::IntegerLiteralExp::print(tabs : Integer) : String {
	var code : String := self.integerSymbol.toString();
	return code;
}

helper ocl::expressions::IntegerLiteralExp::print(tabs : Integer) : String {
	var code : String := self.integerSymbol.toString();
	return code;
}

helper ocl::ecore::BooleanLiteralExp::print(tabs : Integer) : String {
	var code : String := if self.booleanSymbol = true then
							'true'
						 else 
						 	'false'
						 endif;
	return code;
}

helper ocl::ecore::EnumLiteralExp::print(tabs : Integer) : String {
	var code : String := self.eType.name + '::';
	code := code + self.referredEnumLiteral.print(0);
	return code;
}

helper ocl::expressions::BooleanLiteralExp::print(tabs : Integer) : String {
	var code : String := if self.booleanSymbol = true then
							'true'
						 else 
						 	'false'
						 endif;
	return code;
}



helper ocl::ecore::IteratorExp::print(tabs : Integer) : String {
	var code : String := self.source.print(0) + '->' + 
						 self.name + 
						 '(';						  
	var iter := self.iterator->first().oclAsType(ocl::ecore::Variable).print(0);
	code := code + iter; 
	
	//	var iter := self.iterator->first().oclAsType(ocl::ecore::Variable);
	//	code := code + iter.name + ' : ' + iter.eType.name;
	//	self.iterator->subOrderedSet(2,self.iterator->size())->forEach(it) {
	//		iter := it.oclAsType(ocl::ecore::Variable);
	//		code := code + ', ' + iter.name + iter.eType.name;
	//	};
	
	if (self.body != null) then  
		code := code + '|' + self.body.print(0) 
	endif;
	code := code + ')';
	return code;
}
*/

helper ocl::ecore::StringLiteralExp::print(tabs : Integer) : String {
	var code : String :=  self.stringSymbol.replace('\n','\\n').replace('\t','\\t').quotify('\'');
	return code;
}


helper ocl::ecore::OperationCallExp::print(tabs : Integer) : String {
	var code : String := self.source.print(0);
	if (self.source.getType().oclIsKindOf(ocl::ecore::CollectionType)) then {
		code := code + '->';
	}
	else {
		code := code + '.';
	}
	endif;
	code := code + self.referredOperation.oclAsType(ecore::EOperation).name + '(';
	code := code + printArgs(self.argument) + ')';
	
	return code;
}

helper ocl::ecore::PropertyCallExp::print(tabs : Integer) : String {
	var code : String := self.source.print(0);
	code := code + '.' + self.referredProperty.print(0);
	
	//Sequence{self.referredProperty}->switch(p) {
	//	case (p.oclIsKindOf(EAttribute)) {code := code + '.' + self.referredProperty.oclAsType(EAttribute).name}
	//	case (p.oclIsKindOf(EReference)) {code := code + '.' + self.referredProperty.oclAsType(EReference).name}
	//	else {} 
	//};
	
	return code;
}

helper ocl::ecore::IfExp::print(tabs : Integer) : String {
	var code : String := 'if ' + '(' + self.condition.print(0) + ')' + ' then ';
	code := code + self.thenExpression.print(tabs) + '\n';
	if self.elseExpression != null then {
		code := code + printTabs(tabs) + 'else ' + self.elseExpression.print(tabs) + '\n';
	}	
	endif;
	code := code + printTabs(tabs) + 'endif';
	return code;
}

helper ocl::ecore::OCLExpression::print(tabs : Integer) : String {
	var code : String := self.repr();
	return code;
}

helper ocl::expressions::OCLExpression::print(tabs : Integer) : String {
	var code : String := self.repr();
	return code;
}




Previous Topic:[ATL] Could we create an ATL rule without using the "TO" part
Next Topic:[AML] How to manage inherited properties?
Goto Forum:
  


Current Time: Wed Mar 03 02:36:46 GMT 2021

Powered by FUDForum. Page generated in 0.01639 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top