Home » Modeling » TMF (Xtext) » Customize Scoping for inheritance
|
Re: Customize Scoping for inheritance [message #1839774 is a reply to message #1839773] |
Sun, 28 March 2021 12:25 |
|
what is unclear to me in all your questions. what is the problem with simply implement scoping
- from the context object search the Country (EcoreUtil.getContainerOfType might help)
- from the country recursively collect and decollect all Tree and Houses
- put the result of Trees and Houses to a Scope (Scope.scopesFor util will help here)
as you dont post any snippet of scope provider it is hard to find out where your problem is.
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
| | | | | | | | |
Re: Customize Scoping for inheritance [message #1839810 is a reply to message #1839801] |
Mon, 29 March 2021 10:55 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
Okay, so I might have misdirected you, but this is what I want to do with an example.Note that these are three different files in one project.
file1.dsl
country C1 { forest F1
tree T1, T2
house H1, H2
}
file2.dsl
country C2 { forest F2
tree T3, T4
house H3, H4
}
file3.dsl
country C3 inherits C2 { forest F3
tree T5, T6
house H5, H6
remove T3 //here I should only get suggestions for T5, T6 which are part of C3, and T3,T4 which are inherited from C2. However, with the scope provider snippet that I have, I still get suggestions even for T1, and T2 which are part of C1 and I dont want that.
}
I understand that the code snippet I already have might be wrong, but I would very much appreciate your help as I really need it for a project.
Many thanks!
|
|
|
Re: Customize Scoping for inheritance [message #1839816 is a reply to message #1839810] |
Mon, 29 March 2021 12:30 |
|
yes but where is your proper impl of the scope provider?
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (context instanceof Country
&& reference == ForestPackage.Literals.FOREST__REMOVE) {
EObject rootCountry = EcoreUtil2.getRootContainer(context);
Country country=(Country) context;
country.getForests().getTrees();
country.getForests().getHouses();
List<Country> candidates = EcoreUtil2.getAllContentsOfType(rootCountry, Country.class);
return Scopes.scopeFor(candidates);
}
return super.getScope(context, reference);
}
}
is not the impl you use for sure.
you should collect the valid trees and houses there
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Customize Scoping for inheritance [message #1839819 is a reply to message #1839816] |
Mon, 29 March 2021 12:46 |
|
this one works fine for me
public class MyDslScopeProvider extends AbstractMyDslScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == MyDslPackage.Literals.FOREST__REMOVE) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> treesAndHouses = new ArrayList<>();
while (rootCountry != null) {
treesAndHouses.addAll(rootCountry.getForests().getTrees());
treesAndHouses.addAll(rootCountry.getForests().getHouses());
rootCountry = rootCountry.getSupercountry();
}
System.out.println(treesAndHouses);
return Scopes.scopeFor(treesAndHouses);
}
return super.getScope(context, reference);
}
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
| |
Re: Customize Scoping for inheritance [message #1839861 is a reply to message #1839819] |
Tue, 30 March 2021 13:52 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
Hi Christian,
I am currently working on customizing the scope provider for my grammar, and it works for most of it. However, I have issues in a specific case.
So being that Xtexts' default scope provider allows you to reference elements from all the files that are part of the same project by using the qualified name, I want to restrict that. I removed the qualified name but with the following grammar and the following scope provider I am not able to refer to trees specified in country which I am extending.
This is the grammar:
Country:
"country" name=ID ("extends" supercountry=[Country|QualifiedName])?
forests=Forest
;
Forest:
"{"
"forest" name=ID
("tree" trees+=Tree ("," trees+=Tree)*)*
("workingArea" position+=Position)*
("house" houses+=House ("," houses+=House)*)*
("remove" remove=[Tree|QualifiedName])?
;
Tree:
name=ID
;
Position:
name=ID "from" from=[Tree] "to" from=[Tree]
;
House:
name=ID
;
QualifiedName:
ID ('.' ID)*
;
These are the examples:
file1.forest
country C1 { forest F1
tree T1, T2
file2.forest
country C2 extends C1 {
forest F2
tree T7
workingArea area from T7 to T7 //here I also want to be able to refer to T1, and T2, but I can't.
This is a snippet of my scope provider. The second part else if, is what I am trying to implement to make this possible, but I can't seem to get it right.
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.FOREST__REMOVE) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> treesAndHouses = new ArrayList<>();
while (rootCountry != null) {
treesAndHouses.addAll(rootCountry.getForests().getTrees());
treesAndHouses.addAll(rootCountry.getForests().getHouses());
rootCountry = rootCountry.getSupercountry();
}
System.out.println(treesAndHouses);
return Scopes.scopeFor(treesAndHouses);
}
else if (reference == ForestPackage.Literals.FOREST__POSITION) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> position = new ArrayList<>();
while (rootCountry != null) {
position.addAll(rootCountry.getForests().getPosition());
rootCountry = rootCountry.getSupercountry();
}
System.out.println(position);
return Scopes.scopeFor(position);
}
return super.getScope(context, reference);
}
}
Thank you!
|
|
| |
Re: Customize Scoping for inheritance [message #1839947 is a reply to message #1839862] |
Thu, 01 April 2021 17:24 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
Hi Christian,
I am trying to access a specific element from my grammar and I have been trying for a while but no luck.
This is the grammar:
Country:
"country" name=ID ("extends" supercountry=[Country|QualifiedName])?
forests=Forest
;
Forest:
"{"
"forest" name=ID "{"
("tree" trees+=Tree ("," trees+=Tree)*)*
("house" houses+=House ("," houses+=House)*)*
"subforest" subforest+=Subforest
"}";
Tree:
name=ID
;
Position:
name=ID "from" from=[Enter] "to" to=[Exit]
;
House:
name=ID
;
Subforest:
name=ID
"enter" enter+=Enter
"exit" exit+=Exit
("tree" trees+=Tree ("," trees+=Tree)*)*
("workingArea" position+=Position)*
("house" houses+=House ("," houses+=House)*)*
;
Enter:
name=ID
;
Exit:
name=ID
;
QualifiedName:
ID ('.' ID)*
;
And this is my scope provider:
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.POSITION__FROM) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> position = new ArrayList<>();
while (rootCountry != null) {
position.addAll(rootCountry.getForests(). getSubforest());
rootCountry = rootCountry.getSupercountry();
}
System.out.println(position);
return Scopes.scopeFor(position);
}
return super.getScope(context, reference);
}
}
I want to be able to access Enter and Exit so the position will be from enter to exit. Both enter and exit are contained by a subforest, but when I write this line in my scope provider:
position.addAll(rootCountry.getForests(). getSubforest());
I cannot go further than getSubforest() , while I have the idea that in order to access enter and exit I should be able to write
position.addAll(rootCountry.getForests(). getSubforest().getEnter());
position.addAll(rootCountry.getForests(). getSubforest().getExit);
|
|
| | | | | | | |
Re: Customize Scoping for inheritance [message #1839976 is a reply to message #1839974] |
Fri, 02 April 2021 14:44 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
It works for this case, but for a more complex case like the following it doesnt:
This is the grammar:
Country:
"country" name=ID ("extends" supercountry=[Country|QualifiedName])?
forests=Forest
;
Forest:
"{"
"forest" name=ID "{"
("park" parks+=Park ("," parks+=Park)*)*
"workingarea" workingarea=WorkingArea
"}";
Park:
name=ID ("{"
"enter" enter+=Enter
"exit" exit+=Exit
("park" parks+=Park ("," parks+=Park)*)*
"workingarea" workingarea=WorkingArea
"}")*
;
WorkingArea:
name=ID "from" from=[ParkEnter] "to" to=[ParkExit]
;
Enter:
Name=ID
;
Exit:
Name=ID
;
ParkEnter:
Park | Enter
;
ParkExit:
Park | Exit
;
QualifiedName:
ID ('.' ID)*
;
And this is the scope provider:
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.WORKING_AREA__FROM) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> workingarea = new ArrayList<>();
while (rootCountry != null) {
for (Park park :rootCountry.getForests().getParks()){
workingarea.addAll(park.getEnter());
}
workingarea.addAll(rootCountry.getForests().getParks());
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingarea);
return Scopes.scopeFor(workingarea);
}
else if (reference == ForestPackage.Literals.WORKING_AREA__TO) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> workingareato = new ArrayList<>();
while (rootCountry != null) {
for (Park park :rootCountry.getForests().getParks()){
workingareato.addAll(park.getExit());
}
workingareato.addAll(rootCountry.getForests().getParks());
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingareato);
return Scopes.scopeFor(workingareato);
}
return super.getScope(context, reference);
}
}
However, if I try to write this example I cannot. I have put some comments in the grammar to show what is wrong.
country C1 {
forest F1 {
park P1 {
enter Enter1
exit Exit1
park P2
workingarea W1 from P1 to P1 \\here I want to be able to say from and to P1, Enter1,Exit1, P2 , but I am only allowed to say P1
}
park P3 {
enter Enter2
exit Exit2
park P4
workingarea W2 from P1 to P3 \\here I want to be able to say from and to P1, Enter1,Exit1, P2 ,P3,Enter2,Exit2 and P4 but I am only allowed to say P1 and P3.
}
}
}
Many thanks!
|
|
|
Re: Customize Scoping for inheritance [message #1839977 is a reply to message #1839976] |
Fri, 02 April 2021 15:21 |
|
i recommend you to debug your code.
make sure you collect the objects you want.
workingarea W1 from P1 to P1 \\here I want to be able to say from and to P1, Enter1,Exit1, P2 , but I am only allowed to say P1
if you want Exit1 you should collect it.
besides that your example grammar has warnings and the example model does not parse.
so i cannot look into it
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
| |
Re: Customize Scoping for inheritance [message #1839984 is a reply to message #1839980] |
Fri, 02 April 2021 20:50 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
Ok, the grammar should work fine now. I changed Enter: name=ID but I cannot change Exit too because I get :
Quote:
There cannot be two features named "name".
grammar org.xtext.example.forest.Forest with org.eclipse.xtext.common.Terminals
generate forest "http://www.xtext.org/example/forest/Forest"
Country:
"country" name=ID ("extends" supercountry=[Country|QualifiedName])? "{"
forests=Forest
"}"
;
Forest:
"forest" name=ID "{"
("park" parks+=Park ("," parks+=Park)*)*
("workingarea" workingarea=WorkingArea)*
"}";
Park:
name=ID ("{"
"enter" enter+=Enter
"exit" exit+=Exit
("park" parks+=Park ("," parks+=Park)*)*
("workingarea" workingarea=WorkingArea)*
"}")*
;
WorkingArea:
name=ID "from" from=[ParkEnter] "to" to=[ParkExit]
;
Enter:
name=ID
;
Exit:
Name=ID
;
ParkEnter:
Park | Enter
;
ParkExit:
Park | Exit
;
QualifiedName:
ID ('.' ID)*
;
This is the example and there are comments there to explain what I need:
country C1 {
forest F1 {
park P1 {
enter EN1
exit EX1
park P2 {
enter EN2
exit EX2
park P3
park P4 {
enter EN3
exit EX3
park P5
workingarea W4 from EN1 to P2 //need to have from: P5, P4.EN3 to: P5,P4.EX3 because P4 only contains P4.EN3,P4.EX3 and P5
}
workingarea W2 from EN1 to P2 //need to have from: P2.EN2, P3, P4, P4.EN3 to: P2.EX2, P3, P4,P4.EX3 because P2 contains P2.EN2, P2.EX2, P3, P4, P4.EN3 and P4.EX3. Contrary to others, here we have two parks contained in one park therefore we also allow P3 and P4, not only P4.EN3 and P4.EX3
}
workingarea W1 from EN1 to P2 //need to have from: P1.EN1 to: P1.EX1
}
park P6 {
enter EN4
exit EX4
}
workingarea WF from EN4 to P6 // here I currently have from: EN1, EN4,P1,P2,P6 . I should not have P2 , I should only have P1, P6, P1.EN1,P6.EN4. To should be: P1.EX1, P6.EX4, P1,P6
}
}
So to summarize each working area that belongs to a park, should allow cross referencing enter and exit of that same park, sub parks of that park and the corresponding enter and exit. However, the current scope provider only allows to cross reference park P1, park P6 and their corresponding enter and exit (EN1,EX1,EN4,EX4) but not their sub parks and corresponding enter and exit (it allows the same thing throughout the entire grammar).
For the forest, I should not have P2, because it is a subpark of P1. I should only have P1, P6 and their corresponding enter and exit.
Hope this isn't too complex.
This is the scope provider.
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.WORKING_AREA__FROM) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> workingarea = new ArrayList<>();
while (rootCountry != null) {
for (Park park :rootCountry.getForests().getParks()){
workingarea.addAll(park.getParks());
workingarea.addAll(park.getEnter());
}
workingarea.addAll(rootCountry.getForests().getParks());
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingarea);
return Scopes.scopeFor(workingarea);
}
else if (reference == ForestPackage.Literals.WORKING_AREA__TO) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> workingareato = new ArrayList<>();
while (rootCountry != null) {
for (Park park :rootCountry.getForests().getParks()){
workingareato.addAll(park.getParks());
workingareato.addAll(park.getExit());
}
workingareato.addAll(rootCountry.getForests().getParks());
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingareato);
return Scopes.scopeFor(workingareato);
}
return super.getScope(context, reference);
}
}
I think the current scope provide only collects the first (P1, P6) and second (P2) level of parks and their respective enter and exit points, but it does not go deeper than that, while in my case I guess I have to check until there are no more parks.
Many thanks!
[Updated on: Fri, 02 April 2021 22:50] Report message to a moderator
|
|
| | | | | | | | | | | | | |
Re: Customize Scoping for inheritance [message #1840095 is a reply to message #1840093] |
Tue, 06 April 2021 16:42 |
|
no you need to pass a function or closure.
you can use eContainer() on an eObject to get the parent, then downcast it.
e.g.
List<ParkEnter> workingarea = new ArrayList<ParkEnter>();
return Scopes.scopeFor(workingarea, (ParkEnter e) -> {
Park p = (Park) e.eContainer();
return QualifiedName.create(p.getName(), e.getName());
}, IScope.NULLSCOPE);
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Customize Scoping for inheritance [message #1840102 is a reply to message #1840095] |
Tue, 06 April 2021 20:40 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
I tried out the following scope provider where instead of :
List<EObject> workingarea = new ArrayList<>();
I put
List<ParkEnter> workingarea = new ArrayList<ParkEnter>();
Because I couldn't say :
List<ParkEnter> workingarea = new ArrayList<ParkEnter>();
return Scopes.scopeFor(workingarea, (ParkEnter e) -> {
Park p = (Park) e.eContainer();
return QualifiedName.create(p.getName(), e.getName());
}, IScope.NULLSCOPE);
Being that I already had declared a working area.
This is the scope provider that I am using:
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.WORKING_AREA__FROM) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<ParkEnter> workingarea = new ArrayList<ParkEnter>();
// List<EObject> workingarea = new ArrayList<>();
while (rootCountry != null) {
workingarea.addAll(EcoreUtil2.getAllContentsOfType(rootCountry, ParkEnter.class));
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingarea);
return Scopes.scopeFor(workingarea, (ParkEnter e) -> {
Park p = (Park) e.eContainer();
return QualifiedName.create(p.getName(), e.getName());
}, IScope.NULLSCOPE);
}
return super.getScope(context, reference);
}
}
But I do not get any suggestions when I try to write the grammar
|
|
|
Re: Customize Scoping for inheritance [message #1840116 is a reply to message #1840102] |
Wed, 07 April 2021 03:58 |
|
Please please debug your code and the scope provider
And the proposal provider
also check the console for errors.
this would have helped you to find the problem an solve it
:(
Function<ParkEnter, QualifiedName> nameComputation = (ParkEnter e) -> {
EObject eContainer = e.eContainer();
if (eContainer instanceof Park) {
Park p = (Park) eContainer;
return QualifiedName.create(p.getName(), e.getName());
}
return QualifiedName.create(e.getName());
};
return Scopes.scopeFor(workingarea, nameComputation, IScope.NULLSCOPE);
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
[Updated on: Wed, 07 April 2021 04:10] Report message to a moderator
|
|
|
Re: Customize Scoping for inheritance [message #1840129 is a reply to message #1840116] |
Wed, 07 April 2021 08:29 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
Hi Christian,
Sorry for all the hustle.
I tried your approach, but first on this line:
Function<ParkEnter, QualifiedName> nameComputation = (ParkEnter e) -> {
I got an error saying:
Quote:
Multiple markers at this line
- The target type of this expression must be a functional
interface
- Function cannot be resolved to a type
So I imported com.google.common.base.Function
However afterwards I got an error on this line:
return Scopes.scopeFor(workingarea, nameComputation, IScope.NULLSCOPE);
saying:
Quote:
Multiple markers at this line
- The method scopeFor(Iterable<? extends T>, Function<T,QualifiedName>, IScope) in the type Scopes is not applicable for the arguments (List<EObject>,
Function<ParkEnter,QualifiedName>, IScope)
- The method scopeFor(Iterable<? extends T>, Function<T,QualifiedName>, IScope) in the type Scopes is not applicable for the arguments (List<EObject>,
Function<ParkEnter,QualifiedName>, IScope)
This is the full scope provider:
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.WORKING_AREA__FROM) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> workingarea = new ArrayList<>();
while (rootCountry != null) {
workingarea.addAll(EcoreUtil2.getAllContentsOfType(rootCountry, ParkEnter.class));
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingarea);
Function<ParkEnter, QualifiedName> nameComputation = (ParkEnter e) -> {
EObject eContainer = e.eContainer();
if (eContainer instanceof Park) {
Park p = (Park) eContainer;
return QualifiedName.create(p.getName(), e.getName());
}
return QualifiedName.create(e.getName());
};
return Scopes.scopeFor(workingarea, nameComputation, IScope.NULLSCOPE);
}
return super.getScope(context, reference);
}
}
Many thanks once again!
|
|
| |
Re: Customize Scoping for inheritance [message #1840139 is a reply to message #1840130] |
Wed, 07 April 2021 09:58 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
Hi Christian,
Yes you are right that is why it is so hard for me to customize this scope provider. However I still get issues, maybe it is something related to the EObject e, because in row:
return QualifiedName.create(p.getName(),e.getName());
And in row
return QualifiedName.create(e.getName());
I get
Quote:
- The method getName() is undefined for the type EObject
Which I would not get when there was ParkEnter instead of EObject.
This is the full scope provider
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.WORKING_AREA__FROM) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> workingarea = new ArrayList<>();
while (rootCountry != null) {
workingarea.addAll(EcoreUtil2.getAllContentsOfType(rootCountry, ParkEnter.class));
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingarea);
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
EObject eContainer = e.eContainer();
if (eContainer instanceof Park) {
Park p = (Park) eContainer;
return QualifiedName.create(p.getName(),e.getName());
}
return QualifiedName.create(e.getName());
};
return Scopes.scopeFor(workingarea, nameComputation, IScope.NULLSCOPE);
}
return super.getScope(context, reference);
}
}
Many thanks!
|
|
| | | | |
Re: Customize Scoping for inheritance [message #1840153 is a reply to message #1840152] |
Wed, 07 April 2021 15:38 |
|
question: how firm are you with java programming?
//pseudo code
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
if (e instanceof ParkEnter) {
... container logic
} else if (e instanceof OtherStuffYOurPutTOTHATLIST) {
.......
} elseif (e instanceof ThridStuff) {
.....
}
else {
throw new IllegalStateException("did not expect an " e.GetClass().getName() +"here");
}
EObject eContainer = e.eContainer();
if (eContainer instanceof Park) {
Park p = (Park) eContainer;
if (e instanceof Enter) {
Enter en = (Enter) eContainer;
}
return QualifiedName.create(p.getName(), en.getname());
}
return QualifiedName.create(en.getName());
};
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
Re: Customize Scoping for inheritance [message #1840159 is a reply to message #1840153] |
Wed, 07 April 2021 19:58 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
Hi Christian,
I tried a few things with the grammar :
First I tried the following function:
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
if (e instanceof Park)
{
Park p = (Park) e;
return QualifiedName.create(p.getName(), ((Park) e).getName());
}
return QualifiedName.create(((ParkEnter) e).getName());
};
But here I get Park.Park and not Park.Enter () because of this line:
p.getName(), ((Park) e).getName()
Afterwards I tried the following function:
Quote:
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
if (e instanceof ParkEnter)
{
ParkEnter p = (ParkEnter) e;
return QualifiedName.create(p.getName(), ((ParkEnter) e).getName());
}
return QualifiedName.create(((ParkEnter) e).getName());
};
Here I get Park.Park and Enter.Enter being that ParkEnter: Park | Enter, but still I don't get Park.Enter
Now I am trying the following:
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
if (e instanceof Enter)
{
Enter en = (Enter) e;
return QualifiedName.create(Park.getName(), en.getName());
}
return QualifiedName.create(((ParkEnter) e).getName());
};
because I want to have Park.getName() , Enter.getName, but I don't really know how to access Enter, and the Park to which that Enter belongs to.
In this scope provider I get an error because
Quote:
Cannot make a static reference to the non-static method getName() from the type
ParkEnter
I am including the grammar once again:
Country:
"country" name=ID ("extends" supercountry=[Country|QualifiedName])? "{"
forests=Forest
"}"
;
Forest:
"forest" name=ID "{"
("park" parks+=Park ("," parks+=Park)*)*
("workingarea" workingarea=WorkingArea)*
"}";
Park:
name=ID ("{"
"enter" enter+=Enter
("park" parks+=Park ("," parks+=Park)*)*
("workingarea" workingarea=WorkingArea)*
"}")*
;
WorkingArea:
name=ID "from" from=[ParkEnter|QualifiedName]
;
Enter:
name=ID
;
ParkEnter:
Park | Enter
;
QualifiedName:
ID ('.' ID)*
;
And the scope provider:
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.WORKING_AREA__FROM) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> workingarea = new ArrayList<>();
while (rootCountry != null) {
workingarea.addAll(EcoreUtil2.getAllContentsOfType(rootCountry, ParkEnter.class));
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingarea);
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
if (e instanceof Enter)
{
Enter en = (Enter) e;
return QualifiedName.create(Park.getName(), en.getName());
}
return QualifiedName.create(((ParkEnter) e).getName());
};
/*
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
if (e instanceof ParkEnter)
{
ParkEnter p = (ParkEnter) e;
return QualifiedName.create(p.getName(), ((ParkEnter) e).getName());
}
return QualifiedName.create(((ParkEnter) e).getName());
};
*/
/*
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
if (e instanceof Park)
{
Park p = (Park) e;
return QualifiedName.create(p.getName(), ((Park) e).getName());
}
return QualifiedName.create(((ParkEnter) e).getName());
};
*/
return Scopes.scopeFor(workingarea, nameComputation, IScope.NULLSCOPE);
}
return super.getScope(context, reference);
}
}
|
|
|
Re: Customize Scoping for inheritance [message #1840170 is a reply to message #1840159] |
Thu, 08 April 2021 04:30 |
|
Park is a Class and not a variable.
as you have Seen you can use eContainer to access parents
And you can ask the parent for its parent and you get the grandparent .
Where is this code gone? Why have you removed it
You can Also use EcoreUtil2.getContainerOfType(object, TypeOfAncestorYouSearch.class)
Please please consult somebody with basic java knowledge.
I will stop answering here as long as the problem boils down
To lacking java knowledge
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
| | | | | | |
Re: Customize Scoping for inheritance [message #1840192 is a reply to message #1840183] |
Thu, 08 April 2021 12:09 |
John Henbergs Messages: 239 Registered: October 2020 |
Senior Member |
|
|
Hi Christian,
I was able to solve the issue that I had before, but now I was wondering about something else. With the following scope provider:
public class ForestScopeProvider extends AbstractForestScopeProvider {
@Override
public IScope getScope(EObject context, EReference reference) {
if (reference == ForestPackage.Literals.WORKING_AREA__FROM) {
Country rootCountry = (Country) EcoreUtil2.getRootContainer(context);
List<EObject> workingarea = new ArrayList<>();
while (rootCountry != null) {
workingarea.addAll(EcoreUtil2.getAllContentsOfType(rootCountry, ParkEnter.class));
rootCountry = rootCountry.getSupercountry();
}
System.out.println(workingarea);
Function<EObject, QualifiedName> nameComputation = (EObject e) -> {
if (e instanceof Enter)
{
Enter en = (Enter) e;
Park p = EcoreUtil2.getContainerOfType(en, Park.class);
return QualifiedName.create(p.getName(), en.getName());
}
return QualifiedName.create(((ParkEnter)e).getName());
};
return Scopes.scopeFor(workingarea, nameComputation, IScope.NULLSCOPE);
}
return super.getScope(context, reference);
}
}
I should use the qualified name even when I cross reference elements in the same hierarchical level. For example in the following grammar(please read the comment).
country C1 {
forest F1 {
park P1 {
enter EN1
park P2 {
enter EN2
park P3
park P4 {
enter EN3
park P5
workingarea W4 from P4.EN3. // here it should be EN3 because both EN3 and W4 are Part of P4. If I were to have EN2, that I should write it as P2.EN2, as it is not part of P4.
}
workingarea W2 from P2
}
workingarea W1 from P6.EN4
}
park P6 {
enter EN4
}
workingarea WF from P6.EN4
}
}
Is there a way around this?
Many thanks!
|
|
| | |
Goto Forum:
Current Time: Thu Sep 26 20:40:46 GMT 2024
Powered by FUDForum. Page generated in 0.16479 seconds
|