|
Re: How to infer a method with generics? [message #1749049 is a reply to message #1749037] |
Thu, 01 December 2016 12:52   |
Alex Tugarev 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 #1771289 is a reply to message #1749312] |
Wed, 23 August 2017 17:15  |
Peter Luthardt Messages: 43 Registered: February 2014 |
Member |
|
|
Sorry but I have to reopen this thread.
I have learned a lot and created a tiny dsl
grammar lutte.typedmethodParameter.LUTTE1 with org.eclipse.xtext.xbase.annotations.XbaseWithAnnotations
generate lUTTE1 "http://www.typedmethodParameter.lutte/LUTTE1"
Model:
'BusinessClass' name = ValidID
operations += Operation*
;
Operation:
typedParameters += TypedParameter* 'op' operationType = JvmTypeReference name = ValidID '(' parameters+=JvmFormalParameter(','parameters+=JvmFormalParameter)*')'
body = XBlockExpression
;
TypedParameter:
'<'typedParameter = JvmTypeParameter'>'
;
with Inferer
/*
* generated by Xtext 2.12.0
*/
package lutte.typedmethodParameter.jvmmodel
import com.google.inject.Inject
import lutte.typedmethodParameter.lUTTE1.Model
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
class LUTTE1JvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(element.toClass("test."+element.name))[
element.operations.forEach[op|
members += op.toMethod(op.name, op.operationType.cloneWithProxies)[
op.typedParameters.forEach[parameter|
typeParameters += parameter.typedParameter
]
op.parameters.forEach[parameter|
parameters += parameter.cloneWithProxies
]
body = op.body
]
members += op.toMethod(op.name+"2", op.operationType.cloneWithProxies)[
op.typedParameters.forEach[parameter|
typeParameters += parameter.typedParameter
]
op.parameters.forEach[parameter|
parameters += parameter.cloneWithProxies
]
]
]
]
}
}
a test case
/*
* generated by Xtext 2.12.0
*/
package lutte.typedmethodParameter.tests
import com.google.inject.Inject
import com.google.inject.Provider
import java.util.ArrayList
import lutte.typedmethodParameter.lUTTE1.Model
import org.eclipse.xtext.generator.InMemoryFileSystemAccess
import org.eclipse.xtext.resource.XtextResourceSet
import org.eclipse.xtext.testing.InjectWith
import org.eclipse.xtext.testing.XtextRunner
import org.eclipse.xtext.testing.util.ParseHelper
import org.eclipse.xtext.xbase.compiler.JvmModelGenerator
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.eclipse.emf.common.util.URI
@RunWith(XtextRunner)
@InjectWith(LUTTE1InjectorProvider)
class LUTTE1ParsingTest {
@Inject
ParseHelper<Model> parseHelper
@Inject private Provider<XtextResourceSet> resourceSetProvider;
@Inject private JvmModelGenerator generator;
@Test
def void loadModel() {
val resourceSet = resourceSetProvider.get
resourceSet.classpathURIContext = this
val result = parseHelper.parse('''
BusinessClass Test
<T> op T test(T t)
{
t
}
''', URI.createURI("test/Test.lutte1"), resourceSet)
Assert.assertNotNull(result)
Assert.assertTrue(result.eResource.errors.isEmpty)
val fsa = new InMemoryFileSystemAccess()
val resources = new ArrayList(resourceSet.resources)
resources.forEach[resource|
generator.doGenerate(resource, fsa)
]
fsa.allFiles.entrySet.forEach[entry|
println(entry.key)
]
val file = fsa.textFiles.get("DEFAULT_OUTPUTtest/Test.java").toString;
Assert.assertEquals('''package test;
@SuppressWarnings("all")
public class Test {
public <T> T test(final T t) {
return t;
}
public <T> test2(final T t);
}
'''.toString.remove('\r'), file)
}
def String remove (String from, String value)
{
return from.replaceAll("("+value+")", "");
}
}
with the result
org.junit.ComparisonFailure: expected:<... t;
}
public [<T> test2(final T] t);
}
> but was:<... t;
}
public [? test2(final ?] t);
}
>
at org.junit.Assert.assertEquals(Assert.java:115)
at org.junit.Assert.assertEquals(Assert.java:144)
at lutte.typedmethodParameter.tests.LUTTE1ParsingTest.loadModel(LUTTE1ParsingTest.java:98)
...
What is it I am missing?
I used xtext 2.12.0 .
|
|
|
Powered by
FUDForum. Page generated in 0.01777 seconds