Hi
Sorry
for the late reply. Yes, there are Eclipse QVTo shortcomings
to fix.
Please
note that your ‘return-type’ has indeed no effect in the
current example, but may be used for filtering the results
by kind. In particular, it will also affect the return type
of the resolve _expression_.
Bypassing
the re-initialization is not directly supported. Your
approach declares the ‘resolved’ variable inside the init
section and reuses it from the outside. Reads smelly and I
didn’t expect this to work at all.
I
suggest to move the initialization to the init section. See
below.
mapping
JClass::jclass2jpackage() : JPackage {
init {
result :=
resolveoneIn(JClass::jclass2jpackage,
p :
JPackage |
self.packageName = p.name);
if (result = null) {
result :=
object
JPackage {
name :=
self.packageName;
}
}
}
}
Do
we really have to bypass the re-initialization? It requires
some extra syntax effort without affecting the visible
behavior of the example.
Should
the syntactical limitations of Eclipse QVTo make it to the
specification? I refer to the JClass:: inside the resolve
_expression_ and also the : JPackage type indication. Both are
redundant.
The
most elegant way to achieve the desired behavior is actually
the following:
mapping
JClass::jclass2jpackage() : JPackage {
init {
result :=
self.packageName.map
packagename2jpackage();
}
}
mapping
String::packagename2jpackage() :
JPackage {
name :=
self;
}
Of
course there is no resolve so it’s not suited as an example
in this section.
Regards
Christopher
Hi Christopher
Thanks
Example 2
result :=
resolveoneIn(JClass::jclass2jpackage,
p : JPackage |
self.packageName = p.name);
works, but trimming either of "JClass::" or "JPackage" gives
errors in the editor. Trimming to just self.packageName =
name gives a triple error. Looks like there are some Eclipse
QVTo bugs to fix here.
Your example using a lambda-_expression_ is very interesting.
The QVT AS specification gives no clue about this; just the
EBNF. The implicit self within such a condition is
unspecified, so maybe self.packageName = name is not
supposed to work in a similar way to an iterator _expression_.
It looks as if the
<resolve_condition> ::= <declarator> ('|'
<_expression_>)?
grammar is wrong. It should be
<resolve_condition> ::= (<declarator> '|')?
<_expression_>
just like an iterator body. Then the 'true' from the
original specification example makes sense as the boring
default _expression_. My 'return-type' are just partial
declarators that have no effect.
The example is specifically showing how to bypass the
re-initialization. How can Eclipse QVTo do this.
Example 4
Wow. That extra "self." is very subtle. Is there anyway to
debug it?
Regards
Ed
On 05/10/2015 10:56, Christopher Gerking
wrote:
Hi
Example
2:
I
see no reason for premature return, at least not in this
example. The resolveIn looks for an existing package which
has been mapped from another class with the same package
name. In case such a package is found, the result becomes
non-null and the implicit instantiation section will not
create a new package. There is no need to “avoid
creating more than two packages having the same name”
because the init section already ensures that package
names are unique. And why “two”, is it a careless mistake?
The
only reason for a premature return could be that the “name
:= self.packageName” initialization reexecutes
unnecessarily. However there is no harm, and other ways
exist to avoid that.
In
Eclipse QVTo the init section can be rewritten more
concisely as
result :=
resolveoneIn(JClass::jclass2jpackage,
p : JPackage |
self.packageName = p.name);
So
yes, there are optional predicates for the target, but I
also don’t understand why there is a “true” predicate.
The
following is even more concise and should maybe make it to
the specification:
result :=
resolveoneIn(jclass2jpackage,
p |
self.packageName = p.name);
The
package name should be enough to select the resolved
mapping, no need for the JCLass:: prefix. Also the p is
already known as JPackage, so there should be no need for
the additional : JPackage type indication.
Example
4:
The
init section of the second mapping must be rewritten in
order to update the correct Java interface. Therefore the
resolveIn requires self as source:
mapping
UML::Class::transformClassInheritance() : JAVA::Interface {
init{
result :=
self.resolveoneIn(UML::Class::transformClass);
}
base :=
self.superClass.resolveIn(UML::Class::transformClass);
}
Regards
Christopher
Hi
In Issue 15376 http://solitaire.omg.org/browse/QVT13-16,
I complain that the examples in 8.1.10 are problematic.
The second example contains
"if result then return;"
which has a non-boolean condition _expression_ and a
missing endif.
In the first example, it is not clear that the
revisit adds rather than overwrites.
In the third and fourth examples it is not clear
why the second pass reuses the context for the first
rather than creates new objects.
5 years later this comes back to haunt
me. With a slightly better understanding of QVTo, my
complaints seem rather understated, the examples are quite
terrible.
The attached ZIP file contains a project with launch
configurations that represent my best attempt at making the
examples work.
----
I cannot get the second example to work:
transformation JClass2JPackage(inout javamodel:JAVA);
main () {
javamodel->objectsOfType(JClass)->jclass2jpackage();}
mapping Class::jclass2jpackage() : JPackage () {
init {
result := resolveIn(jclass2jpackage,true)
->select(p|self.package=p.name)->first();
if result then return;
}
name := self.package;
}
when changed to (JClass2JPackage.qvto):
modeltype JAVA uses 'http://www.omg.org/qvt/examples/javamodel';
transformation JClass2JPackage(inout javamodel:JAVA);
main () { javamodel.objectsOfType(JClass)->jclass2jpackage();}
mapping JClass::jclass2jpackage() : JPackage /*()*/{
init {
result := resolveIn(JClass::jclass2jpackage,JPackage)
->select(p|self.packageName=p.name)->first();
--if (result <> null) return;
}
name := self.packageName;
}
I am defeated by the "if result then return" line.
It seems that we must use () to force the imperative rather
than declarative if.
Presumably we need "<> null" to ensure a Boolean
condition, but Eclipse QVTo doesn't complain about this,
perhaps other bugs occlude this warning.
A value-less return is diagnosed as an error so I tried
"return result", so that:
The premature return is diagnosed as not supported by
Eclipse QVTo.
Iff the premature return is really needed, then the missing
support in Eclipse QVTo is bad.
But I don't understand the resolveIn at all, the second
argument seems optional and undocumented. Is it an optional
predicate on the return value?
The semantics of the init look very important and suspect.
Presumably the resolveIn target is created before/as the
init executes but even if it does, surely, JPackage::name is
uninitialized so that ->first() must always return
invalid since the name match fails and no successful mapping
ever executes?
------
Third example using late resolve seems fine apart from
typos.
------
I cannot make the fourth two-pass variant work. After
changing (UML2JavaTwoPass.qvto)
transformation Uml2Java(in uml:UML,out java:JAVA)
main() : JAVA::Interface {
uml->objectsOfType(Class)->map transformClass();
uml->objectsOfType(Class)->map
transformClassInheritance();
}
mapping UML::transformClass() : JAVA::Interface {
name := "Ifce".concat(self.name);
}
mapping UML::transformClassInheritance() : JAVA:Interface {
base :=
self.superClass->resolveIn(transformClass,JAVA::Interface);
}
to
modeltype JAVA uses 'http://www.omg.org/qvt/examples/javamodel';
modeltype UML uses 'http://www.omg.org/qvt/examples/umlmodel';
transformation Uml2Java(in uml:UML,out java:JAVA);
main() /*: JAVA::Interface*/ {
uml.objectsOfType(Class)->map transformClass();
uml.objectsOfType(Class)->map
transformClassInheritance();
}
mapping UML::Class::transformClass() :
JAVA::Interface {
name := "Ifce".concat(self.name);
}
mapping UML::Class::transformClassInheritance() :
JAVA::Interface {
init{
result :=
resolveIn(UML::Class::transformClass,JAVA::Interface)->first();
}
result.base :=
self.superClass.resolveIn(UML::Class::transformClass,JAVA::Interface);
}
I am unable to persuade the second pass to re-use the first.
Can anyone help? Is it an Eclipse QVTo bug?
Regards
Ed Willink
_______________________________________________
qvto-dev mailing list
qvto-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/qvto-dev
No
virus found in this message.
Checked by AVG - www.avg.com
Version: 2015.0.6140 / Virus Database: 4435/10762 - Release
Date: 10/05/15