Skip to main content



      Home
Home » Modeling » TMF (Xtext) » Resolving type parameters in the Jvm types
Resolving type parameters in the Jvm types [message #1152927] Thu, 24 October 2013 04:55 Go to next message
Eclipse UserFriend
Hi,

I'm using Xbase and JvmType and the Java model inferer support in a DSL
that is supposed to make it easier to implement event handlers, e.g. for
swing and javafx. In the generated Java there will be implementations of
various listeners, based on the types and methods that are found when
traversing/analyzing the API. E.g. a javafx TextField has a
textProperty() method and its return value is a StringProperty which has
an addListener(ChangeListener) method, so I need an implementation of
ChangeListener to react to changes to a text field. The generated code
in this case looks like the following:

public class textField1TextListener implements ChangeListener<?> {
public void changed(final ObservableValue<? extends ?> arg0, final
? arg1, final ? arg2) {

The type parameters complicates the matter, since the type signatures of
the relevant classes are something like this (a bit simplified):

class ObservableValue<T> {
addListener(ChangeListener<T>)
}

class StringProperty extends ObservableValue<String> {
}

The problem with my generated code is that the types refer to type
parameters that are not resolved against the StringProperty context and
its <String> type argument to ObservableValue.

This is a common problem when working with Java types and I'm sure Xtext
has code for this already. Are there any utility classes that I can
(re)use for solving my problem?

Hallvard
Re: Resolving type parameters in the Jvm types [message #1159179 is a reply to message #1152927] Mon, 28 October 2013 06:50 Go to previous message
Eclipse UserFriend
Hi,

Considering a JvmTypeReference R1 in a JvmType T1 with type parameters (for example ChangeListener<T> fron the addListener method declared in ObservableValue<T>) and considering a JvmTypeReference R2 of the JvmType (for example ObservableValue<String>), if I want to get R1 with type parameters substituted (thus to get ChangeListener<String>), I do that:

val mapping = new ConstraintAwareTypeArgumentCollector(containerTypeRef.owner).getTypeParameterMapping(containerTypeRef)
new StandardTypeParameterSubstitutor(mapping, containerTypeRef.owner).substitute(tr)


containerTypeRef is a LightweightTypeReference created from R2 (check XBaseValidator to see how to create such a LightweightTypeReference, there is a helper method there).
tr is a LightweightTypeReference created from R1.

Problem with that is that it does not take the hierarchy of classes into account (if for example R1 is actually defined in a super class of T1 but you only have R2 a reference to T1).

Here is my raw code for it, it contains things that are specific to my grammar, to check who owns the reference (and thus the type parameters that must be substituted:
private def LightweightTypeReference resolveType(LightweightTypeReference portTypeRef, LightweightTypeReference containerTypeRef, Port port) {
	val ac = containerTypeRef.type.associatedAbstractComponent
	val tr = if (!(ac.provides.contains(port) || ac.requires.contains(port)) && ac.specializes != null) {
		val nptr = ac.specializes.toLightweightTypeReference(port.eResource)
		resolveType(portTypeRef, nptr, port)
	} else {
		portTypeRef
	}
	val mapping = new ConstraintAwareTypeArgumentCollector(containerTypeRef.owner).getTypeParameterMapping(containerTypeRef)
	new StandardTypeParameterSubstitutor(mapping, containerTypeRef.owner).substitute(tr)
}
Previous Topic:Custom validation rules marker
Next Topic:Interpreter for xtext
Goto Forum:
  


Current Time: Fri Jul 04 17:07:12 EDT 2025

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

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

Back to the top