Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » [xbase/xcore] infer and refer to constructor
[xbase/xcore] infer and refer to constructor [message #714765] Thu, 11 August 2011 12:53 Go to next message
Eclipse UserFriend
Originally posted by:

Hi,

I'm trying to infer and refer to a JvmConstructor for an
XClass/EClass/GenClass in Xcore. This worked well in a different
project, I could both infer and refer to it. However, in Xcore I use the
same technique, but the scope created for the constructor does not
contain the inferred constructor. During debugging I've noticed that the
EObjectDescriptions seems to contain the XClass, but somehow it doesn't
find the corresponding inferred constructor. I'm not sure I understand
how Xbase translates from an EObject to the corresponding inferred
JvmType, but something seems to be missing.

The only difference in my code between these two projects is how the
constructor is associated with the XClass. In the working one I use an
JvmModelAssociator, while in Xcore a special mapping object is used. I
don't know how this mapping object is used during scoping/linking.

Hallvard
Re: [xbase/xcore] infer and refer to constructor [message #714847 is a reply to message #714765] Thu, 11 August 2011 15:15 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33113
Registered: July 2009
Senior Member
Hallvard,

Hopefully I can get a chance to play with this today to see what's
happening (as well as to fix the other issue you reported).


On 11/08/2011 5:53 AM, Hallvard Trætteberg wrote:
> Hi,
>
> I'm trying to infer and refer to a JvmConstructor for an
> XClass/EClass/GenClass in Xcore. This worked well in a different
> project, I could both infer and refer to it. However, in Xcore I use
> the same technique, but the scope created for the constructor does not
> contain the inferred constructor. During debugging I've noticed that
> the EObjectDescriptions seems to contain the XClass, but somehow it
> doesn't find the corresponding inferred constructor. I'm not sure I
> understand how Xbase translates from an EObject to the corresponding
> inferred JvmType, but something seems to be missing.
>
> The only difference in my code between these two projects is how the
> constructor is associated with the XClass. In the working one I use an
> JvmModelAssociator, while in Xcore a special mapping object is used. I
> don't know how this mapping object is used during scoping/linking.
>
> Hallvard


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [xbase/xcore] infer and refer to constructor [message #714931 is a reply to message #714847] Thu, 11 August 2011 19:08 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by:

On 11.08.11 17.15, Ed Merks wrote:
> Hallvard,
>
> Hopefully I can get a chance to play with this today to see what's
> happening (as well as to fix the other issue you reported).

Here's the relevant code I've written:

XcoreJvmInferrer:

public List<? extends JvmDeclaredType> getDeclaredTypes(GenClass
genClass)
{
...
if (! (genClass.getEcoreClass().isAbstract() ||
genClass.getEcoreClass().isInterface())) {
members.add(getJvmConstructor(genClass));
}
result.add(jvmGenericType);
}
return result;
}

JvmConstructor getJvmConstructor(GenClass genClass) {
JvmConstructor jvmConstructor =
TypesFactory.eINSTANCE.createJvmConstructor();
jvmConstructor.setSimpleName(genClass.getName());
jvmConstructor.setVisibility(JvmVisibility.PUBLIC);
final XClass xClass = mapper.getXClass(genClass);
mapper.getMapping(xClass).setConstructor(jvmConstructor);
mapper.getToXcoreMapping(jvmConstructor).setXcoreElement(xClass);
return jvmConstructor;
}

XClassMapping:

private JvmConstructor constructor;

public JvmConstructor getConstructor()
{
return constructor;
}

public void setConstructor(JvmConstructor constructor)
{
this.constructor = constructor;
}

Here's also a snippet I think belongs in XcoreInterpreter:

protected Object invokeOperation(JvmOperation operation, Object
receiver, List<Object> argumentValues)
...
else if (element instanceof XClass) {
EClass eClass = mapper.getMapping((XClass)element).getEclass();
EObject eInstance =
eClass.getEPackage().getEFactoryInstance().create(eClass);
// what to do with the arguments, can they be used for initialization?
return eInstance;
}
Re: [xbase/xcore] infer and refer to constructor [message #715079 is a reply to message #714931] Fri, 12 August 2011 09:41 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by:

Hi,

I found the missing piece (which I had in the working project)! The
getFullyQualifiedName method of XcoreQualifiedNameProvider didn't handle
JvmConstructor objects, only JvmType objects. I changed it to work for
JvmIdentifiableElement in general (hopefully that's ok) and now the
inferred constructor is correctly linked to. The next step is to make
the interpreter handle such a constructor and write some tests to prove it.

Hallvard

On 11.08.11 21.08, Hallvard Trætteberg wrote:
> On 11.08.11 17.15, Ed Merks wrote:
>> Hallvard,
>>
>> Hopefully I can get a chance to play with this today to see what's
>> happening (as well as to fix the other issue you reported).
>
> Here's the relevant code I've written:
>
> XcoreJvmInferrer:
>
> public List<? extends JvmDeclaredType> getDeclaredTypes(GenClass genClass)
> {
> ...
> if (! (genClass.getEcoreClass().isAbstract() ||
> genClass.getEcoreClass().isInterface())) {
> members.add(getJvmConstructor(genClass));
> }
> result.add(jvmGenericType);
> }
> return result;
> }
>
> JvmConstructor getJvmConstructor(GenClass genClass) {
> JvmConstructor jvmConstructor =
> TypesFactory.eINSTANCE.createJvmConstructor();
> jvmConstructor.setSimpleName(genClass.getName());
> jvmConstructor.setVisibility(JvmVisibility.PUBLIC);
> final XClass xClass = mapper.getXClass(genClass);
> mapper.getMapping(xClass).setConstructor(jvmConstructor);
> mapper.getToXcoreMapping(jvmConstructor).setXcoreElement(xClass);
> return jvmConstructor;
> }
>
> XClassMapping:
>
> private JvmConstructor constructor;
>
> public JvmConstructor getConstructor()
> {
> return constructor;
> }
>
> public void setConstructor(JvmConstructor constructor)
> {
> this.constructor = constructor;
> }
>
> Here's also a snippet I think belongs in XcoreInterpreter:
>
> protected Object invokeOperation(JvmOperation operation, Object
> receiver, List<Object> argumentValues)
> ...
> else if (element instanceof XClass) {
> EClass eClass = mapper.getMapping((XClass)element).getEclass();
> EObject eInstance =
> eClass.getEPackage().getEFactoryInstance().create(eClass);
> // what to do with the arguments, can they be used for initialization?
> return eInstance;
> }
Re: [xbase/xcore] infer and refer to constructor [message #715107 is a reply to message #715079] Fri, 12 August 2011 11:28 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by:

On 12.08.11 11.41, Hallvard Trætteberg wrote:
> Hi,
>
> I found the missing piece (which I had in the working project)! The
> getFullyQualifiedName method of XcoreQualifiedNameProvider didn't handle
> JvmConstructor objects, only JvmType objects. I changed it to work for
> JvmIdentifiableElement in general (hopefully that's ok) and now the
> inferred constructor is correctly linked to. The next step is to make
> the interpreter handle such a constructor and write some tests to prove it.

The tests revealed that JvmIdentifiableElement was too general, I've
changed it to:

else if (eObject instanceof JvmType || eObject instanceof
JvmConstructor)
{
String qualifiedName = ((JvmIdentifiableElement)
eObject).getQualifiedName();
return nameConverter.toQualifiedName(qualifiedName);
}

After overriding XcoreInterpreter's _evaluateConstructorCall, so it
creates the appropriate EObject, the following test now works (as do the
other tests):

@Test
def void testConstructor() {
val pack = parse.parse('''
package foo.bar

class Foo {
String value
op Foo copy() {
val foo = new Foo()
foo.value = value
return foo
}
}
''')
validator.assertNoErrors(pack)
val ePackage = pack.eResource.contents.get(2) as EPackage
val fooClass = ePackage.getEClassifier("Foo") as EClass
val foo = ePackage.EFactoryInstance.create(fooClass)
val copy = foo.eInvoke(fooClass.EOperations.head, new BasicEList());
assertTrue(copy instanceof EObject);
assertEquals(fooClass, (copy as EObject).eClass());
val valueFeature = fooClass.getEStructuralFeature("value");
assertEquals(foo.eGet(valueFeature), (copy as
EObject).eGet(valueFeature));
}

Hallvard
Re: [xbase/xcore] infer and refer to constructor [message #715184 is a reply to message #715107] Fri, 12 August 2011 15:44 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33113
Registered: July 2009
Senior Member
Hallvard,

This sounds cool. :-)

I've been playing with getting the interpreter working in the reflective
editor (by hacking it in a gross way to create an XtextResourceSet).
From the Xcore editor, you can create a dynamic instance of some
XClass's corresponding EClass. The reflective editor loads the *.xcore
resource while loading the instance and after that your operation
invocation view has proven useful. It can be used to invoke the
interpreter on the dynamic instances in the editor. I've committed the
preliminary changes for Xcore and have attached an updated patch in the
bugzilla.



On 12/08/2011 4:28 AM, Hallvard Trætteberg wrote:
> On 12.08.11 11.41, Hallvard Trætteberg wrote:
>> Hi,
>>
>> I found the missing piece (which I had in the working project)! The
>> getFullyQualifiedName method of XcoreQualifiedNameProvider didn't handle
>> JvmConstructor objects, only JvmType objects. I changed it to work for
>> JvmIdentifiableElement in general (hopefully that's ok) and now the
>> inferred constructor is correctly linked to. The next step is to make
>> the interpreter handle such a constructor and write some tests to
>> prove it.
>
> The tests revealed that JvmIdentifiableElement was too general, I've
> changed it to:
>
> else if (eObject instanceof JvmType || eObject instanceof
> JvmConstructor)
> {
> String qualifiedName = ((JvmIdentifiableElement)
> eObject).getQualifiedName();
> return nameConverter.toQualifiedName(qualifiedName);
> }
>
> After overriding XcoreInterpreter's _evaluateConstructorCall, so it
> creates the appropriate EObject, the following test now works (as do
> the other tests):
>
> @Test
> def void testConstructor() {
> val pack = parse.parse('''
> package foo.bar
>
> class Foo {
> String value
> op Foo copy() {
> val foo = new Foo()
> foo.value = value
> return foo
> }
> }
> ''')
> validator.assertNoErrors(pack)
> val ePackage = pack.eResource.contents.get(2) as EPackage
> val fooClass = ePackage.getEClassifier("Foo") as EClass
> val foo = ePackage.EFactoryInstance.create(fooClass)
> val copy = foo.eInvoke(fooClass.EOperations.head, new
> BasicEList());
> assertTrue(copy instanceof EObject);
> assertEquals(fooClass, (copy as EObject).eClass());
> val valueFeature = fooClass.getEStructuralFeature("value");
> assertEquals(foo.eGet(valueFeature), (copy as
> EObject).eGet(valueFeature));
> }
>
> Hallvard


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:using multiple alternatives - but there are no alternatives?!?!
Next Topic:Content-Assist question
Goto Forum:
  


Current Time: Fri Mar 29 07:51:27 GMT 2024

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

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

Back to the top