ScopeProvider and Linker [message #1763891] |
Mon, 22 May 2017 12:38  |
Eclipse User |
|
|
|
Hi all
I have this metamodel
package fsm : fsm = 'http://fsm'
{
class FSM
{
property ownedState#owningFSM : State[*|1] { ordered composes };
}
class State
{
property owningFSM#ownedState : FSM[1];
attribute name : String[?];
property outgoingTransition#source : Transition[*|1] { ordered composes };
property incomingTransition#target : Transition[*|1] { ordered };
attribute initial : Boolean[1];
attribute final : Boolean[1];
}
class Transition
{
property source#outgoingTransition : State[1];
property target#incomingTransition : State[1];
attribute input : String[?];
attribute output : String[?];
}
primitive datatype _'String' : 'java.lang.String' { serializable };
}
I generate a Xtext grammar from this metamodel
// automatically generated by Xtext
grammar org.xtext.example.fsm.FSM with org.eclipse.xtext.common.Terminals
import "http://fsm"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
FSM returns FSM:
{FSM}
'FSM'
'{'
('ownedState' '{' ownedState+=State ( "," ownedState+=State)* '}' )?
'}';
State returns State:
initial?='initial'
final?='final'
'State'
'{'
('name' name=ID)?
('outgoingTransition' '{' outgoingTransition+=Transition ( "," outgoingTransition+=Transition)* '}' )?
'}';
Transition returns Transition:
'Transition'
'{'
('input' input=STRING)?
('output' output=STRING)?
'target' target=[State|ID]
'}';
In order to manage the eopposite relation target <--> incomingTransition
I create a FSMLinker class
public class FSMLinker extends LazyLinker {
@Override
protected EObject createProxy(EObject obj, INode node, EReference eRef) {
State s = (State) ((Transition)obj).eContainer();
FSM fsm = (FSM) s.eContainer();
for (State state : fsm.getOwnedState())
if(state.getName().equals(node.getText())){
return state;
}
return super.createProxy(obj, node, eRef);
}
}
I manage also the scope provider by editing FSMScopeProvider
class FSMScopeProvider extends AbstractFSMScopeProvider {
override getScope(EObject object, EReference ref) {
if (object instanceof Transition) {
scope_Transition_target(object as Transition, ref)
}
}
def scope_Transition_target(Transition transition, EReference reference) {
var ArrayList<IEObjectDescription> res = new ArrayList<IEObjectDescription>
var State s = transition.eContainer as State
var FSM fsm = s.eContainer as FSM
for (state : fsm.ownedState) {
res.add(EObjectDescription.create(state.name, state))
}
return new SimpleScope(IScope.NULLSCOPE, res)
}
}
When I create a model like this
FSM{
ownedState
{
initial final State { name s1 outgoingTransition {Transition {
input "did" output "aa" target s1
}
}},
initial final State { name s2 }
}
}
no error is happened.
However, when i change the model to be like that
FSM{
ownedState
{
initial final State { name s1 outgoingTransition {Transition {
input "did" output "aa" target s2
}
}},
initial final State { name s2 }
}
}
An error appears
- The required feature 'target' of 'fsm.impl.TransitionImpl@58395231{platform:/resource/fsm/test.fsm#//@ownedState.0/@outgoingTransition.0}' must be set
Any suggestion?
|
|
|
|
|
|
|
|
|
|
Re: ScopeProvider and Linker [message #1763946 is a reply to message #1763920] |
Tue, 23 May 2017 05:42   |
Eclipse User |
|
|
|
For me also the test is fine.
For the tested model
FSM{
ownedState
{
initial final State { name s1 outgoingTransition {Transition {
input "did" output "aa" target s2
}
}},
initial final State { name s2 }
}
}
when, I test parse it, I obtain the correct xmi
<?xml version="1.0" encoding="ASCII"?>
<fsm:FSM xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:fsm="http://fsm">
<ownedState name="s1" initial="true" final="true">
<outgoingTransition target="//@ownedState.1" input="did" output="aa"/>
</ownedState>
<ownedState name="s2" incomingTransition="//@ownedState.0/@outgoingTransition.0" initial="true" final="true"/>
</fsm:FSM>
However, when I Run my toxmi method
I obtain the following without incomingTransition
<?xml version="1.0" encoding="ASCII"?>
<fsm:FSM xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:fsm="http://fsm">
<ownedState name="s1" initial="true" final="true">
<outgoingTransition target="//@ownedState.1" input="did" output="aa"/>
</ownedState>
<ownedState name="s2" initial="true" final="true"/>
</fsm:FSM>
This is my code used to save as xmi.
public void run(IAction action) {
IFile file = getFile();
URI xtextURI = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
XtextResourceSet resourceSet = new XtextResourceSet();
Resource xtextResource = resourceSet.createResource(xtextURI);
System.out.println(xtextURI.toString());
if (xtextResource != null){
Map<String,Boolean> options = new HashMap<String,Boolean>();
options.put(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
try {
xtextResource.load(options);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Resource xmiResource = new XMIResourceFactoryImpl().createResource(xtextURI.trimFileExtension().appendFileExtension("xmi"));
xmiResource.getContents().add(xtextResource.getContents().get(0));
EcoreUtil.resolveAll(resourceSet);
try {
xmiResource.save(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
ModelStatus sts = new ModelStatus(IStatus.ERROR, "org.eclipse.xtext.toXmi", "http://fsm", "Impossible to load the selected file for xmi conversion.\n" +
"Maybe this file is not an XText instance ? Status");
ErrorDialog.openError(shell, "Error", "Impossible to load the selected file for xmi conversion.\n" +
"Maybe this file is not an XText instance ?", sts);
}
}
Is it correct, PLZ ?
|
|
|
|
Re: ScopeProvider and Linker [message #1763964 is a reply to message #1763952] |
Tue, 23 May 2017 08:49   |
Eclipse User |
|
|
|
I update my toXmi class
public void run(IAction action) {
IFile file = getFile();
Injector injector = FsmActivator.getInstance().getInjector("org.xtext.example.fsm.FSM");
XtextResourceSetProvider provider = injector.getInstance(XtextResourceSetProvider.class);
ResourceSet resourceSet = provider.get(file.getProject());
URI xtextURI = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
XtextResource xtextResource = (XtextResource) resourceSet.getResource(xtextURI, true);;
if (xtextResource != null){
Map<String,Boolean> options = new HashMap<String,Boolean>();
options.put(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
try {
xtextResource.load(options);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Resource xmiResource = new XMIResourceFactoryImpl().createResource(xtextURI.trimFileExtension().appendFileExtension("xmi"));
xmiResource.getContents().add(xtextResource.getContents().get(0));
EcoreUtil.resolveAll(resourceSet);
try {
xmiResource.save(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
ModelStatus sts = new ModelStatus(IStatus.ERROR, "org.eclipse.xtext.toXmi", "http://fsm", "Impossible to load the selected file for xmi conversion.\n" +
"Maybe this file is not an XText instance ? Status");
ErrorDialog.openError(shell, "Error", "Impossible to load the selected file for xmi conversion.\n" +
"Maybe this file is not an XText instance ?", sts);
}
}
I obtain that
<?xml version="1.0" encoding="ASCII"?>
<fsm:FSM xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:fsm="http://fsm">
<ownedState name="s1" initial="true" final="true">
<outgoingTransition input="did" output="aa">
<target href="My.fsm#|0"/>
</outgoingTransition>
</ownedState>
<ownedState name="s2" initial="true" final="true"/>
</fsm:FSM>
No IncomingTransition and target reference is not correct.
Plz, Christian, Does exist an example that can be followed to create my own toxmi module for my dsl?
best regards
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03092 seconds