Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Using results from language interpreter in JavaValidator(Looking for correct way to add information from interpreted language in runtime tasks)
icon5.gif  Using results from language interpreter in JavaValidator [message #697371] Sat, 16 July 2011 12:34 Go to next message
Jonathan Blakes is currently offline Jonathan BlakesFriend
Messages: 4
Registered: February 2011
Junior Member
[This is from a question I incorrectly asked on the Xtext 2.0 documentation disqus.]

I am creating an interpreted language. After editing and saving a language file my IXtextBuilderParticipant interprets the file to provide information to several Eclipse Views about the results. I would also like to somehow be able to use these results in my JavaValidator so that it can provide feedback in the XtextEditor about which operations caused problems.

My inital attempt used a private variable in the JavaValidator in which I store the results of the interpreter to which I pass the root EObject of my grammar:

public MyDSLJavaValidator extends AbstractMyDSLJavaValidator {

	private Result result;

	@Check
	public void checkRoot(Root root) {
		result = new Interpreter().interpret(root);
	}

	@Check
	public void checkSomething(Something something) {
		// regular checking
		if (result != null) {
			// result aware checking
		}
	}


But @szarnekow responded with:

Quote:
You should not store the result in the validator as the instance will be shared for different resources. Attach the result to the resource instead (probably as an EAdapter). I'd recommend to use the IResourceScopeCache.


Which sounds like exactly what I wanted (I saw that the validator was meant to be a singleton from the RuntimeModule but didn't know how to get around this).
Unfortunately I don't see how I can implement this suggestion, can anyone here offer me an example that does so? (Googling was not successful)

I know that I can get an IResourceScopeCache by injection but how do I:

a) set a value in the cache so I can retrieve it?

b) attach the result to the resource using an EAdapter? (which seems to be used for notifications not storage)

Other questions I have are:

c) Does the check method for the Root EObject get called before the others? And if not is there a way to have it do so to ensure that the result is available to all the other check methods (providing it can be correctly interpreted)?

d) can I have 2 JavaValidators, one with the results and one without? Would this be inefficient?

Thanks,

Jon

Edit: the thread title "Hook after edits" also refers to the same ideas but without providing a concrete answer.

[Updated on: Sat, 16 July 2011 14:43]

Report message to a moderator

Re: Using results from language interpreter in JavaValidator [message #697685 is a reply to message #697371] Sun, 17 July 2011 18:02 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3118
Registered: July 2009
Senior Member
Hi Jon,

(a) + (b) simply use something along these lines:

@Inject
private IResourceScopeCache cache;

public Result getInterpreterResult(EObject obj) {
final Root root = EcoreUtil.getRootContainer(obj);
Result = cache.get("interpreter.result", root.eResource(), new
Provider<Result>() {
public Result get() {
return new Interpreter().interpret(root);
}
});
return result;
}

The cache ensures that the result is only computed once as long as the
objects don't change.

(c) Yes that is ensured but it doesn't matter if you use the cache.
(d) I don't understand the question. You can use as many validators as
you want. Simply register your additional validators in the same way as
the generated validator is registered in the
AbstractYourLangRuntimeModule. Whether that's efficient or not depends
on your validation rules.

Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com

On 16.07.11 14:34, forums-noreply@eclipse.org wrote:
> [This is from a question I incorrectly asked on the Xtext 2.0
> documentation disqus.]
>
> I am creating an interpreted language. After editing and saving a
> language file my IXtextBuilderParticipant interprets the file to provide
> information to several Eclipse Views about the results. I would also
> like to somehow be able to use these results in my JavaValidator so that
> it can provide feedback in the XtextEditor about which operations caused
> problems.
>
> My inital attempt used a private variable in the JavaValidator in which
> I store the results of the interpreter to which I pass the root EObject
> of my grammar:
>
>
> public MyDSLJavaValidator extends AbstractMyDSLJavaValidator {
>
> private Result result;
>
> @Check
> public void checkRoot(Root root) {
> result = new Interpreter().interpret(root);
> }
>
> @Check
> public void checkSomething(Something something) {
> // regular checking
> if (result != null) {
> // result aware checking
> }
> }
>
>
> But @szarnekow responded with:
>
> Quote:
>> You should not store the result in the validator as the instance will
>> be shared for different resources. Attach the result to the resource
>> instead (probably as an EAdapter). I'd recommend to use the
>> IResourceScopeCache.
>
>
> Which sounds like exactly what I wanted (I saw that the validator was
> meant to be a singleton from the RuntimeModule but didn't know how to
> get around this).
> Unfortunately I don't see how I can implement this suggestion, can
> anyone here offer me an example that does so? (Googling was not successful)
>
> I know that I can get an IResourceScopeCache by injection but how do I:
>
> a) set a value in the cache so I can retrieve it?
>
> b) attach the result to the resource using an EAdapter? (which seems to
> be used for notifications not storage)
>
> Other questions I have are:
>
> c) Does the check method for the Root EObject get called before the
> others? And if not is there a way to have it do so to ensure that the
> result is available to all the other check methods (providing it can be
> correctly interpreted)?
>
> d) can I have 2 JavaValidators, one with the results and one without?
> Would this be inefficient?
>
> Thanks,
>
> Jon
Re: Using results from language interpreter in JavaValidator [message #697862 is a reply to message #697685] Mon, 18 July 2011 08:26 Go to previous messageGo to next message
Jonathan Blakes is currently offline Jonathan BlakesFriend
Messages: 4
Registered: February 2011
Junior Member
Hello Sebastian.

Thanks for answering my questions.

I can see how to add a second validator now (d) - I thought it would override the other one but the methods are named after the class not the interface so that is OK.

(a + b) I had cobbled together the following, but your answer is much neater and I will try that.

public class MyDslValidator extends AbstractDNAplJavaValidator {

	@Inject
	private IResourceScopeCache resourceScopeCache;
	
	/**
	 * Used by getRegisteredAdapter to obtain the ResourceAdapter. 
	 */
	class Type {}
	
	/* 
	 * Sebastian Zarnekow wrote, in response to Jonathan Blakes:
	 * You should not store the result in the validator as the instance will
	 * be shared for different resources. Attach the result to the resource 
	 * instead (probably as an EAdapter). I'd recommend to use the 
	 * IResourceScopeCache. 
	 */
	/**
	 * Used to add functionality to the current resource (like the result of the
	 * interpretation) and cache it in such a way that it is discard as soon as
	 * the model changes.
	 */
	class ResourceAdapter extends AdapterImpl {
		private Root root;
		public ResourceAdapter(Root root) {
			this.root = root;
		}
		public boolean isAdapterForType(Object type) {
			if (type == Type.class) 
				return true;
			return false;
		}
		public Result getResult() {
			return resourceScopeCache.get("Root", root.eResource(), new Provider<Result>() {
				public Result get() {
					Interpreter interpreter = new Interpreter(root);
					return interpreter.getResult();
				}
			);
		}
	
	/**
	 * Add a ResourceAdapter to the resource being validated.
	 * @param root The root EObject of the grammar.
	 */
	@Check
	public void checkRoot(final Root root) {
		// Add a ResourceAdapter to the resource being validated
		EList<Adapter> adapters = root.eResource().eAdapters();
		if (Iterables.isEmpty((Iterables.filter(adapters, ResourceAdapter.class)))) {
			adapters.add(new ResourceAdapter(root));
		}
	}
	
	/**
	 * Accessor that goes via a ResourceAdapter to get the cached Result.
	 */
	private Result getResult() {
		return ((ResourceAdapter) EcoreUtil.getRegisteredAdapter(getCurrentObject().eResource(), Type.class)).getResult();
	}
	
	@Check
	public void checkSomething(Something something) {
               Result = getResult();
               ...


How come you didn't use an eAdapter as you suggested before? I this there anything wrong with the approach that I used?

Best regards,

Jon
Re: Using results from language interpreter in JavaValidator [message #697907 is a reply to message #697862] Mon, 18 July 2011 10:28 Go to previous message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3118
Registered: July 2009
Senior Member
Hi Jon,

the resource scope cache uses the adapter approach internally. Sorry for
any confusion that I caused with the reference to EAdapter.

Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com

On 18.07.11 10:26, forums-noreply@eclipse.org wrote:
> Hello Sebastian.
>
> Thanks for answering my questions.
> I can see how to add a second validator now (d) - I thought it would
> override the other one but the methods are named after the class not the
> interface so that is OK.
>
> (a + b) I had cobbled together the following, but your answer is much
> neater and I will try that.
>
>
> public class MyDslValidator extends AbstractDNAplJavaValidator {
>
> @Inject
> private IResourceScopeCache resourceScopeCache;
>
> /**
> * Used by getRegisteredAdapter to obtain the ResourceAdapter. */
> class Type {}
>
> /* * Sebastian Zarnekow wrote, in response to Jonathan Blakes:
> * You should not store the result in the validator as the instance will
> * be shared for different resources. Attach the result to the resource *
> instead (probably as an EAdapter). I'd recommend to use the *
> IResourceScopeCache. */
> /**
> * Used to add functionality to the current resource (like the result of the
> * interpretation) and cache it in such a way that it is discard as soon as
> * the model changes.
> */
> class ResourceAdapter extends AdapterImpl {
> private Root root;
> public ResourceAdapter(Root root) {
> this.root = root;
> }
> public boolean isAdapterForType(Object type) {
> if (type == Type.class) return true;
> return false;
> }
> public Result getResult() {
> return resourceScopeCache.get("Root", root.eResource(), new
> Provider<Result>() {
> public Result get() {
> Interpreter interpreter = new Interpreter(root);
> return interpreter.getResult();
> }
> );
> }
>
> /**
> * Add a ResourceAdapter to the resource being validated.
> * @param root The root EObject of the grammar.
> */
> @Check
> public void checkRoot(final Root root) {
> // Add a ResourceAdapter to the resource being validated
> EList<Adapter> adapters = root.eResource().eAdapters();
> if (Iterables.isEmpty((Iterables.filter(adapters,
> ResourceAdapter.class)))) {
> adapters.add(new ResourceAdapter(root));
> }
> }
>
> /**
> * Accessor that goes via a ResourceAdapter to get the cached Result.
> */
> private Result getResult() {
> return ((ResourceAdapter)
> EcoreUtil.getRegisteredAdapter(getCurrentObject().eResource(),
> Type.class)).getResult();
> }
>
> @Check
> public void checkSomething(Something something) {
> Result = getResult();
> ...
>
>
> How come you didn't use an eAdapter as you suggested before? I this
> there anything wrong with the approach that I used?
>
> Best regards,
>
> Jon
Previous Topic:Beginner : need xtend help
Next Topic:Creating an Action to Open the Xtext Project Wizard
Goto Forum:
  


Current Time: Thu Mar 28 13:22:19 GMT 2024

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

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

Back to the top