How to reference available methods of a JvmTypeReference (Xbase) [message #1723598] |
Tue, 16 February 2016 12:28  |
Eclipse User |
|
|
|
How do you write a grammar (plus, presumably, a bit of custom scoping) which can reference first a JvmTypeReference (that's easy and works) and then any of the methods available on (only) that type?
I've attempted this in https://github.com/vorburger/xtext-sandbox/blob/master/JvmType/ch.vorburger.xtext.sandbox.learnjvmtype/src/ch/vorburger/xtext/sandbox/LearnJvmType.xtext like this:
ServiceCall:
'call' type=JvmTypeReference method=XFeatureCall;
but I'm clearly completely not getting it yet.. as above allows e.g. 'call java.lang.String startsWith("pre")' but I don't think that 'startsWith()' is really recognized as a method of String yet - it allows just about anything there (and does not offer auto completion for it).
How do you do this right? Do I really want method=XFeatureCall, or another Xtype there? What does the scope provider to "propose the methods of the type=JvmTypeReference" in the method=XFeatureCall look like, roughly?
PS: I'm also not as clear as I'd like to be between a) type=JvmTypeReference (which seems to work) vs. b) type=[jvmTypes::JvmType|QualifiedName] - if all you want is to be able to refer to a Java class, then b) is probably more suitable in this case?
PPS: The ultimate goal is to then write an JvmModelInferrer which would turn this into something like a 'class Test { @Inject 'type class here' 'lower class type here'; void example() { 'lower class type here'.'method here' }
|
|
|
Re: How to reference available methods of a JvmTypeReference (Xbase) [message #1723623 is a reply to message #1723598] |
Tue, 16 February 2016 15:45   |
Eclipse User |
|
|
|
hi,
did you consider a straight forward inferrer?
Model:
calls+=ServiceCall*;
ServiceCall:
'call' type=JvmTypeReference method=XRestrictedFeatureCall;
XRestrictedFeatureCall returns xbase::XExpression:
{xbase::XFeatureCall}
('<' typeArguments+=JvmArgumentTypeReference (',' typeArguments+=JvmArgumentTypeReference)* '>')?
feature=[types::JvmIdentifiableElement|IdOrSuper]
(=>explicitOperationCall?='('
(
featureCallArguments+=XShortClosure
| featureCallArguments+=XExpression (',' featureCallArguments+=XExpression)*
)?
')');
def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(element.toClass("demo.Demo")) [
var i = 0;
for (call : element.calls) {
i = i + 1
members += call.toField("field"+i, call.type.cloneWithProxies) [
annotations += Inject.annotationRef()
]
val m1 = call.toMethod("executeIntern"+i, inferredType) [
visibility = JvmVisibility.PRIVATE
parameters+=call.toParameter("it", call.type.cloneWithProxies) => [
]
body = call.method
]
members += m1
val ifinal = i
members += call.toMethod("execute"+i, call.method.inferredType) [
body = '''
«IF m1.returnType.qualifiedName != Void.TYPE.typeRef.qualifiedName»return «ENDIF»executeIntern«ifinal»(field«ifinal»);'''
]
}
]
}
(very very naive impl)
you may do some customization to remove stuff like this from the scope
|
|
|
|
Powered by
FUDForum. Page generated in 0.03496 seconds