Skip to main content



      Home
Home » Modeling » TMF (Xtext) » use generated classes in DSL file, problem of missing type
use generated classes in DSL file, problem of missing type [message #1835810] Sun, 13 December 2020 20:55 Go to next message
Eclipse UserFriend
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 index.php/fa/39535/0/
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 199 times)
Re: use generated classes in DSL file, problem of missing type [message #1835838 is a reply to message #1835810] Mon, 14 December 2020 12:29 Go to previous message
Eclipse UserFriend
can you please provide a jvmmodelinferrer that actually compiles

cross post from https://stackoverflow.com/questions/65278762/xtext-use-generated-classes-in-dsl-file-problem-of-missing-type

[Updated on: Tue, 15 December 2020 13:00] by Moderator

Previous Topic:Programmatic serialization not using formatter preferences
Next Topic:Problems with JDK 14
Goto Forum:
  


Current Time: Sun Aug 24 02:27:14 EDT 2025

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

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

Back to the top