|
|
|
|
|
Re: Getting the Qualified Name and Global Name Collision [message #660030 is a reply to message #660025] |
Wed, 16 March 2011 15:19 |
|
Hi,
yes you have toi do the stuff lazy as it is done with the class org.eclipse.xtext.scoping.impl.FilteringScope.
(build a wrapping scope arround the delegate scope and do the filterinmg/transformation on the fly)
It seems that you want to get all AFiles, so what about
public IScope scope_EObject_objecttag(EObject o, EReference ref) {
return new FilteringScope(delegateGetScope(o, ref), MyDslPackage.Literals.AFILE);
}
this simply gets you all AFile objects into the scope.
maybe a look at the scope implementation of org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalSc opeProvider might be a look worth. here some kind of aliasing is done too.
~Christian
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
[Updated on: Wed, 16 March 2011 15:31] Report message to a moderator
|
|
|
Re: Getting the Qualified Name and Global Name Collision [message #660522 is a reply to message #659995] |
Fri, 18 March 2011 20:26 |
Rafael Angarita Messages: 94 Registered: November 2010 |
Member |
|
|
HI, Christian. Thank you very much for your help. I have tried several things, but none of them have worked for me. I rewrote my sample grammar to make it less confusing:
First I have a Table which can contain Columns and Indexes:
Table:
'Name:' name=ID
'Columns:' '{' columns+=Column (',' columns+=Column)* '}'
'Indexes:' '{' indexes+=Index+ '}'
;
Column:
attribute=[ColumnRef::Column]
;
Index: {Index}
'Columns:' '{' indexcolumns+=IndexColumn (',' indexcolumns+=IndexColumn)* '}'
;
IndexColumn:
indexColumn=[Column]
;
To compute the QN of Table.Column and make it referencable within its table I wrote the next methods:
@Override
public String getQualifiedName(EObject obj) {
System.out.println("getQualifiedName");
if(obj instanceof Column) {
System.out.println("Column");
Column col = ((Column) obj);
CompositeNode cNode = NodeUtil.getNode(col);
EList<AbstractNode> anList = cNode.getChildren();
if (anList.size() > 1){
AbstractNode aNode = anList.get(1);
LeafNode lNode = (LeafNode) aNode;
System.out.println(lNode.getText());
return lNode.getText();
}
}
return super.getQualifiedName(obj);
}
@Inject
IQualifiedNameProvider nameProvider;
public IScope scope_IndexColumn_indexColumn(Index i, EReference r) {
EList<Column> list = ((Table) i.eContainer())
.getColumns();
return Scopes.scopeFor(list, nameProvider, IScope.NULLSCOPE);
}
I define a Column in another file:
Now, I have another object wich can reference objects of different types, so I use a reference to a EObject:
Procedure:
'object: ' eo=[ecore::EObject]
;
Suppose I want only Columns to be referenced in my Procedure. I have tried the next to do the filtering:
1. Using the filtering from the arithmetics example:
@Override
public IScope getScope(EObject context, EReference reference) {
IScope scope = super.getScope(context, reference);
return new FilteringScope(scope,
new Predicate<IEObjectDescription>() {
@Override
public boolean apply(IEObjectDescription input) {
//System.out.println(input.getQualifiedName());
return input!=null && input.getEObjectURI()!=null && input.getEObjectURI().fileExtension()!=null &&
(input.getEObjectURI().fileExtension().equals("column"));
};
});
}
The content proposed for the EObjects of my Procedure is filtered well, only Columns are showed. However, If I choose a Column that was used as a Table index, I still get the error: "Couldn't resolve reference to EObject".
2. I tried:
@Override
public IScope getScope(EObject context, EReference reference) {
return new org.eclipse.xtext.scoping.impl.FilteringScope(delegateGetScope(context, reference), ColumnPackage.Literals.COLUMN);
}
But it did nothing at all.
3. I wrote the method:
public IScope scope_Procedure_eo(Procedure i, EReference r) {
//System.out.println("ss");
IScope result = delegateGetScope(i, r);
Iterable<IEObjectDescription> objects = Iterables.filter(result.getAllContents(), new Predicate<IEObjectDescription>() {
@Override
public boolean apply(IEObjectDescription input) {
return input.getEObjectURI().fileExtension().equals("column");
}
});
return new SimpleScope(objects);
//return new SimpleScope(objects);
}
It actually do the filtering very well, but I get the error: "getAllContents schouldn't be called on a global scope during linking"
I guess there is no way to make the Columns of a table only visible to the current Table when computing the QN. The QN is always exported to the global scope.
Sorry for the long, long post, but I am really stuck here.
Thank you very much for your help.
|
|
|
Re: Getting the Qualified Name and Global Name Collision [message #660527 is a reply to message #660522] |
Fri, 18 March 2011 21:24 |
|
Hi,
The Following works nice for me.
(1) First remove the NameProvider Thing. In my case
public class TablesQNP extends DefaultDeclarativeQualifiedNameProvider {
}
(2) Adapt the Scoping for the IndexColumns
public IScope scope_IndexColumn_indexColumn(Index i, EReference r) {
EList<Column> list = ((Table) i.eContainer())
.getColumns();
Function<Column, String> nameProvider = new Function<Column, String>() {
@Override
public String apply(Column from) {
CompositeNode cNode = NodeUtil.getNode(from);
EList<AbstractNode> anList = cNode.getChildren();
if (anList.size() > 1){
AbstractNode aNode = anList.get(1);
LeafNode lNode = (LeafNode) aNode;
return lNode.getText();
}
return null;
}
};
return Scopes.scopeFor(list,nameProvider, IScope.NULLSCOPE);
}
Using just a local name provider prevents fron pluplicate things are thrown to the index.
(3) Adapt Scoping for the Procedure thing
package org.xtext.example.ref.scoping;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.FilteringScope;
import org.xtext.example.columns.columns.ColumnsPackage;
import org.xtext.example.ref.ref.Procedure;
/**
* This class contains custom scoping description.
*
* see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping
* on how and when to use it
*
*/
public class RefScopeProvider extends AbstractDeclarativeScopeProvider {
public IScope scope_Procedure_eo(Procedure i, EReference r) {
return new FilteringScope(delegateGetScope(i, r), ColumnsPackage.Literals.COLUMN);
}
}
This works nicly for me.
~Christian
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
Powered by
FUDForum. Page generated in 0.03673 seconds