|
|
Re: Need some help [message #841281 is a reply to message #841038] |
Wed, 11 April 2012 05:40 |
Goran M. 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 #842547 is a reply to message #841723] |
Thu, 12 April 2012 11:54 |
Goran M. 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 #844047 is a reply to message #843946] |
Fri, 13 April 2012 16:25 |
Sebastian Zarnekow Messages: 3118 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 |
Sebastian Zarnekow Messages: 3118 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
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05085 seconds