Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » [Xbase 2.4] TypeComputer is not invoked
[Xbase 2.4] TypeComputer is not invoked [message #1032057] Tue, 02 April 2013 14:15 Go to next message
Sebastian Benz is currently offline Sebastian Benz
Messages: 6
Registered: March 2011
Junior Member

Hi,

I am trying to calculate the common supertype in Xtext 2.4 using the new typesystem's API. In my DSL you can define tables, which look like:

def myTable {
| column1 | column2 |
| "value1"| "value4" |
| "value2"| "value3" |
}

Each cell in a table is an XExpression. Now I am trying in my JVMModelInferrer to infer the type of each column by calculating the common supertype of all column's expression. This used to work in Xtext 2.3 without problems. With the new typesystem's API I have the problem that the inferred type of each expression is null:

@Inject extension CommonTypeComputationServices commonTypeComputationServices
@Inject private IBatchTypeResolver typeResolver

...

val context = ...
val expressions = ...
val types = expressions.map[
typeResolver.resolveTypes(context).getActualType(it) <- this is always null
]

val typeReferenceOwner = new StandardTypeReferenceOwner(commonTypeComputationServices, context)
val commonSuperType = typeConformanceComputer.getCommonSuperType(types, typeReferenceOwner)

What I have noticed is that the TypeComputer is never invoked for my expressions. Do I need to register my expressions somehow for them to be included in the type inference?

Cheers,

Sebastian
Re: [Xbase 2.4] TypeComputer is not invoked [message #1032152 is a reply to message #1032057] Tue, 02 April 2013 16:20 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian Zarnekow
Messages: 2908
Registered: July 2009
Senior Member
Hi Sebastian,

please refer to the type computation for switch-expressions, collection
literals or if-expressions: You basically propagate the expected type to
your children and have a look at the Javadoc of the ITypeComputer:


The type of an expression depends on its children.
Expression types may be inferred from the types of contained children.
Therefore the given computation state is directly used to compute their
types. The framework will automatically propagate the common type of all
children to the parent. If- or Switch expression fall into this
category. A simplified implementation would again look like this:
void computeTypes(XIfExpression expression, ITypeComputationState state) {
state.withExpectations(getTypeForName(Boolean.TYPE,
state).computeTypes(expression.getIfExpression());
state.computeTypes(expression.getThen());
state.computeTypes(expression.getElse());
}

The If expression adjusts the expectation for one of its children and
computes its type. Afterwards, it directly reuses the current
expectations to compute the types of its branch expressions. The common
super type of those is assigned to the If expression by the framework.
[/snip]

Instead of using #getActualType, you'd use state.computeTypes(cell).
Since the table expression is similar to a collection literal, I'd dive
into that one, instead. In either situation it's your responsibility to
define the expectation for your children and compute their types
explicitely by calling state.computeTypes(..). The result will be
available for clients after all types have been computed. For that
purpose, you'd have to override
XbaseTypeComputer.computeTypes(XExpression, ITypeComputationState) and
handle your new expression types. A dispatch method should work if you
use Xtend.

Let me know if you have trouble with this approach.

Regards,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com

Am 02.04.13 16:15, schrieb Sebastian Benz:
> Hi,
>
> I am trying to calculate the common supertype in Xtext 2.4 using the new
> typesystem's API. In my DSL you can define tables, which look like:
>
> def myTable {
> | column1 | column2 |
> | "value1"| "value4" |
> | "value2"| "value3" |
> }
>
> Each cell in a table is an XExpression. Now I am trying in my
> JVMModelInferrer to infer the type of each column by calculating the
> common supertype of all column's expression. This used to work in Xtext
> 2.3 without problems. With the new typesystem's API I have the problem
> that the inferred type of each expression is null:
>
> @Inject extension CommonTypeComputationServices
> commonTypeComputationServices
> @Inject private IBatchTypeResolver typeResolver
>
> ..
>
> val context = ...
> val expressions = ...
> val types = expressions.map[
> typeResolver.resolveTypes(context).getActualType(it) <- this is
> always null
> ]
>
> val typeReferenceOwner = new
> StandardTypeReferenceOwner(commonTypeComputationServices, context)
> val commonSuperType = typeConformanceComputer.getCommonSuperType(types,
> typeReferenceOwner)
>
> What I have noticed is that the TypeComputer is never invoked for my
> expressions. Do I need to register my expressions somehow for them to be
> included in the type inference?
>
> Cheers,
>
> Sebastian
Re: [Xbase 2.4] TypeComputer is not invoked [message #1032225 is a reply to message #1032152] Tue, 02 April 2013 18:36 Go to previous messageGo to next message
Sebastian Benz is currently offline Sebastian Benz
Messages: 6
Registered: March 2011
Junior Member

Thanks for the quick reply. I might have misphrased my question. My problem is not implementing the TypeComputer but the JvmModelInferrer. I need to access the types of the expressions in order to generate a corresponding constructor. This is why I am using IBatchTypeResolver#getActualType(...). However, this call returns null as the type computer is never invoked for the table cell expressions. I can fix the latter by extending DispatchAndExtensionAwareReentrantTypeResolver to explicitly trigger the computation of the types for the tables, but this leads to some other problems and does not feel like the correct approach.

My question is how can I influence for which elements of my DSLs the type computation will be performed?
Re: [Xbase 2.4] TypeComputer is not invoked [message #1032742 is a reply to message #1032225] Wed, 03 April 2013 11:34 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian Zarnekow
Messages: 2908
Registered: July 2009
Senior Member
Am 02.04.13 20:36, schrieb Sebastian Benz:
> Thanks for the quick reply. I might have misphrased my question. My
> problem is not implementing the TypeComputer but the JvmModelInferrer. I
> need to access the types of the expressions in order to generate a
> corresponding constructor. This is why I am using
> IBatchTypeResolver#getActualType(...). However, this call returns null
> as the type computer is never invoked for the table cell expressions. I
> can fix the latter by extending
> DispatchAndExtensionAwareReentrantTypeResolver to explicitly trigger the
> computation of the types for the tables, but this leads to some other
> problems and does not feel like the correct approach.
> My question is how can I influence for which elements of my DSLs the
> type computation will be performed?

It's actually not allowed to use a computed type in the inferer itself,
since the type computation depends most likely on resolved links which
depend on the available signatures. The type proxies that are available
in the JvmTypesBuilder v2.3 have been superseded by
JvmTypesBuilder#inferredType(XExpression?), so if you need a certain
type to be inferred to put it into a signature, you'd have to use such a
reference and handle it explicitly in the ReentrantTypeResolver.

Type computation will be performed for all expressions in the model,
e.g. primary traversal is done for the JvmModel and its logically
contained expressions and as a last resort for broken models, the source
model is traversed, too. In other words: the tables, their columns and
rows will be travered if they are logically contained in a JVM element.
I'm not sure how this approach suits your needs. Unfortunately I
currently don't have the time to explore the implementation that you had
for 2.3.1 but I'm optimistic that the inferredType(..) approach will
work out for your use-case, too. Please point me to all the stumbling
blocks that I put into your way :-)

Regards,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: [Xbase 2.4] TypeComputer is not invoked [message #1033564 is a reply to message #1032742] Thu, 04 April 2013 11:25 Go to previous messageGo to next message
Sebastian Benz is currently offline Sebastian Benz
Messages: 6
Registered: March 2011
Junior Member

Quote:

Am 02.04.13 20:36, schrieb Sebastian Benz:
> Thanks for the quick reply. I might have misphrased my question. My
> problem is not implementing the TypeComputer but the JvmModelInferrer. I
> need to access the types of the expressions in order to generate a
> corresponding constructor. This is why I am using
> IBatchTypeResolver#getActualType(...). However, this call returns null
> as the type computer is never invoked for the table cell expressions. I
> can fix the latter by extending
> DispatchAndExtensionAwareReentrantTypeResolver to explicitly trigger the
> computation of the types for the tables, but this leads to some other
> problems and does not feel like the correct approach.
> My question is how can I influence for which elements of my DSLs the
> type computation will be performed?

It's actually not allowed to use a computed type in the inferer itself,
since the type computation depends most likely on resolved links which
depend on the available signatures. The type proxies that are available
in the JvmTypesBuilder v2.3 have been superseded by
JvmTypesBuilder#inferredType(XExpression?), so if you need a certain
type to be inferred to put it into a signature, you'd have to use such a
reference and handle it explicitly in the ReentrantTypeResolver.


OK, this makes sense. I managed to get a first working version using this approach. The Xtend implementation was actually a good guide on how to use this approach.

Quote:
Type computation will be performed for all expressions in the model,
e.g. primary traversal is done for the JvmModel and its logically
contained expressions and as a last resort for broken models, the source
model is traversed, too. In other words: the tables, their columns and
rows will be travered if they are logically contained in a JVM element.
I'm not sure how this approach suits your needs. Unfortunately I
currently don't have the time to explore the implementation that you had
for 2.3.1 but I'm optimistic that the inferredType(..) approach will
work out for your use-case, too. Please point me to all the stumbling
blocks that I put into your way Smile


Triggering the type computation based on the JVM model definitely makes sense. However, this forces you to have a clean mapping between your domain model and the JVM model as hacks no longer work (like in my case). This can make it a little bit harder, but I think it results in the end in a cleaner solution.

I got a basic version working, but there are some things which still do not work:

- The inferred type for closures in table cells cannot be retrieved. It is computed correctly but serializing the cell type results in a NPE.
- My table cells cannot access fields declared in the same type.

My theory is that both problems result from the table cells not being correctly linked to the JVM model, but I had not yet time to into it in more detail. I have to admit that I haven't yet fully understood when it is important to just associate two elements, when to associate them primary, when to associate a logical container and what the implications of these associations are.
Re: [Xbase 2.4] TypeComputer is not invoked [message #1033781 is a reply to message #1033564] Thu, 04 April 2013 16:34 Go to previous message
Sebastian Zarnekow is currently offline Sebastian Zarnekow
Messages: 2908
Registered: July 2009
Senior Member
Hi Sebastian,

let me try to answer the questions from the last paragraph:


The associations is basically just a navigation thing (except for
dispatch methods). If a certain region in a Java file should be revealed
in an editor, the association is used to find the original Xtend source
element. Scoping / the type inference uses the logical container. I'm
aware of a bug in 2.3.1 which allowed to use more than one expression as
the *logically contained* body of a constructor / operation. Even though
that could have been used to implement what seemed to be proper scoping,
it could lead to problems. This was fixed, even though not entirely. It
is unfortunately still possible to set the very same JVM element es the
logical container of more than one expression, but only of the
expressions will be considered (there is no exception thrown to indicate
a programming problem but just some quirky misbehavior). We will support
other things like logically contained expressions in other expressions,
but that is currently not possible. Therefore, you'd have to put each of
your cell expressions into an own _init_5_2 method to get proper scoping
semantics. The constructor would be the black-box that delegates to the
init methods.

The NPEs indicate expressions that are not yet linked or that don't have
an associated type, which would be a follow up problem.

Regards,
Sebastian

Am 04.04.13 13:25, schrieb Sebastian Benz:
> Quote:
>> Am 02.04.13 20:36, schrieb Sebastian Benz:
>> > Thanks for the quick reply. I might have misphrased my question. My
>> > problem is not implementing the TypeComputer but the
>> JvmModelInferrer. I
>> > need to access the types of the expressions in order to generate a
>> > corresponding constructor. This is why I am using
>> > IBatchTypeResolver#getActualType(...). However, this call returns null
>> > as the type computer is never invoked for the table cell expressions. I
>> > can fix the latter by extending
>> > DispatchAndExtensionAwareReentrantTypeResolver to explicitly trigger
>> the
>> > computation of the types for the tables, but this leads to some other
>> > problems and does not feel like the correct approach.
>> > My question is how can I influence for which elements of my DSLs the
>> > type computation will be performed?
>>
>> It's actually not allowed to use a computed type in the inferer
>> itself, since the type computation depends most likely on resolved
>> links which depend on the available signatures. The type proxies that
>> are available in the JvmTypesBuilder v2.3 have been superseded by
>> JvmTypesBuilder#inferredType(XExpression?), so if you need a certain
>> type to be inferred to put it into a signature, you'd have to use such
>> a reference and handle it explicitly in the ReentrantTypeResolver.
>
>
> OK, this makes sense. I managed to get a first working version using
> this approach. The Xtend implementation was actually a good guide on how
> to use this approach.
> Quote:
>> Type computation will be performed for all expressions in the model,
>> e.g. primary traversal is done for the JvmModel and its logically
>> contained expressions and as a last resort for broken models, the
>> source model is traversed, too. In other words: the tables, their
>> columns and rows will be travered if they are logically contained in a
>> JVM element. I'm not sure how this approach suits your needs.
>> Unfortunately I currently don't have the time to explore the
>> implementation that you had for 2.3.1 but I'm optimistic that the
>> inferredType(..) approach will work out for your use-case, too. Please
>> point me to all the stumbling blocks that I put into your way :)
>
>
> Triggering the type computation based on the JVM model definitely makes
> sense. However, this forces you to have a clean mapping between your
> domain model and the JVM model as hacks no longer work (like in my
> case). This can make it a little bit harder, but I think it results in
> the end in a cleaner solution.
> I got a basic version working, but there are some things which still do
> not work:
>
> - The inferred type for closures in table cells cannot be retrieved. It
> is computed correctly but serializing the cell type results in a NPE. -
> My table cells cannot access fields declared in the same type.
> My theory is that both problems result from the table cells not being
> correctly linked to the JVM model, but I had not yet time to into it in
> more detail. I have to admit that I haven't yet fully understood when it
> is important to just associate two elements, when to associate them
> primary, when to associate a logical container and what the implications
> of these associations are.
Previous Topic:Problem when generating Xtext problem from different EMF models
Next Topic:DSL Maturing, next steps
Goto Forum:
  


Current Time: Thu Oct 23 20:10:48 GMT 2014

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

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