Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Reference Enum Literals of an Ecore model
Reference Enum Literals of an Ecore model [message #1851248] Thu, 31 March 2022 17:30 Go to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
Hello,

I have defined a DSL, and the instances of this DSL will mostly be used to references elements of other external Ecore models.

I am encountering issues when it comes to referencing EEnumLiterals. I am including a subset of the grammar in the following:

Root:
('main' main=[ecore::EObject|QualifiedName])?
;
QualifiedName:
	ID ('.' ID)* 
;


When I try to reference the EEnumLiteral that I want, in the tree editor, I get it as an alternative, but when I try to save it, it says there is an error. When I try to reference it from the textual file, I do not get it as an alternative at all.

Any idea what could be the issue, or how can it be resolved?

Thank you in advance!
John
Re: Reference Enum Literals of an Ecore model [message #1851249 is a reply to message #1851248] Thu, 31 March 2022 18:03 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
how did you implement scoping? did you check if enums are indexed?

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Reference Enum Literals of an Ecore model [message #1851283 is a reply to message #1851249] Fri, 01 April 2022 11:48 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
The enums are indexed, but I did not implement any scoping, cause I was getting everything I wanted until I came across EEnum Literals.

If I extend this a bit more to provide a better understanding, it would be the following grammar:

Load: 
('load' load+=Model)
;
Model:
	name=STRING?
		(model=[ecore::EPackage|EString])
	;
Root:
('main' main=[ecore::EObject|QualifiedName])?
;
QualifiedName:
	ID ('.' ID)* 
;


The possible alternatives in 'main' are EClasses,EReferences, EAttributes, and EEnumLiterals. I get the first three but not the EEnum Literals.

The qualified name should be as follows:
-For EClass : packageName.className
-For EReference: packageName.className.referenceName
-For EAttribute: packageName.className.attributeName
-For EEnumLiteral I would expect: packageName.Enum.EEnumLiteral


Does this necessarily require overriding the scope provider? If so, how could Iachieve that?

Many thanks!
Re: Reference Enum Literals of an Ecore model [message #1851291 is a reply to message #1851283] Fri, 01 April 2022 14:40 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
please check EcoreQualifiedNameProvider. i assume it does not support literals.
and so they are NOT indexed.
if they are indexed. check the name they are indexed


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Reference Enum Literals of an Ecore model [message #1851294 is a reply to message #1851291] Fri, 01 April 2022 15:52 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
Hi Christian,

sorry for bothering you with this. I checked all the files in the org.xtext.example.mydsl, both the ones generated from Xtext and the ones generated by the .genmodel. Could you please point me out on where I can find the EcoreQualifiedNameProvider. I was only able to find the online documentation and I do not see the EEnumLiterals : https://archive.eclipse.org/modeling/tmf/xtext/javadoc/2.1.0/org/eclipse/xtext/ecore/EcoreQualifiedNameProvider.html
Re: Reference Enum Literals of an Ecore model [message #1851301 is a reply to message #1851294] Fri, 01 April 2022 18:19 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
its in this plugin
https://github.com/eclipse/xtext-extras/blob/92c99efc47049adddc3e3e776f774c19f3278b79/org.eclipse.xtext.ecore/META-INF/MANIFEST.MF#L4


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Reference Enum Literals of an Ecore model [message #1851318 is a reply to message #1851294] Sat, 02 April 2022 09:48 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
This is how it looks like
/*******************************************************************************
 * Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.xtext.ecore;

import java.util.Collections;

import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.util.IResourceScopeCache;
import org.eclipse.xtext.util.PolymorphicDispatcher;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.util.Tuples;

import com.google.inject.Inject;
import com.google.inject.Provider;

/**
 * @author Jan Koehnlein - Initial contribution and API
 */
public class EcoreQualifiedNameProvider extends IQualifiedNameProvider.AbstractImpl {

	private PolymorphicDispatcher<String> nameDispatcher = new PolymorphicDispatcher<String>("name", 1, 1,
			Collections.singletonList(this), PolymorphicDispatcher.NullErrorHandler.<String> get()) {
		@Override
		protected String handleNoSuchMethod(Object... params) {
			return null;
		}
	};

	@Inject
	private IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE;

	@Override
	public QualifiedName getFullyQualifiedName(final EObject obj) {
		return cache.get(Tuples.pair(obj, getCacheKey()), obj.eResource(), new Provider<QualifiedName>() {

			@Override
			public QualifiedName get() {
				EObject temp = obj;
				String name = nameDispatcher.invoke(temp);
				if (Strings.isEmpty(name))
					return null;
				QualifiedName qualifiedName = QualifiedName.create(name);
				if(!isRecurseParent(obj))
					return qualifiedName;
				QualifiedName parentsQualifiedName = getFullyQualifiedName(obj.eContainer());
				if (parentsQualifiedName == null)
					return null;
				else 
					return parentsQualifiedName.append(qualifiedName);
			}

		});
	}

	protected boolean isRecurseParent(final EObject obj) {
		return obj.eContainer() != null;
	}

	protected String getCacheKey() {
		return "fqn";
	}

	protected String name(EPackage ePackage) {
		return ePackage.getName();
	}

	protected String name(EClassifier eClassifier) {
		return eClassifier.getName();
	}

	protected String name(EStructuralFeature eStructuralFeature) {
		return eStructuralFeature.getName();
	}

	protected String name(EOperation eOperation) {
		return eOperation.getName();
	}
}

Re: Reference Enum Literals of an Ecore model [message #1851319 is a reply to message #1851318] Sat, 02 April 2022 11:04 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
as i said: debug this class. check out if literals are indexed.
if no it wont work without custom scoping


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Reference Enum Literals of an Ecore model [message #1851321 is a reply to message #1851319] Sat, 02 April 2022 15:26 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
Hi Christian,

I tried what you said with the debugging. In line

return cache.get(Tuples.pair(obj, getCacheKey()), obj.eResource(), new Provider<QualifiedName>()


If I hover over obj, then at a certain point I do get the EEnumLiteral, but it never reaches

return parentsQualifiedName.append(qualifiedName);

it just skips to the other one.

Does that mean that EEnumLiterals are not indexed?
If so, is there any way I can reuse this code, to customise the scope provider to also get it for EEnumLiterals?

Many thanks!
Re: Reference Enum Literals of an Ecore model [message #1851322 is a reply to message #1851321] Sat, 02 April 2022 16:15 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Yes. I prepared a patch. You can find a preview version at
https://ci.eclipse.org/xtext/job/xtext-umbrella/job/cd_indexEEnumLiterals/lastSuccessfulBuild/artifact/build/p2-repository/


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Reference Enum Literals of an Ecore model [message #1851323 is a reply to message #1851322] Sat, 02 April 2022 16:17 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
An no you would have to use a different syntax for Emmis literals than
QualifiedNams if you want to use custom scoping
You need two references then
One to an enumeration and a 2nd to the literal


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Reference Enum Literals of an Ecore model [message #1851332 is a reply to message #1851323] Sun, 03 April 2022 09:43 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
Hi Christian,

Sorry I am not getting this part about the two references correctly. Is it not possible to have this qualified name in the following, only by the reference "main" in "Root":
The qualified name should be as follows:
-For EClass : packageName.className
-For EReference: packageName.className.referenceName
-For EAttribute: packageName.className.attributeName
-For EEnumLiteral I would expect: packageName.Enum.EEnumLiteral


When you say two references do you mean something like this?
[code]
main=[ecore::EObject|QualifiedName]( '.' literal=[ecore::EEnumLiteral])?
[\code]

If so, when I customise the custom provider in this case, should I do it for both references (main and literal), or only for literal and the main can have the default one that already has. Could you please provide some instructions on the steps that I have to follow to customise the scope provider ether if I need both references or only one?

Many thanks!
Re: Reference Enum Literals of an Ecore model [message #1851334 is a reply to message #1851332] Sun, 03 April 2022 10:55 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
No it's not. You need a reference to something that is in the index
Like the package oder enum
As a start point
So that YOU in scope provider can as it for the literals

Your grammar is ambiguous so it won't work in all cases
So you need a different syntax

Did you test my patch ?
In scope provider you would downcast


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Reference Enum Literals of an Ecore model [message #1851337 is a reply to message #1851334] Sun, 03 April 2022 11:43 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
I could not try the patch because I Tried Team -> ApplyPatch (tried both the url and the zip file but it says it does not contain a valid patch).

What I thought as a possible solution was the following.
In the scope provider, to first get the package (of the ecore metamodel that I am trying to reference) that contains the EEnumLiteral that I want. So reference would be MODEL__MODEL.

 (model=[ecore::EPackage|EString])


Then, get all the objects of this package and check if the enum chosen in "main", exists in this package. If it does,"literal" should return the values of the EEnumLiterals of that EEnum

main=[ecore::EObject|QualifiedName]( '.' literal=[ecore::EEnumLiteral])?


Would this make sense?
Re: Reference Enum Literals of an Ecore model [message #1851340 is a reply to message #1851337] Sun, 03 April 2022 12:24 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
No you need to instal the patch to your target platform or eclipse
And yes you need to implement scoping for that


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Reference Enum Literals of an Ecore model [message #1851376 is a reply to message #1851340] Mon, 04 April 2022 11:57 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
HI Christian,

I implemented scoping. I have only one issue now. For the moment I return all EEnumLiterals of all Enums in the metamodel. However, I want to check the type of EEnum defined in "main", to then only return the enumliterals of that enum. However, I cannot seem to get the EEnum, I only get EObject.

For the following example:
 main=[ecore::EObject|QualifiedName]( '.' literal=[ecore::EEnumLiteral])?


When I do

MyDslPackage.Literals.ROOT__MAIN.getEReferenceType()


I get EObject. I understand I get EObject because even in main I say reference EObjects, but is there a name to at least get the name? For example if in the textual model in "main" have a.b, can I at least get "b"?

Or is there any way I can check if it is an ENum? because if I do, I can then in literals only return the literals of that Enum.

[Updated on: Mon, 04 April 2022 12:11]

Report message to a moderator

Re: Reference Enum Literals of an Ecore model [message #1851382 is a reply to message #1851376] Mon, 04 April 2022 14:17 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
as i said
you need to cast context to
object that has
main=[ecore::EObject|QualifiedName]( '.' literal=[ecore::EEnumLiteral])?
and then have something like

// you may add an instaneof hwere too
LIst<EEnumLiterals> literals = ((EEnum)object.getMain()).getLiterals()) // pseudo code
IScope scope = Scopes.scopeFor(literaks)


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Mon, 04 April 2022 14:18]

Report message to a moderator

Re: Reference Enum Literals of an Ecore model [message #1851403 is a reply to message #1851382] Tue, 05 April 2022 06:33 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

The above advice is probably good, but a note of caution. EEnumLiterals are literals, just like integers, and so depending on quite how the EEnumLiteral was created you may find that the reflective context of the EEnum is lost. In extremis, the OCL support for oclType() of an EEnumLiteral occasionally has to do a search of all metaclasses to locate all enums and thereby determine which enum the EEnumLiteral is a literal of. With hindsight, the Ecore support for EEnumLiteral could have been just a little bit richer.

Regards

Ed Willink
Re: Reference Enum Literals of an Ecore model [message #1851415 is a reply to message #1851403] Tue, 05 April 2022 10:04 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
Hi,

Thank you both for your answers. I was finally able to fix it based on Christian's suggestions.
Sorry if I take more of your time with some additional questions :)

1. Is using two references the only possible solution in this case? As it somehow feels more as a trick than a solution and I was wondering if it is the most appropriate one, and why there is a need to do it like this? What did you mean by not indexed and do you have any information what is the reason for that?

2. Being that the rule is like this:
(main=[ecore::EObject|QualifiedName]( '.' literal=[ecore::EEnumLiteral])?)?
...
QualifiedName:
	ID ('.' ID)* 
;


I cannot actually generate Xtext Artefacts because after the dot there could either be an EEnumLiteral or another EObject. Thus, the only solution that came to my mind was to something something else instead of the dot such as:
(main=[ecore::EObject|QualifiedName]( '!' literal=[ecore::EEnumLiteral])?)?

However, is there a way, to tell xtext that if the Object in main is an EEnum then, after the dot there will be an EEnumLiteral in literal? So that I can still use the dot?

3. If I reference an object using the qualified name, lets say (a.b.c), if I just write c, then I do not get any suggestions, like I do in the tree editor. In the textual editor I have to write a.b first to then get suggestions about c. Is there anything I can do that the moment that I write c in the textual editor, I get all the qualified names leading to that?

Many thanks for all your help!
Re: Reference Enum Literals of an Ecore model [message #1851426 is a reply to message #1851415] Tue, 05 April 2022 13:52 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
you can also use the patched xtext verison but you dont want to :(
you can also use a different syntax. but you dont seem to want to


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Tue, 05 April 2022 13:54]

Report message to a moderator

Re: Reference Enum Literals of an Ecore model [message #1851429 is a reply to message #1851426] Tue, 05 April 2022 14:13 Go to previous messageGo to next message
John Henbergs is currently offline John HenbergsFriend
Messages: 239
Registered: October 2020
Senior Member
I was having some issues trying to install the patch.

As for the second point, would you suggest a particular syntax to allow using only one reference, "main" , let's say?
Re: Reference Enum Literals of an Ecore model [message #1851434 is a reply to message #1851429] Tue, 05 April 2022 14:48 Go to previous message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Enum -> literal

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Previous Topic:Xtext String no quotes
Next Topic:Xtext and Log4j/Reload4j
Goto Forum:
  


Current Time: Thu Mar 28 08:45:34 GMT 2024

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

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

Back to the top