Home » Modeling » TMF (Xtext) » Getting an element from a list by name in Xtend(Bound Mismatch attempting to use workaround suggested in Xtext Bug 354799)
Getting an element from a list by name in Xtend [message #967614] |
Thu, 01 November 2012 22:29 |
Michael Colburn Messages: 10 Registered: November 2012 |
Junior Member |
|
|
Please refer to the following link:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=354799#c11
where as a work-around, it is proposed by Sven Efftinge to use the following to get an element from a list by name:
def <T extends NamedElement> T get(List<T> list, String key) {
list.findFirst[ name == key ]
}
I have experimented with this using a very simple grammar named Config:
Config: properties+=Property*;
Property: name=ID '=' value=(ID|STRING);
I added the get function (shown above) to my ConfigGenerator.xtend class,
then, entered a call as follows:
def compile(Config c) '''
«c.properties.get("Angle")» // Angle is the 'name' of a property
'''
This results in an error in ConfigGenerator.java in the following generated method:
42 public CharSequence compile(final Config c) {
43 StringConcatenation _builder = new StringConcatenation();
44 EList<EMap> _properties = c.getProperties();
45 [b]EMap _get = this.<EMap>get(_properties, "Angle");[/b]
46 _builder.append(_get, "");
47 _builder.newLineIfNotEmpty();
48 return _builder;
49 }
The error at line 45 (in bold) is:
Bound mismatch: The generic method get(List<T>, String) of type ConfigGenerator is not applicable for the arguments (EList<EMap>, String). The inferred type EMap is not a valid substitute for the bounded parameter <T extends NamedElement>
In ConfigGenerator.xtend, I imported org.eclipse.uml2.uml.NamedElement.
Is the error caused by using the wrong NamedElement? Is there another one that is a valid substitute? Or, is there some other problem?
Thank you in advance for any assistance!
|
|
|
Re: Getting an element from a list by name in Xtend [message #968412 is a reply to message #967614] |
Fri, 02 November 2012 12:45 |
Sebastian Zarnekow Messages: 3118 Registered: July 2009 |
Senior Member |
|
|
Hi Michael,
I'm not sure where your class 'Property' comes from (which EPackage you
use). Since I think you don't use the UML package intentionally, I think
NamedElement is not what you want to use. Instead you should refer to
your own types in your method #get
Did you try to use
def Property get(List<Property> list, String key) { .. }
as a more simple (yet less reusable) implementation in a first shot?
Does that work.
Nevertheless it looks like you somehow used an existing EPackage where
Config#getProperties yields an EMap and not just an EList. This may
cause some confusion, too. Could you post a complete grammar?
Best regards,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com
Am 02.11.12 13:12, schrieb Michael Colburn:
> Please refer to the following link:
>
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=354799#c11
>
> where as a work-around, it is proposed by Sven Efftinge to use the
> following to get an element from a list by name:
>
>
> def <T extends NamedElement> T get(List<T> list, String key) {
> list.findFirst[ name == key ]
> }
>
>
> I have experimented with this using a very simple grammar named Config:
>
>
> Config: properties+=Property*;
> Property: name=ID '=' value=(ID|STRING);
>
>
> I added the get function (shown above) to my ConfigGenerator.xtend class,
>
> then, entered a call as follows:
>
> def compile(Config c) '''
> «c.properties.get("Angle")» // Angle is the 'name' of a property
> '''
>
> This results in an error in ConfigGenerator.java in the following
> generated method:
>
>
> 42 public CharSequence compile(final Config c) {
> 43 StringConcatenation _builder = new StringConcatenation();
> 44 EList<EMap> _properties = c.getProperties();
> 45 EMap _get = this.<EMap>get(_properties, "Angle");
> 46 _builder.append(_get, "");
> 47 _builder.newLineIfNotEmpty();
> 48 return _builder;
> 49 }
>
>
> The error at line 45 (in bold) is:
>
> Bound mismatch: The generic method get(List<T>, String) of type
> ConfigGenerator is not applicable for the arguments (EList<EMap>,
> String). The inferred type EMap is not a valid substitute for the
> bounded parameter <T extends NamedElement>
>
>
> In ConfigGenerator.xtend, I imported org.eclipse.uml2.uml.NamedElement.
>
> Is the error caused by using the wrong NamedElement? Is there another
> one that is a valid substitute? Or, is there some other problem?
>
> Thank you in advance for any assistance!
>
>
>
>
>
>
>
>
>
|
|
|
Re: Getting an element from a list by name in Xtend [message #968522 is a reply to message #968412] |
Fri, 02 November 2012 14:24 |
Michael Colburn Messages: 10 Registered: November 2012 |
Junior Member |
|
|
Sebastian,
Thank you for your reply!
After I made the original post, I realized that I had pasted the wrong version of ConfigGenerator.java. The correct version (which has the error) is:
public CharSequence compile(final Config c) {
StringConcatenation _builder = new StringConcatenation();
EList<Property> _properties = c.getProperties();
Property _get = this.<Property>get(_properties, "Title");
_builder.append(_get, "");
_builder.newLineIfNotEmpty();
return _builder;
}
I could not get your suggested approach to work, but I realized that all I need to do is the following:
def compile(Config c) '''
«c.properties.findFirst([name == "Title"]).value»
This works fine. Is there a more efficient means, e.g. one that directly accesses via the ID rather than iterating through the list until it is found?
Also, the following does not work. Can you explain why?
def Property get(List<Property> list, String key) {
list.findFirst([name == key])
}
Nor does this:
def Property get(EList<Property> list, String key) {
list.findFirst([name == key])
}
In both cases, the error is:
Couldn't resolve reference to JvmIdentifiableElement '=='.
- Incompatible implicit return type. Expected java.lang.Boolean
or boolean but was void
- Incompatible types. Expected org.eclipse.xtext.xbase.lib.Functions.Function1<?
super org.eclipse.xtend.lib.Property, java.lang.Boolean> but
was (org.eclipse.xtend.lib.Property)=>void
Thanks!
[Updated on: Fri, 02 November 2012 14:53] Report message to a moderator
|
|
|
Re: Getting an element from a list by name in Xtend [message #969598 is a reply to message #968522] |
Sat, 03 November 2012 11:10 |
Sebastian Zarnekow Messages: 3118 Registered: July 2009 |
Senior Member |
|
|
Hi Michael,
no, there is no more efficient version since the list is not indexed by
name or something. You'd have to create that index manually.
You may want to remove the parentheses, though:
c.properties.findFirst[ name == 'Title' ].value
Regards,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com
Am 02.11.12 15:24, schrieb Michael Colburn:
> Sebastian,
>
> Thank you for your reply!
>
> After I made the original post, I realized that I had pasted the wrong
> version of ConfigGenerator.java. The correct version (which has the
> error) is:
>
>
> public CharSequence compile(final Config c) {
> StringConcatenation _builder = new StringConcatenation();
> EList<Property> _properties = c.getProperties();
> Property _get = this.<Property>get(_properties, "Title");
> _builder.append(_get, "");
> _builder.newLineIfNotEmpty();
> return _builder;
> }
>
>
> I could not get your suggested approach to work, but I realized that all
> I need to do is the following:
>
>
> def compile(Config c) '''
> «c.properties.findFirst([name == "Title"]).value»
> '''
>
>
> This works fine. Is there a more efficient means, e.g. one that
> directly accesses via the ID rather than iterating through the list
> until it is found?
> Thanks!
>
|
|
|
Goto Forum:
Current Time: Fri Apr 19 08:18:31 GMT 2024
Powered by FUDForum. Page generated in 0.03485 seconds
|