Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » [Acceleo] eClass().name comparison not working ..
[Acceleo] eClass().name comparison not working .. [message #677567] Wed, 08 June 2011 16:32 Go to next message
the_ch40s is currently offline the_ch40s
Messages: 14
Registered: April 2011
Junior Member
Hello,
me again^^.

I have some unexpected behaviour:
I got two names of eClasses, which show up exactly the same in the generated code, but their comparison always returns false. This is the code-example:

[for vhdlEnt : VHDLEntity | module.eContents(VHDLEntity) )]
[for (port: ModulePort | module.eContents(ModulePort) )]
    [if (port.eClass().name = vhdlEnt.eClass().name)]
        true
    [/if]
    [port.eClass().name/]
    [vhdlEnt.eClass().name/]
[/for]
[/for]


As stated above, the two expressions below the if-block return the exact same string( AKFixedPoint), but the if-block itself just doesn't evaluate to true.
What am i missing?

Thanks in advance Smile

greetz

[Updated on: Wed, 08 June 2011 16:38]

Report message to a moderator

Re: [Acceleo] eClass().name comparison not working .. [message #677594 is a reply to message #677567] Wed, 08 June 2011 17:05 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 3844
Registered: July 2009
Senior Member
Hi

This example cannot be what you're executing.

- the first for has a parenthesis mismatch
- both fors are terminated by /if
- the name printpouts lack a /

Regards

Ed Willink

On 08/06/2011 21:32, forums-noreply@eclipse.org wrote:
> Hello,
> me again^^.
>
> I have some unexpected behaviour:
> I have to names of eClasses, which show up exactly the same in the
> generated code, but their comparison always returns false. This is the
> code-example:
>
> [for vhdlEnt : VHDLEntity | module.eContents(VHDLEntity) )]
> [for (port: ModulePort | module.eContents(ModulePort) )]
> [if (port.eClass().name = vhdlEnt.eClass().name)]
> true
> [/if]
> [port.eClass().name]
> [vhdlEnt.eClass().name]
> [/if]
> [/if]
>
> As stated above, the two expressions below the if-block return the
> exact same string, but the if-block itself just doesn't evaluate to true.
> What am i missing?
>
> Thanks in advance :)
>
> greetz
Re: [Acceleo] eClass().name comparison not working .. [message #677599 is a reply to message #677594] Wed, 08 June 2011 18:19 Go to previous messageGo to next message
the_ch40s is currently offline the_ch40s
Messages: 14
Registered: April 2011
Junior Member
Sorry, i edited the post a bit later.
The code is not exactly like that, but it sums it up. Here is the corrected version

[for (vhdlEnt : VHDLEntity | module.eContents(VHDLEntity) )]
[for (port: ModulePort | module.eContents(ModulePort) )]
    [if (port.eClass().name = vhdlEnt.eClass().name)]
        true
    [/if]
    [port.eClass().name/]
    [vhdlEnt.eClass().name/]
[/for]
[/for]


Anyways, i found a solution:
If i change the if-block to
...
if( port.eClass().name.toString() = vhdlEnt.eClass.name.toString()
...

it works as expected, what surprises me a bit, since eClass().name returns an EString, and i was under the impression that i could use the equal operator on it.

Would be nice if someone could clear this up Smile

Thanks for the help.

[Updated on: Wed, 08 June 2011 18:19]

Report message to a moderator

Re: [Acceleo] eClass().name comparison not working .. [message #677665 is a reply to message #677599] Thu, 09 June 2011 01:56 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 3844
Registered: July 2009
Senior Member
Hi

If i change the if-block to
> ..
> if( port.eClass().name.toString() =
> vhdlEnt.eClass.name.toString()
> ..
>
>
> It works as expected, what surprises me a bit, since eClass().name
> returns an EString, and i was under the impression that i could use
> the equal operator on it.
Yes. This is an OCL expression malfunctioning but in an Acceleo context.

It looks as if either left or right hand side has not been converted
from EString to String and so the actual comparison occurs for one of
String/EString, EString/String when String/String should have occurred.

I've endeavoured to reproduce this in Eclipse OCL 3.1.0RC4 without
success. I'll let the Acceleo guys respond since it may be an Acceleo
issue. Certainly the eContents(...) is Acceleo specific.

Are you sure you're final posting is what you tested?
'vhdlEnt.eClass.name' woiuld explain it; comparison of a class name and
an operation name.

[The reported beheviour is actually 'correct'; the OCL specification
defines only OclAny::=(OclAny) and defines it as Object identity
comparison (i.e Java's = rather than equals()). Fortunately nobody
intentionally implements the specification this way and there is an
issue raised to get the specification changed.]

Regards

Ed Willink
Re: [Acceleo] eClass().name comparison not working .. [message #677721 is a reply to message #677665] Thu, 09 June 2011 04:40 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent Goubet
Messages: 1609
Registered: July 2009
Senior Member
Hi,

@Ed : that doesn't really make sense :
"It looks as if either left or right hand side has not been converted
from EString to String and so the actual comparison occurs for one of
String/EString, EString/String when String/String should have occurred."
Internally, we are simply delegating to OCL the evaluation of the operation call. IIRC, the actual comparison through OCL will evaluate both side's property calls, then use "equals()" on these values. Both sides are a String, string.equals(anotherString) will return true if they have the same value.

What I suspect here is more the "usual" problem of comparing a collection (containing a single String) with a String.

Could you post the real example where you observe this failure?

Laurent Goubet
Obeo
Re: [Acceleo] eClass().name comparison not working .. [message #677731 is a reply to message #677721] Thu, 09 June 2011 04:59 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 3844
Registered: July 2009
Senior Member
Hi Laurent
> What I suspect here is more the "usual" problem of comparing a
> collection (containing a single String) with a String.
That's certainly a possible failure, though very unlikely given the
symmetry of the 'problem', however the lack of an accurate exposition
does not inspire confidence that we aren't dealing with a typo.

Behind the scenes, EString is difficult.

The mature code has OCL Strings and EStrings and it is necessary to
invoke getOCLType to normalize. An omitted getOCLType could explain the
problem since an = could be found but it would be on partially converted
objects.

The pivot code has similar challenges between Strings and DataTypes
behaving as Strings. The pivot code has to call getBehavioralType() to
normalize. I'm looking for a way to make this less subject to programmer
oversight.

Regards

Ed Willink
Re: [Acceleo] eClass().name comparison not working .. [message #677746 is a reply to message #677721] Thu, 09 June 2011 05:27 Go to previous messageGo to next message
the_ch40s is currently offline the_ch40s
Messages: 14
Registered: April 2011
Junior Member
@Ed
I just typed the code as an example, and there was a typo again ^^, it's eClass().name on both sides.

@Laurent
Of course Smile
Here is the complete example:
...
[for (mod : Module | eContents(Module))]
	[for (vhdlEnt : VHDLEntity | mod.getVHDLEnts())]	
		[for (port : ModulePort | mod.eContents(ModulePort))]
		[let vhdlPort : VHDLPort = vhdlEnt.vhdlPorts->select(entityPort = port.entityPort)->first()]
			[if (getAKType(port).toString() = getAKType(vhdlPort).toString() )]
					true
			[/if]
		[/let]
		[/for]
 	[/for]
[/for]
 
[/template]

[query public getAKType(port : ModulePort) : String
				= port.eInverse(Channel).akType.oclAsType(AKTypeLiteral).value.eClass().name /]
				
[query public getAKType(port : VHDLPort) : String
				= port.akType.eClass().name /]

[query public getVHDLEnts(mod : Module) : OrderedSet(VHDLEntity) 
				= mod.entity.eInverse(VHDLEntity) /]



This works as intended.
However, if i leave out the ".toString()" on the getAKType() calls, the if-block will not evaluate to true, although printing out getAKTypye() for both sides individually will return the exact same result (at least it looks like it^^).
Moving the ".toString()" into the getAKType query(so it would be "... .eClass().name.toString()" won't help either, it will then take another ".toString()" at the call of the query, to work as expected.
The same thing happens if i do not use the querys(or the let), but use the expressions directly.

Thanks for the answers so far Smile
Re: [Acceleo] eClass().name comparison not working .. [message #677779 is a reply to message #677746] Thu, 09 June 2011 07:27 Go to previous messageGo to next message
Laurent Goubet is currently offline Laurent Goubet
Messages: 1609
Registered: July 2009
Senior Member
As I Thought : you're not comparing "String"s, but a Sequence with a String. Acceleo has its own pretty printer for Collections so that we do not print the starting "[", the "," separator and the trailing "]" of the "normal" collection.toString(). That is why you have things that "seem" equals when printed, even though they are not. As for why it works with ".toString()", I won't enter in the details, but that, too, should fail. It works because of a parser shortcoming that's been highlighted in Acceleo 3.1 (i.e : in 3.1, you'd have at least two warnings with this module).

The problem is that we did not check for the validity of Queries return types. You could have a query returning a boolean value, yet declared as "[query public query() : String = true]". Your "getAKType(ModulePort)" query really returns a Sequence of Strings, not a String. "eInverse" returns a Sequence; all subsequent calls are implicit collect operations. You should rewrite it like this :

[query public getAKType(port : ModulePort) : String
				= port.eInverse(Channel)->first().akType.oclAsType(AKTypeLiteral).value.eClass().name /]


On the contrary, "getAKType(port : VHDLPort)" properly returns a single String.

Laurent Goubet
Obeo
Re: [Acceleo] eClass().name comparison not working .. [message #677790 is a reply to message #677779] Thu, 09 June 2011 07:55 Go to previous message
the_ch40s is currently offline the_ch40s
Messages: 14
Registered: April 2011
Junior Member
Thanks for the detailed explanation Smile

Really appreciate it !
Previous Topic:[Acceleo] Acceleo Application run configuration icw deployed generator
Next Topic:New Acceleo Project wizard
Goto Forum:
  


Current Time: Sat Apr 19 13:19:16 EDT 2014

Powered by FUDForum. Page generated in 0.01802 seconds