[xbase/xcore] infer and refer to constructor [message #714765] |
Thu, 11 August 2011 12:53 |
Eclipse User |
|
|
|
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 |
Ed Merks Messages: 33142 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 |
Eclipse User |
|
|
|
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 |
Eclipse User |
|
|
|
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 |
Eclipse User |
|
|
|
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 |
Ed Merks Messages: 33142 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/
|
|
|
Powered by
FUDForum. Page generated in 0.02642 seconds