Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Problem with scopes
Problem with scopes [message #893350] Tue, 03 July 2012 16:14 Go to next message
Sergio Otero is currently offline Sergio OteroFriend
Messages: 37
Registered: June 2012
Member
Hi

I've succesfully written scopes definitions using xtend if the referenced objects can be accesible via EMF

	def IScope scope_Origin_atr(Origin or, EReference ref) {
		Scopes::scopeFor(or.navigateEMF.allReferencesINeed)
	}


Now i have another case where from all default referenced objects, i want to remove some of them using a condition. I've tried several combinations, but i haven't been able:

	def IScope scope_OtherOrigin_atr(OtherOrigin or, EReference ref) {
		val baseScope = super.delegateGetScope(or, ref)
		//Remove some of the elements in baseScope
		val filteredScope = baseScope
		
		filteredScope
	}	


Any idea?

Thanks

Sergio

Re: Problem with scopes [message #893358 is a reply to message #893350] Tue, 03 July 2012 16:44 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13366
Registered: July 2009
Senior Member
Hi ca you elaborate a bit on the kind of condition/filtering you are
talking about and e.g. come up with an example

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext at itemis dot de


Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/xtext/
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Problem with scopes [message #893377 is a reply to message #893350] Tue, 03 July 2012 18:39 Go to previous messageGo to next message
Sergio Otero is currently offline Sergio OteroFriend
Messages: 37
Registered: June 2012
Member
Hi

I'll try to define the problem using a variation of the Martin Fowler example (and writing without Eclipse, so maybe there are some errors)

Imagine that when selecting the State in a Transition, you don't want all available States, but only States without Actions (i know it doesn't make sense here, it's only a example).

Transition: event=[Event] '=>' state=[State]


You can accomplish that doing:

def IScope scope_Transition_state(Transition t, EReference ref) {
		Scopes::scopeFor(t.stateMachine.states.filter[s | s.actions.size == 0])
	}

	def Statemachine stateMachine(Transition t) {
		// navigate from transition to it's parent Statemachine
	}


Suppose you change the grammar to support the definition of events, commands and states in separated files

From:

Statemachine :
  'events'
  (events+=Event)+
  'end'
  ('resetEvents'
  (resetEvents+=[Event])+
  'end')?
  'commands'
  (commands+=Command)+
  'end'
  (states+=State)+;


To

Statemachine: Event | Command | State


Only with this change, you can define in separate files Events, Commands and States and references like "Transition: event=[Event] '=>' state=[State];" continue to work perfectly.

The problem is that now i cannot do the "trick" of browsing the EMF model to do the scoping.

Instead of that, i would need to get the default proposal and filter those that have 0 actions (this is only an alternative without the grammar change):

def IScope scope_Transition_state(Transition t, EReference ref) {
		val baseScope = super.delegateGetScope(t, ref)

		// I don't know how to filter here the object IScope
		
		baseScope
	}


I've tried to use FilteringScope with a closure like you suggested in other thread (http://www.eclipse.org/forums/index.php/m/802897/). More or less like that:

val filtscope = new FilteringScope(baseScope, [iod| EObjectOrProxy instanceof State])


It's not testing if the State has 0 actions, but even that returns false because the object is a proxy, not the State.

Maybe digging more inside IEObjectDescription i could get it to work, but something tells me this is not the best way Embarrassed

If you need more clarifications, please tell me.

Thanks

Sergio
Re: Problem with scopes [message #893391 is a reply to message #893377] Tue, 03 July 2012 19:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 13366
Registered: July 2009
Senior Member
Hi,

Using this example you a facing a lot of problems/restrictions at the same time.
never the less lets give it a try, (using the fowler sample of xtext 2.2.1)

(0) change grammar to allow only one thing in one file and states having zero actions

(1) we want to store the information of a State having actions in the index. since indexing is done at a state where no cross refs exists/are linked we could do something like ....
sadly the hooks for such things are still far away from being perfect,

public class StatenachineResourceDescriptionStrategy extends
		DefaultResourceDescriptionStrategy {
	
	public static final String HAS_ACTIONS = "HAS_ACTIONS";
	
	@Override
	public boolean createEObjectDescriptions(EObject eObject,
			IAcceptor<IEObjectDescription> acceptor) {
		if (eObject instanceof State) {
			return createStateDescriptions((State) eObject, acceptor);
		}
		return super.createEObjectDescriptions(eObject, acceptor);
	}
	
	public boolean createStateDescriptions(State state, IAcceptor<IEObjectDescription> acceptor) {
		if (getQualifiedNameProvider() == null)
			return false;
		try {
			QualifiedName qualifiedName = getQualifiedNameProvider().getFullyQualifiedName(state);
			if (qualifiedName != null) {
				Map<String, String> data = new HashMap<String, String>();
				data.put(HAS_ACTIONS, Boolean.toString(NodeModelUtils.findNodesForFeature(state, StatemachinePackage.Literals.STATE__ACTIONS).size() > 0));
				acceptor.accept(EObjectDescription.create(qualifiedName, state, data ));
			}
		} catch (Exception exc) {
			exc.printStackTrace();
		}
		return true;
	}

}


and bind it in the runtime module

public Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
		return StatenachineResourceDescriptionStrategy.class;
	}


finally we use the data in the scope provider

public class StatemachineScopeProvider extends AbstractDeclarativeScopeProvider {
	
	public IScope scope_Transition_state(Transition t, EReference ref) {
		return new FilteringScope(delegateGetScope(t, ref), new Predicate<IEObjectDescription>() {
			
			@Override
			public boolean apply(IEObjectDescription input) {
				String hasActions = input.getUserData(StatenachineResourceDescriptionStrategy.HAS_ACTIONS);
				return hasActions != null && !Boolean.valueOf(hasActions);
			}
		});
	}

}


please note: (if states and transitions are defined in the same file) you have to do a second adoptions for the local resource

public class StatemchineImportedNamespaceAwareLocalScopeProvider extends
		ImportedNamespaceAwareLocalScopeProvider {
	
	@Inject
	private IQualifiedNameProvider qualifiedNameProvider;

	@Override
	protected ISelectable internalGetAllDescriptions(final Resource resource) {
		Iterable<EObject> allContents = new Iterable<EObject>(){
			public Iterator<EObject> iterator() {
				return EcoreUtil.getAllContents(resource, false);
			}
		}; 
		Iterable<IEObjectDescription> allDescriptions = scopedElementsFor2(allContents, qualifiedNameProvider);
		return new MultimapBasedSelectable(allDescriptions);
	}
	

	public  <T extends EObject> Iterable<IEObjectDescription> scopedElementsFor2(Iterable<? extends T> elements,
			final Function<T, QualifiedName> nameComputation) {
		Iterable<IEObjectDescription> transformed = Iterables.transform(elements,
				new Function<T, IEObjectDescription>() {
					public IEObjectDescription apply(T from) {
						final QualifiedName qualifiedName = nameComputation.apply(from);
						Map<String, String> data = new HashMap<String, String>();
						if (from instanceof State) {
							data.put(StatenachineResourceDescriptionStrategy.HAS_ACTIONS,Boolean.toString(((State)from).getActions().size() > 0));
							if (qualifiedName != null) 
								return new EObjectDescription(qualifiedName, from, data );
						} else {
							if (qualifiedName != null) 
								return new EObjectDescription(qualifiedName, from, null );
						}
						
						return null;
					}
				});
		return Iterables.filter(transformed, Predicates.notNull());
	}
}


and again do the binding

public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
		binder.bind(IScopeProvider.class).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(StatemchineImportedNamespaceAwareLocalScopeProvider.class);
	}


~Christian

--
Need training, onsite consulting or any other kind of help for Xtext?
Go visit http://xtext.itemis.com or send a mail to xtext@itemis.de
Re: Problem with scopes [message #893394 is a reply to message #893391] Tue, 03 July 2012 20:18 Go to previous message
Sergio Otero is currently offline Sergio OteroFriend
Messages: 37
Registered: June 2012
Member
In my case, changing the grammar doesn't solve it because it's a semantic problem (i think so), so i'll adapt the solution to my problem and i think it'll work.

Anyway, for a more complex condition involving not only the referenced node but also properties of it's childs, maybe it'll be more scalable to do a validation that trying to compute all the posible choices.

Thanks

Sergio
Previous Topic:IXtextDocument.modify consumes all preceding white space
Next Topic:How to create non-printable ASCII chars as terminal rules?
Goto Forum:
  


Current Time: Wed Feb 26 17:00:22 GMT 2020

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

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

Back to the top