Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » How to infer a method with generics?(How to create a JvmOperation with generics)
How to infer a method with generics? [message #1749037] Thu, 01 December 2016 11:14 Go to next message
Peter Luthardt is currently offline Peter LuthardtFriend
Messages: 35
Registered: February 2014
Member
I am trying to enhance my DSL which is derived from XbaseWithAnnotations to enable the use of generic method.

The user should write something like this:

op <T> doSomething (T arg)
{
println("Hallo"+T)
}

1.) Is there a nice way to do this? I am sure I am not the first one who tries to do something like this. but I could not find any example.
2.) I could not figure out how to tell the JvmOpertation about the generics.

Any hint welcome

Thank you



Re: How to infer a method with generics? [message #1749049 is a reply to message #1749037] Thu, 01 December 2016 12:52 Go to previous messageGo to next message
Alex Tugarev is currently offline Alex TugarevFriend
Messages: 14
Registered: July 2011
Junior Member
In YourDslJvmModelInferrer you'll need:
    @Inject private org.eclipse.xtext.common.types.TypesFactory typesFactory
    @Inject private org.eclipse.xtext.common.types.util.TypeReferences references


Then when iterating over features you need to create type parameter first:
    val tp = typesFactory.createJvmTypeParameter()
    tp.name = "T"


And then add this type parameter to JvmOperation instance and also as type of parameter.

        members += operation.toMethod(operation.name, references.createTypeRef(tp)) [
            typeParameters += tp
            parameters += params.head.toParameter(p.name, references.createTypeRef(tp))
            // ...
        ]

[Updated on: Fri, 02 December 2016 12:08]

Report message to a moderator

Re: How to infer a method with generics? [message #1749064 is a reply to message #1749049] Thu, 01 December 2016 14:22 Go to previous messageGo to next message
Peter Luthardt is currently offline Peter LuthardtFriend
Messages: 35
Registered: February 2014
Member
Thanks, but is works only for one Method

        members += operation.toMethod(f.name, references.createTypeRef(tp)) [
            typeParameters += tp
            parameters += params.head.toParameter(p.name, references.createTypeRef(tp))
            // ...
        ]
       members += operation.toMethod(f.name+"X", references.createTypeRef(tp)) [
            typeParameters += tp
            parameters += params.head.toParameter(p.name, references.createTypeRef(tp))
            // ...
        ]

Does not work. "Cannot make a static reference to the non-static type T"

I need to create an Interface and an Implementation so I have to use it twice. (I tried tp.cloneWithProxies, but no success)
Re: How to infer a method with generics? [message #1749071 is a reply to message #1749064] Thu, 01 December 2016 14:59 Go to previous messageGo to next message
Alex Tugarev is currently offline Alex TugarevFriend
Messages: 14
Registered: July 2011
Junior Member
Just create one type parameter per operation. Then they can be named the same.
Re: How to infer a method with generics? [message #1749074 is a reply to message #1749071] Thu, 01 December 2016 15:39 Go to previous messageGo to next message
Peter Luthardt is currently offline Peter LuthardtFriend
Messages: 35
Registered: February 2014
Member
I do not understand.
Creating the genericTypes twice does not solve the problem
	val genericTypes = method.createJvmTypeParameter()
	members += method.toMethod(method.declaration.methodName, method.type().cloneWithProxies) [
				
		genericTypes.forEach[tp|
			typeParameters += tp.cloneWithProxies
		]...
	]

	val genericTypesX = method.createJvmTypeParameter()
	members += method.toMethod(method.declaration.methodName+"X", method.type().cloneWithProxies) [
		genericTypesX.forEach[tp|
			typeParameters += tp.cloneWithProxies	
		]...
	]
Re: How to infer a method with generics? [message #1749075 is a reply to message #1749071] Thu, 01 December 2016 15:39 Go to previous messageGo to next message
Peter Luthardt is currently offline Peter LuthardtFriend
Messages: 35
Registered: February 2014
Member
I do not understand.
Creating the genericTypes twice does not solve the problem
	val genericTypes = method.createJvmTypeParameter()
	members += method.toMethod(method.declaration.methodName, method.type().cloneWithProxies) [
				
		genericTypes.forEach[tp|
			typeParameters += tp.cloneWithProxies
		]...
	]

	val genericTypesX = method.createJvmTypeParameter()
	members += method.toMethod(method.declaration.methodName+"X", method.type().cloneWithProxies) [
		genericTypesX.forEach[tp|
			typeParameters += tp.cloneWithProxies	
		]...
	]
Re: How to infer a method with generics? [message #1749148 is a reply to message #1749075] Fri, 02 December 2016 10:21 Go to previous messageGo to next message
Lorenzo Bettini is currently offline Lorenzo BettiniFriend
Messages: 1732
Registered: July 2009
Location: Firenze, Italy
Senior Member
You're not creating the generic types twice: you're cloning them
Re: How to infer a method with generics? [message #1749150 is a reply to message #1749148] Fri, 02 December 2016 10:48 Go to previous messageGo to next message
Peter Luthardt is currently offline Peter LuthardtFriend
Messages: 35
Registered: February 2014
Member
val genericTypesX = method.createJvmTypeParameter()

calls the method like suggested by Alex
    val tp = typesFactory.createJvmTypeParameter()
    tp.name = "T"

So for every generic parameter I call the code.
I my case this should create a new JvmTypeParameter instance for each JvmOperation.

Mybe this shows it better:
	val tp = typesFactory.createJvmTypeParameter()
	tp.name = "T"
	members += method.toMethod(method.declaration.methodName, method.type().cloneWithProxies) [
				
		typeParameters += tp.cloneWithProxies
		...
	]

	val tpX = typesFactory.createJvmTypeParameter()
	tpX.name = "T"
	members += method.toMethod(method.declaration.methodName+"X", method.type().cloneWithProxies) [
		typeParameters += tpX.cloneWithProxies
		...
	]

results in an error: Cannot make a static reference to the non-static type T
Re: How to infer a method with generics? [message #1749152 is a reply to message #1749150] Fri, 02 December 2016 11:14 Go to previous messageGo to next message
Alex Tugarev is currently offline Alex TugarevFriend
Messages: 14
Registered: July 2011
Junior Member
Why are you cloning the type parameters?

typeParameters += tp // .cloneWithProxies


Please inspect the working example from above.

After reading your first post once again, I'm not sure which signatures you are expecting to be created.

[Updated on: Fri, 02 December 2016 11:15]

Report message to a moderator

Re: How to infer a method with generics? [message #1749154 is a reply to message #1749152] Fri, 02 December 2016 11:51 Go to previous messageGo to next message
Peter Luthardt is currently offline Peter LuthardtFriend
Messages: 35
Registered: February 2014
Member
Thank you for your patience.
I have create a tiny dsl which shows the problem.
When you run the test case you get the error message.
Re: How to infer a method with generics? [message #1749156 is a reply to message #1749154] Fri, 02 December 2016 12:14 Go to previous messageGo to next message
Alex Tugarev is currently offline Alex TugarevFriend
Messages: 14
Registered: July 2011
Junior Member
Okay, I had a look at your test.

In addition to my last comment: please also consider to use a type reference to the actual type parameter as return type of the inferred operation. Cf. example from above. The relevant line is:
  members += operation.toMethod(operation.name, references.createTypeRef(typeParameterT)) [ ...
Re: How to infer a method with generics? [message #1749160 is a reply to message #1749156] Fri, 02 December 2016 13:12 Go to previous messageGo to next message
Peter Luthardt is currently offline Peter LuthardtFriend
Messages: 35
Registered: February 2014
Member
Thanks,

I have change to
	def dispatch void infer(Class element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
		acceptor.accept(element.toClass("my.class."+element.name))[
			element.methods.forEach[method|
				val tp = typesFactory.createJvmTypeParameter()
				tp.name = method.generic
				members += method.toMethod(method.name, references.createTypeRef(tp))[
					typeParameters += tp
				]
				val tpX = typesFactory.createJvmTypeParameter()
				tpX.name = method.generic
				members += method.toMethod(method.name+"X", references.createTypeRef(tpX))[
					typeParameters += tpX
				]
			]
		]
	}

but still the same: "Cannot make a static reference to the non-static type T"
Re: How to infer a method with generics? [message #1749312 is a reply to message #1749160] Mon, 05 December 2016 11:20 Go to previous message
Jan Koehnlein is currently offline Jan KoehnleinFriend
Messages: 737
Registered: July 2009
Location: Hamburg
Senior Member
In your grammar, you say

Method:
	'<' generic=ValidID '>' ...


as such you don't give Xbase a hint that this is a type parameter.

You have to write

Method:
	'<'generic=JvmTypeParameter'>' ...


instead. You can use this type parameter directly in the inferrer, i.e.

element.methods.forEach[method|
	members += method.toMethod(method.name, method.type)[
		typeParameters += method.generic
	]
	members += method.toMethod(method.name+"X", method.type)[
		typeParameters += method.generic
	]
]


---
Get professional support from the Xtext committers at www.typefox.io
Previous Topic:method generateFile undefined for the type MyDslGenerator
Next Topic:Variable/String Substitution Grammar with ${var} Style
Goto Forum:
  


Current Time: Sat Jun 24 01:57:31 GMT 2017

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

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