Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
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 Go to next message
Michael Colburn is currently offline Michael ColburnFriend
Messages: 8
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 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 2961
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 Go to previous messageGo to next message
Michael Colburn is currently offline Michael ColburnFriend
Messages: 8
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 Go to previous message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 2961
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!
>
Previous Topic:Xtend2 fails initializing String[]
Next Topic:Why generated file in /src-gen is removed when input file is not valid
Goto Forum:
  


Current Time: Tue Dec 23 02:20:50 GMT 2014

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

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