use generated classes in DSL file, problem of missing type [message #1835810] |
Mon, 14 December 2020 01:55  |
Alexander Gornostaev Messages: 2 Registered: December 2020 |
Junior Member |
|
|
Shortly, the problem is that when I'm writing my dsl file (with grammars inherited from xbase), I may need to use some classes, that are surely to be generated after the validation but that are not available during writing the file.
The question is, how do i configure Xtext and Xbase in order to use in my DSL file (the one with DSL extension, ".myx") classes that are not yet generated by JvmModelInferrer?
Here is the language grammar:
grammar org.xtext.example.mydsl.MyX with org.eclipse.xtext.xbase.Xbase
Model:
expressions+=CommonExpression*;
CommonExpression:
Anime | AnimeResource
;
AnimeResource:
'AnimeRes' name=ID '{'
(args+=FullJvmFormalParameter)*
'}'
;
Anime:
'watch' name=ID body=XBlockExpression
;
Here is what i want to achive (test.myx):
AnimeRes Resource {
}
watch Watcher {
val someStub = Resource.create()
}
So the dsl file looks like there is a static method defined for Resource class. But in reality, there must be additional parameters that should be passed to Resource, they are purely boilerplate in my case, that's why I don't want to pass them into "create" each time. How I want the generated file look like to achieve that:
package test;
public class Model {
private int id= 0;
public static class Resource {
private int id;
public Resource(final int id) {
this.id = id;
}
}
public class ResourceCreator {
public Resource create() {
return new Resource(id /* the creator is inner non-static class */));
}
}
public ResourceCreator Resource = new ResourceCreator();
}
That way I'm kind of cheating. I have a variable that has the name of the class, and in the client code it looks like they use static method when they are really just using a builder that is named like the class. Here is the JvmModelInferrer to make similarly looking file:
class MyXJvmModelInferrer extends AbstractModelInferrer {
def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(element.toClass(QualifiedName.create("test", "Model"))) [
for (expression : element.expressions) {
switch (expression ) {
AnimeResource: {
members += expression.toClass(expression.name) [
static = true
visibility = JvmVisibility.PUBLIC
val _members = members
expression.args.forEach [
_members += expression.toField(name, parameterType) [
static = false
visibility = JvmVisibility.PUBLIC
]
]
members += expression.toField("id", typeRef(int))
members += expression.toConstructor [
val _parameters = parameters
expression.args.forEach [
_parameters += it.toParameter(name, parameterType)
]
_parameters += expression.toParameter("id", typeRef(int))
body = '''
«FOR param : parameters»this.«param.name» = «param.name»;
«ENDFOR»
'''
]
]
members += element.toClass(expression.name + "Creator") [
static = false
visibility = JvmVisibility.PUBLIC
members += element.toMethod("create", typeRef(expression.name)) [
val parameters = parameters
parameters.args.forEach [
parameters += it.toParameter(name, parameterType)
]
body = '''
return new «expression.name»(
«FOR param : parameters»
«IF parameters.indexOf(param) < parameters.size - 1»,
«ENDIF»
«ENDFOR»id);
'''
]
]
members += expression.toField(expression.name, typeRef(expression.name + "Creator")) [
visibility = JvmVisibility.PUBLIC
initializer = '''
new «expression.name + "Context"»();
'''
]
}
}
}
]
}
}
The problem that I've faced with this approach is shown in the attached screenshot 
So it seems that some linking fails but I can not understand what I should do to fix that and what bindings I should override and how.
Any help would be appreciated.
Attachment: OZjXW.png
(Size: 31.38KB, Downloaded 83 times)
|
|
|
|
Powered by
FUDForum. Page generated in 0.02016 seconds