Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » How to get collection type parameter (generics) from JvmTypeReference?
How to get collection type parameter (generics) from JvmTypeReference? [message #991013] Mon, 17 December 2012 02:03 Go to next message
Espinosa CZ is currently offline Espinosa CZFriend
Messages: 27
Registered: July 2009
Junior Member
I am trying to write utility method to return collection type

@Inject TypeReferences typeReferences;
public JvmType getCollectionType(JvmTypeReference clazz) {
	if (typeReferences.isInstanceOf(clazz, Collection.class)) {
		collectionType = typeReferences.getArgument(clazz, 0);
		return collectionType;
	}
}


where clazz may represent java.util.List<String>, then I expect the method to return java.lang.String, or for java.util.Set<a.b.m.Book> to return a.b.m.Book.

The promisingly sounding typeReferences.getArgument(..) however returns "JvmParameterizedTypeReference: E" where getType() gives "JvmTypeParameter <E> java.util.List". Hmm. I got into blind alley.

Is it even possible or does the type erasure applies also for JvmTypeReference?

Thank you for any hints.
Espinosa

[Updated on: Mon, 17 December 2012 20:22]

Report message to a moderator

Re: How to get collection type parameter (generics) from JvmTypeReference? [message #991204 is a reply to message #991013] Mon, 17 December 2012 18:02 Go to previous messageGo to next message
Hallvard Traetteberg is currently offline Hallvard TraettebergFriend
Messages: 601
Registered: July 2009
Location: Trondheim, Norway
Senior Member
On 16.12.12 18.03, Espinosa CZ wrote:
> I am trying to write utility method to return collection type
>
>
> @Inject TypeReferences typeReferences;
> public JvmType getCollectionType(JvmTypeReference clazz) {
> if (typeReferences.isInstanceOf(clazz, Collection.class)) {
> collectionType = typeReferences.getArgument(classType, 0);
> return collectionType;
> }
> }
>
> where clazz may represent java.util.List<String>, then I expect the
> method to return java.lang.String, or for java.util.Set<a.b.m.Book> to
> return a.b.m.Book.
>
> The promisingly sounding typeReferences.getArgument(..) however returns
> "JvmParameterizedTypeReference: E" where getType() gives
> "JvmTypeParameter <E> java.util.List". Hmm. I got into blind alley.

I think you're getting the type parameter of the java.util.List type,
instead of the argument of the reference to java.util.List. What about
testing if clazz instanceof JvmParameterizedTypeReference and then
getting its first argument?

Hallvard
Re: How to get collection type parameter (generics) from JvmTypeReference? [message #991241 is a reply to message #991204] Tue, 18 December 2012 00:39 Go to previous messageGo to next message
Espinosa CZ is currently offline Espinosa CZFriend
Messages: 27
Registered: July 2009
Junior Member
Thank you Hallvard.
However it did not help.
It has the same effect as calling typeReferences.getArgument(clazz, 0).

Here is my code:
public List<String> getFieldNamesForClassTreatCollections(JvmTypeReference clazz) {
	JvmTypeReference genericType;
	if (typeReferences.isInstanceOf(clazz, Collection.class)) {
		if (clazz instanceof JvmParameterizedTypeReference) {
			genericType = ((JvmParameterizedTypeReference) clazz)
				.getArguments().get(0);
			System.out.println(genericType);
			System.out.println(genericType.getType());
		}
		
	}
	return genericType;
}


It prints:
JvmParameterizedTypeReference: E
JvmTypeParameter <E> java.util.List


When inspected in Eclipse debugging, the 'genericType' is of type JvmParameterizedTypeReferenceImplCustom. I deep probed all its data but there is no reference to generics type (a.b.m.Section in my case). Only upper and lower bounds (?) and similar stuff.

It must be doable somehow! Xtend2/Xbase has to do generics probing when inferring types and in similar situations.
Re: How to get collection type parameter (generics) from JvmTypeReference? [message #991254 is a reply to message #991241] Tue, 18 December 2012 06:55 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian ZarnekowFriend
Messages: 2961
Registered: July 2009
Senior Member
Am 18.12.12 01:39, schrieb Espinosa CZ:
> Thank you Hallvard.
> However it did not help.
> It has the same effect as calling typeReferences.getArgument(clazz, 0).
>
> Here is my code:
> public List<String>
> getFieldNamesForClassTreatCollections(JvmTypeReference clazz) {
> JvmTypeReference genericType;
> if (typeReferences.isInstanceOf(clazz, Collection.class)) {
> if (clazz instanceof JvmParameterizedTypeReference) {
> genericType = ((JvmParameterizedTypeReference) clazz)
> .getArguments().get(0);
> System.out.println(genericType);
> System.out.println(genericType.getType());
> }
>
> }
> return genericType;
> }
>
> It prints:
> JvmParameterizedTypeReference: E
> JvmTypeParameter <E> java.util.List
>
> When inspected in Eclipse debugging, the 'genericType' is of type
> JvmParameterizedTypeReferenceImplCustom. I deep probed all its data but
> there is no reference to generics type (a.b.m.Section in my case). Only
> upper and lower bounds (?) and similar stuff.
>
> It must be doable somehow! Xtend2/Xbase has to do generics probing when
> inferring types and in similar situations.

Where does your clazz come from when you invoke your method and it
prints 'E' and <E> java.util.List.? How do you create that reference?

Regards,
Sebastian
--
Looking for professional support for Xtext, Xtend or Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: How to get collection type parameter (generics) from JvmTypeReference? [message #991312 is a reply to message #991254] Tue, 18 December 2012 13:30 Go to previous message
Espinosa CZ is currently offline Espinosa CZFriend
Messages: 27
Registered: July 2009
Junior Member
I have cracked it yesterday late night. Solved.
Sebastian, your question is very correct indeed.

The probed type was inferred from parent->field type.
Before anything JvmType related is to be set to Model AST, I have learned recently, one have to create an instance copy of the inferred JvmType. Otherwise all sorts of quirk behavior happen, like the Bug 396433.

I did not use the right copy creating library call:

public JvmTypeReference createDefensiveCopyOfJvmTypeReference(JvmTypeReference typeReference) {
	return typeReferences.createTypeRef(typeReference.getType());
}


I have to use EcoreUtil.copy() or EcoreUtil.clone() instead.

public JvmTypeReference createDefensiveCopyOfJvmTypeReference(JvmTypeReference typeReference) {
	return EcoreUtil.copy(typeReference);
}


Now it works as expected, type parameter (generics) is not lost and getCollectionType() works as expected, no change required:

@Inject TypeReferences typeReferences;
public JvmType getCollectionType(JvmTypeReference clazz) {
	if (typeReferences.isInstanceOf(clazz, Collection.class)) {
		collectionType = typeReferences.getArgument(clazz, 0);
		return collectionType;
	}
}


What is TypeReferences.createTypeRef(jvmType) supposed to do? It worked well until I started to play with parametrized types. You are supposed to provide type parameters yourself? Like createTypeRef(jvmType, jvmTypeParam1, .., jvmTypeParamN). If you do not, then the copy, the created type reference, exhibits "type erasure" like in Java. What is the point?

Regards
Espinosa

P.S.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=396433

[Updated on: Tue, 18 December 2012 13:34]

Report message to a moderator

Previous Topic:Maven repository needed
Next Topic:Parameterized parser rule
Goto Forum:
  


Current Time: Fri Dec 19 21:14:50 GMT 2014

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

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