Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Need some help
icon5.gif  Need some help [message #840767] Tue, 10 April 2012 13:43 Go to next message
Goran M. is currently offline Goran M.Friend
Messages: 12
Registered: April 2012
Junior Member
Hi all,

I am new into XTEXT and I am stuck completely. I got a DSL which definies simple
commands.

alias partner "org.free.project.partner"

create partner:aPartner CTPartner

call aPartner.setName("John Doe")



The package org.free.project.partner is a third-party library and contains a class ObjectFactory for creating instances of the classes in that package.

The second line should create an instance of CTPartner by using the ObjectFactory.

The third line calls the Method setName on the created instance.


Actually I am lost in all the jvmType-stuff. I managed to use jvmTypes but then I need to use a qualified name. I would prefer the above syntax. Defining an alias and then using the simple name of the class.

Second I would like to get a proposal of all methods of CTPartner when I type in aPartner and then hit CTRL+SPACE.

How can I manage that? I already checked some classes like the subclass of AbstractModelInferrer and the ProposalProvider but I have no clue where to start.

I spent the whole day searching for howtos and tutorials but I only got the typicall
ones like h**p://www.eclipse.org/Xtext/documentation/

Thanks a lot

Goran



Re: Need some help [message #841038 is a reply to message #840767] Tue, 10 April 2012 20:44 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
Can you post your grammar?
Regards
- henrik

On 2012-10-04 15:43, Goran Marjanovic wrote:
> Hi all,
>
> I am new into XTEXT and I am stuck completely. I got a DSL which
> definies simple
> commands.
>
> alias partner "org.free.project.partner"
>
> create partner:aPartner CTPartner
>
> call aPartner.setName("John Doe")
>
>
>
> The package org.free.project.partner is a third-party library and
> contains a class ObjectFactory for creating instances of the classes in
> that package.
> The second line should create an instance of CTPartner by using the
> ObjectFactory.
>
> The third line calls the Method setName on the created instance.
>
>
> Actually I am lost in all the jvmType-stuff. I managed to use jvmTypes
> but then I need to use a qualified name. I would prefer the above
> syntax. Defining an alias and then using the simple name of the class.
>
> Second I would like to get a proposal of all methods of CTPartner when I
> type in aPartner and then hit CTRL+SPACE.
>
> How can I manage that? I already checked some classes like the subclass
> of AbstractModelInferrer and the ProposalProvider but I have no clue
> where to start.
>
> I spent the whole day searching for howtos and tutorials but I only got
> the typicall
> ones like h**p://www.eclipse.org/Xtext/documentation/
>
> Thanks a lot
> Goran
>
>
>
>
Re: Need some help [message #841281 is a reply to message #841038] Wed, 11 April 2012 05:40 Go to previous messageGo to next message
Goran M. is currently offline Goran M.Friend
Messages: 12
Registered: April 2012
Junior Member
Hi Henrik,

this grammar does not recognize the Java class as the "javaType" is an ID.

grammar de.demo.scripting.editor.BiproScript with org.eclipse.xtext.xbase.Xbase
import "h**p://www.eclipse.org/xtext/common/JavaVMTypes" as jvmTypes
generate biproScript "h**p://www.demo.de/scripting/editor/BiproScript"

BiproModel:
	script+=AbstractCommand*;

AbstractCommand:
	SimpleCommand | ServiceCommand | ComplexCommand;

SimpleCommand:
	Alias | Create | Call;

Alias:
	'alias' name=ID packageName=STRING;

Create:
	'create' myAlias=[Alias] ':' name=ID javaType=ID;

Call:
	'call' myCreate=[Create] '.' callValue+=MethodName ('.' callValue+=MethodName)*;

MethodName:
	name=ID params=Method;

Method:
	{Method}'('(params+=JvmFormalParameter (',' params+=JvmFormalParameter)*)? ')';



If I use the following grammar for the Create-Command

Create:
	'create' myAlias=[Alias] ':' name=ID javaType=[jvmTypes::JvmType|QualifiedName];


I get all classes as a proposal but I need to use the full qualified name.

This is what I would like:

  • alias-command for imports
  • create-command with reference to an alias and the simplename. The proposal should be only the classes which belong to the package defined by the alias
  • when pressing CTRL+SPACE (or when pressing '.') the call-command should propose all methods of the object defined by create


I need a hint where and how to start. Maybe some starting classes and methods.

Thanks in advance!!!

Goran

[Updated on: Wed, 11 April 2012 05:41]

Report message to a moderator

Re: Need some help [message #841661 is a reply to message #841281] Wed, 11 April 2012 15:47 Go to previous messageGo to next message
Henrik Lindberg is currently offline Henrik LindbergFriend
Messages: 2509
Registered: July 2009
Senior Member
On 2012-11-04 7:40, Goran Marjanovic wrote:

>
> If I use the following grammar for the Create-Command
>
>
> Create:
> 'create' myAlias=[Alias] ':' name=ID
> javaType=[jvmTypes::JvmType|QualifiedName];
>
>
This looks like the right start. You now get a reference to a JvmType.

> I get all classes as a proposal but I need to use the full qualified name.
>
> This is what I would like:
>
> alias-command for imports
> create-command with reference to an alias and the simplename. The
> proposal should be only the classes which belong to the package defined
> by the alias
> when pressing CTRL+SPACE (or when pressing '.') the call-command should
> propose all methods of the object defined by create
>
>
> I need a hint where and how to start. Maybe some starting classes and
> methods.
> Thanks in advance!!!
>

The first step is to define the references to some particular type in
your grammar (like the JvmType, but there are many other types in the
jvmTypes package).

Secondly, you implement the Scoping that defines what is visible in a
particular location.

Suggest you start by reading up on how scoping works.

Regards
- henrik
Re: Need some help [message #841723 is a reply to message #841661] Wed, 11 April 2012 17:08 Go to previous messageGo to next message
Goran M. is currently offline Goran M.Friend
Messages: 12
Registered: April 2012
Junior Member
Thanks....I will check the Scope API...

Goran
Re: Need some help [message #842547 is a reply to message #841723] Thu, 12 April 2012 11:54 Go to previous messageGo to next message
Goran M. is currently offline Goran M.Friend
Messages: 12
Registered: April 2012
Junior Member
Well...2 out of 3. My alias import works fine and the Java-Objectlookup also. Here is how I've done it.

Import
One important thing is how the grammar is defined. My alias-command was definied like:

Alias:
	'alias' name=ID packageName=STRING
;


I changed it to

Alias:
	'alias' name=ID importedNamespace=QualifiedNameWithWildCard
;


The most important thing was changing the name from packageName to importedNamespace. Now I can cross-reference to my Java-Objects.

Propose only the classes within the package
This was more tricky (at least for me). First I tried by scoping, but I did not get further as I didn't find how and where to start. But then I used my ProposalProvider in the following way:

@Override
	public void completeCreate_JavaType(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		super.lookupCrossReference(((CrossReference) assignment.getTerminal()), context, acceptor, new CreateFilter((Create) model));
	}


The CreateFilter is an inner-class:

class CreateFilter implements Predicate<IEObjectDescription> {

		private QualifiedName packageQName;

		public CreateFilter(Create createModel) {
			String[] segments = createModel.getNamespace().getImportedNamespace().split("\\.");
			this.packageQName = QualifiedName.create(segments).skipLast(1);
		}

		@Override
		public boolean apply(IEObjectDescription input) {
			QualifiedName name = input.getQualifiedName();

			// skipLast to remove the wildcard
			return name.startsWith(packageQName);
		}

	}



This works for me. If I hit CTRL+SPACE in my create-command I only got the classes from the corresponding package proposed. For all newbies out there: I found this solution by a step-by-step debugging and reading the source code. It's hard but I succeeded. I don't know if there is a nicer way, but for me it works.

Now next thing is to get the method-names proposed.

Regards
Goran

[Updated on: Thu, 12 April 2012 11:56]

Report message to a moderator

Re: Need some help [message #843946 is a reply to message #842547] Fri, 13 April 2012 14:27 Go to previous messageGo to next message
Goran M. is currently offline Goran M.Friend
Messages: 12
Registered: April 2012
Junior Member
Hi,

well, I am not happy with this solution as the performance is bad. I tried to solve it with a ScopeProvider. Here is the code for filtering the classes depending on the package:

Create create = (Create) context;
IScope scope = super.getScope(context, reference);

String[] segments = create.getImports().getImportedNamespace().split("\\.");
QualifiedName packageQName = QualifiedName.create(segments).skipLast(1);

Iterable<IEObjectDescription> it = scope.getAllElements();
ArrayList<IEObjectDescription> list = new ArrayList<IEObjectDescription>();

for (IEObjectDescription descr : it) {
    if (descr.getQualifiedName().startsWith(packageQName)) {
        list.add(descr);
    }
}

return new SimpleScope(list, false);


Now, while debugging, I can see that the super.getScope()-call returns a scope
where all classes are already fetched.

But the only way to get to the classes is by calling getAllAlements() which needs
a lot of time. Is there a faster way to get the classes?

Regards
Goran
Re: Need some help [message #844047 is a reply to message #843946] Fri, 13 April 2012 16:25 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3108
Registered: July 2009
Senior Member
Goran,

you could implement the IScope interface manually and delegate to the
super scope (which is populated lazily if you don't call
getAllElements). You own scope would basically look like this:

MyScope implements IScope {
MyScope(IScope delegate) { this.delegate = delegate }
public IEObjectDescription getSingleElement(QualifiedName name) {
if (name matches import criteria) {
return delegate.getSingleElement(name);
}
return IScope.NULLSCOPE;
}

public Iterable<IEObjectDescription> getElements(final QualifiedName
name) {
if (name matches import criteria) {
return delegate.getElements(name);
}
return IScope.NULLSCOPE;
}

.. similar for the other methods ..


}

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

Am 13.04.12 16:27, schrieb Goran M.:
> Hi,
> well, I am not happy with this solution as the performance is bad. I
> tried to solve it with a ScopeProvider. Here is the code for filtering
> the classes depending on the package:
>
>
> Create create = (Create) context;
> IScope scope = super.getScope(context, reference);
>
> String[] segments =
> create.getImports().getImportedNamespace().split("\\.");
> QualifiedName packageQName = QualifiedName.create(segments).skipLast(1);
>
> Iterable<IEObjectDescription> it = scope.getAllElements();
> ArrayList<IEObjectDescription> list = new ArrayList<IEObjectDescription>();
>
> for (IEObjectDescription descr : it) {
> if (descr.getQualifiedName().startsWith(packageQName)) {
> list.add(descr);
> }
> }
>
> return new SimpleScope(list, false);
>
>
> Now, while debugging, I can see that the super.getScope()-call returns a
> scope
> where all classes are already fetched.
>
> But the only way to get to the classes is by calling getAllAlements()
> which needs
> a lot of time. Is there a faster way to get the classes?
>
> Regards
> Goran
Re: Need some help [message #844051 is a reply to message #843946] Fri, 13 April 2012 16:25 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3108
Registered: July 2009
Senior Member
Goran,

you could implement the IScope interface manually and delegate to the
super scope (which is populated lazily if you don't call
getAllElements). You own scope would basically look like this:

MyScope implements IScope {
MyScope(IScope delegate) { this.delegate = delegate }
public IEObjectDescription getSingleElement(QualifiedName name) {
if (name matches import criteria) {
return delegate.getSingleElement(name);
}
return IScope.NULLSCOPE;
}

public Iterable<IEObjectDescription> getElements(final QualifiedName
name) {
if (name matches import criteria) {
return delegate.getElements(name);
}
return IScope.NULLSCOPE;
}

.. similar for the other methods ..


}

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

Am 13.04.12 16:27, schrieb Goran M.:
> Hi,
> well, I am not happy with this solution as the performance is bad. I
> tried to solve it with a ScopeProvider. Here is the code for filtering
> the classes depending on the package:
>
>
> Create create = (Create) context;
> IScope scope = super.getScope(context, reference);
>
> String[] segments =
> create.getImports().getImportedNamespace().split("\\.");
> QualifiedName packageQName = QualifiedName.create(segments).skipLast(1);
>
> Iterable<IEObjectDescription> it = scope.getAllElements();
> ArrayList<IEObjectDescription> list = new ArrayList<IEObjectDescription>();
>
> for (IEObjectDescription descr : it) {
> if (descr.getQualifiedName().startsWith(packageQName)) {
> list.add(descr);
> }
> }
>
> return new SimpleScope(list, false);
>
>
> Now, while debugging, I can see that the super.getScope()-call returns a
> scope
> where all classes are already fetched.
>
> But the only way to get to the classes is by calling getAllAlements()
> which needs
> a lot of time. Is there a faster way to get the classes?
>
> Regards
> Goran
Re: Need some help [message #845785 is a reply to message #844051] Sun, 15 April 2012 12:22 Go to previous messageGo to next message
Goran M. is currently offline Goran M.Friend
Messages: 12
Registered: April 2012
Junior Member
Hi Sebastian,

thanks for your answer. I still got a little problem I tested with the following grammar (just the important parts):


Import:
    'import' name=ID importedNamespace=QualifiedNameWithWildCard;

QualifiedNameWithWildCard :
    QualifiedName  ('.' '*')?;

Entity:
    'entity' name=ValidID 
        ('extends' aAlias=[Import] superType=JvmTypeReference)? '{'
        features+=Feature*
    '}';


So if I define an entity like

import util java.util.*;
import sql java.sql.*;

entity test extends sql 



If I hit CTRL+SPACE after sql, I got the whole java type list.
I debugged the methods and I got "sql" and "util" as QualifiedName which references the import but not the java-package.


Additionaly I am not sure if I do it the right way.

I have overwritten my XXXRuntimeModule:
public void configureIScopeProviderDelegate(Binder binder) {
		binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class)
		.annotatedWith(Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
		.to(MyDslScopeProvider.class);
	
	}


and my getScope-method of my IScope-implementingh class returns:

return new MyDslSope(super.getScope(....));


is that right?

Maybe I should check the globalScope as the import is accessible global....

Sorry about the questions, but I am still bloody damn new to the whole stuff...

Regards
Goran
Re: Need some help [message #845803 is a reply to message #845785] Sun, 15 April 2012 12:35 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 3108
Registered: July 2009
Senior Member
Hi Goran,

trying to introduce aliases for imported namespaces is another story.
The JvmTypeReferences uses qualified names internally thus it's always
allowed to use the FQN of a class. The imports are handled by
ImportNormalizers which will introduce aliases for FQNs if a certain
import clause is present. You may want to dig into
ImportedNamespaceAwareLocalScopeProvider.internalGetImportedNamespaceResolvers(EObject,
boolean) to implement your alias semantic. Please not that it's usually
not necessary to have an attribute aAlias before a type reference.

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

Am 15.04.12 14:22, schrieb Goran M.:
> Hi Sebastian,
>
> thanks for your answer. I still got a little problem I tested with the
> following grammar (just the important parts):
>
>
>
> Import:
> 'import' name=ID importedNamespace=QualifiedNameWithWildCard;
>
> QualifiedNameWithWildCard :
> QualifiedName ('.' '*')?;
>
> Entity:
> 'entity' name=ValidID ('extends' aAlias=[Import]
> superType=JvmTypeReference)? '{'
> features+=Feature*
> '}';
>
>
> So if I define an entity like
>
> import util java.util.*;
> import sql java.sql.*;
>
> entity test extends sql
>
>
> If I hit CTRL+SPACE after sql, I got the whole java type list.
> I debugged the methods and I got "sql" and "util" as QualifiedName which
> references the import but not the java-package.
>
>
> Additionaly I am not sure if I do it the right way.
>
> I have overwritten my XXXRuntimeModule:
>
> public void configureIScopeProviderDelegate(Binder binder) {
> binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class)
> .annotatedWith(Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
>
> .to(MyDslScopeProvider.class);
>
> }
>
>
> and my getScope-method of my IScope-implementingh class returns:
>
>
> return new MyDslSope(super.getScope(....));
>
>
> is that right?
>
> Maybe I should check the globalScope as the import is accessible global....
>
> Sorry about the questions, but I am still bloody damn new to the whole
> stuff...
>
> Regards
> Goran
>
Re: Need some help [message #845849 is a reply to message #845803] Sun, 15 April 2012 13:30 Go to previous message
Goran M. is currently offline Goran M.Friend
Messages: 12
Registered: April 2012
Junior Member
Hi Sebastian,

Thanks for your reply. For me the alias should just filter the amount of proposes when hit CTRL+Space,
so that the returned list is smaller. I will try it with the ImportedNamespaceAwareLocalScopeProvider.internalGetImportedNamespaceResolvers...Thanks.

Regards
Goran
Previous Topic:C-Based Editor (Xtext or CDT)?
Next Topic:ImportedNamespaceAwareLocalScopeProvider should check the path
Goto Forum:
  


Current Time: Mon Jul 13 19:23:12 GMT 2020

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

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

Back to the top