Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » cross-reference with modified name
cross-reference with modified name [message #1799466] Fri, 07 December 2018 10:19 Go to next message
Ravi Nallappan is currently offline Ravi NallappanFriend
Messages: 12
Registered: September 2014
Junior Member
Hi,

How do we make a language cross-reference to an object from another language/model with slightly different label?

Let me try to describe this further by giving a simplified scenario:

    1. I have language A with Definition as one of a class.


    2. My language B cross-reference the definition from model A.


    3. My language C also cross-reference the definition from model A.


    4. All above are working well. However, there is further requirements that B and C should display the definition slightly differently. e.g

      a. Say language A has definition 'Def1', 'Def2' and 'Def3'


      b. Now language B need to cross-reference as all in uppercase i.e 'DEF1', 'DEF2' and 'DEF3'


      c. Now language C need to cross-reference as all in lowercase i.e 'def1', 'def2' and 'def3'



    5. What this means is language B and C even though they refer to same definition object but each should render the label on their own way. Also I want the go-to-declaration feature to work.

    Maybe what I am looking for is something like from
    schemaName=[mib::Definition|MIB_ID]
    to
    schemaName=[mib::Definition.ucName|MIB_ID]



I am open to any suggestion. Thanks.
Re: cross-reference with modified name [message #1799467 is a reply to message #1799466] Fri, 07 December 2018 10:22 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
have a look what xtext does for imports with AliasedEObjectDescription.
alterantively: index the elements under two names: adapt DefaultResourceDescriptionStrategy.
store for the names which variant they are in the user data.
in scoping use userdata to filter the correct name variant


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: cross-reference with modified name [message #1799486 is a reply to message #1799467] Fri, 07 December 2018 16:03 Go to previous messageGo to next message
Ravi Nallappan is currently offline Ravi NallappanFriend
Messages: 12
Registered: September 2014
Junior Member
Here is what I have tried:

class LanguageBScopeProvider extends AbstractLanguageBScopeProvider {
	override getScope(EObject context, EReference reference) {
		if (context instanceof TableExpression) {
			if (reference == XcorePackage.Literals.TABLE_EXPRESSION__SCHEMA_NAME) {
				val scope = super.getScope(context, reference)
				val defs = scope.allElements.map([ d |
					new AliasedEObjectDescription(QualifiedName.create(d.name.firstSegment.toUpperCase), d)
				]).map([d|d as IEObjectDescription])
				return new SimpleScope(defs)
			}
		}
		super.getScope(context, reference)
	}
}


This allows the language B accepts language A's Definition object in lower case. However, the content assist still shows the definitions in original forms. (i.e Once selected, need to manually change case)

Anything I have done above is wrong? Or do I need to manually handle LanguageBProposalProvider as well? Thanks.


Corresponding Language B grammar:

TableExpression:
	(schemaName=[mib::Definition|MIB_ID] '.' tableName=[mib::Identifier] | '(' select=SelectStatement ')')
	('AS'? tableAlias=ID)?;
Re: cross-reference with modified name [message #1799488 is a reply to message #1799486] Fri, 07 December 2018 16:16 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Don't understand. Each DSL has its own scopeprovider

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: cross-reference with modified name [message #1799492 is a reply to message #1799488] Fri, 07 December 2018 16:56 Go to previous messageGo to next message
Ravi Nallappan is currently offline Ravi NallappanFriend
Messages: 12
Registered: September 2014
Junior Member
Let me clarify.

The above code does allow me write def1 in language B to refer to Def1. However the autocomplete list still lists down as Def1, Def2 etc.

Is the later is expected? How do I fix it?
Re: cross-reference with modified name [message #1799498 is a reply to message #1799492] Fri, 07 December 2018 17:51 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
The scoping in b is done in b

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: cross-reference with modified name [message #1799584 is a reply to message #1799498] Mon, 10 December 2018 14:53 Go to previous messageGo to next message
Ravi Nallappan is currently offline Ravi NallappanFriend
Messages: 12
Registered: September 2014
Junior Member
Managed to reproduce the issue with simple LangA and LangB used in above example.

Here is xtext grammar for Lang A

grammar org.xtext.example.crr.langa.LangA with org.eclipse.xtext.common.Terminals

generate langA "http://www.xtext.org/example/crr/langa/LangA"

Model:
	definitions+=Definition*;
	
Definition:
	'set' name=ID 'as' value=INT;


Here is xtext grammar for Lang B

grammar org.xtext.example.crr.langb.LangB with org.eclipse.xtext.common.Terminals

generate langB "http://www.xtext.org/example/crr/langb/LangB"
import "http://www.xtext.org/example/crr/langa/LangA" as langA

Model:
	uses1+=Use1*
	uses2+=Use2*;

Use1:
	'use1' name=[langA::Definition]
;
	
Use2:
	'use2' name=UseRef ;

UseRef:
	name=[langA::Definition]
;


And LangA definition has been eobject aliased in LangB's scope as follow:

class LangBScopeProvider extends AbstractLangBScopeProvider {
	override getScope(EObject context, EReference reference) {
		if (context instanceof Use1) {
			if (reference == LangBPackage.Literals.USE1__NAME) {
				val scope = super.getScope(context, reference)
				println("USE1__NAME")
				val defs = scope.allElements.map([ d |
					new AliasedEObjectDescription(QualifiedName.create(d.name.firstSegment.toUpperCase), d)
				]).map([d|d as IEObjectDescription])
				return new SimpleScope(defs)
			}
		}
		if (context instanceof UseRef) {
			if (reference == LangBPackage.Literals.USE_REF__NAME) {
				val scope = super.getScope(context, reference)
				println("USE_REF__NAME")
				val defs = scope.allElements.map([ d |
					new AliasedEObjectDescription(QualifiedName.create(d.name.firstSegment.toUpperCase), d)
				]).map([d|d as IEObjectDescription])
				return new SimpleScope(defs)
			}
		}
		super.getScope(context, reference)
	}
}


And the above mentioned issue can be reproduced as shown in the image below

index.php/fa/34485/0/

The different between LangB-"use1"-way and LangB-"use2"-way is the cross-reference is specified with a keyword (works) and does not work when cross-reference is in its own object/rule i.e UseRef.

I do not understand the behaviour. helps if you can clarify it.

Attached is the source code to reproduce the issue.




[Updated on: Mon, 10 December 2018 14:54]

Report message to a moderator

Re: cross-reference with modified name [message #1799599 is a reply to message #1799584] Mon, 10 December 2018 21:18 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
this is a different problem.
Xtext creates objects lazy (usually)
that means "after" the first assignment

in your grammar you have

Use2:
'use2' name=UseRef ;

UseRef:
name=[langA::Definition]
;

=> the context may be a Use2 or even a Model (depending on situation), that is expected behaviour.
=> you have to consider that in your scoping impl.

you can otherwise mitigate it by changing the grammar (depends on the situation if this is possible)

Use2:
name=UseRef ;

UseRef:
{UseRef}'use2' name=[langA::Definition]
;

the label in the completion is done there:org.eclipse.xtext.resource.impl.AliasedEObjectDescription.getQualifiedName()
called by org.eclipse.xtext.ui.editor.contentassist.AbstractContentProposalProvider.getStyledDisplayString(IEObjectDescription)
you might custoize that in your proposal provider




Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: cross-reference with modified name [message #1799605 is a reply to message #1799599] Tue, 11 December 2018 00:47 Go to previous message
Ravi Nallappan is currently offline Ravi NallappanFriend
Messages: 12
Registered: September 2014
Junior Member
Thanks Christian, that explained it.

In my case, since context does not have to be fixed - I able just to skip the check. i.e this works.

class LangBScopeProvider extends AbstractLangBScopeProvider {
	override getScope(EObject context, EReference reference) {
		if (context instanceof Use1) {
			if (reference == LangBPackage.Literals.USE1__NAME) {
				val scope = super.getScope(context, reference)
				println("USE1__NAME")
				val defs = scope.allElements.map([ d |
					new AliasedEObjectDescription(QualifiedName.create(d.name.firstSegment.toUpperCase), d)
				]).map([d|d as IEObjectDescription])
				return new SimpleScope(defs)
			}
		}
//		if (context instanceof UseRef) {
//			if (reference == LangBPackage.Literals.USE_REF__NAME) {
//				val scope = super.getScope(context, reference)
//				println("USE_REF__NAME")
//				val defs = scope.allElements.map([ d |
//					new AliasedEObjectDescription(QualifiedName.create(d.name.firstSegment.toUpperCase), d)
//				]).map([d|d as IEObjectDescription])
//				return new SimpleScope(defs)
//			}
//		}
		if (reference == LangBPackage.Literals.USE_REF__NAME) {
			val scope = super.getScope(context, reference)
			println("none UseRef USE_REF__NAME")
			val defs = scope.allElements.map([ d |
				new AliasedEObjectDescription(QualifiedName.create(d.name.firstSegment.toUpperCase), d)
			]).map([d|d as IEObjectDescription])
			return new SimpleScope(defs)
		}
		super.getScope(context, reference)
	}
}
Previous Topic:executing mwe2 programmatically within Eclipse plugin
Next Topic:Xtext DSL plugin only provides keyword suggestions for the first line of the file
Goto Forum:
  


Current Time: Fri Apr 26 14:34:37 GMT 2024

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

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

Back to the top