You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Xtext的doGenerate方法?求核心方法实现示例

实现Xtext的doGenerate方法来打印编辑器语句的示例

我明白你现在的困惑——看着自动生成的Xtend代码不知道怎么下手,其实核心就是遍历你的模型元素,把各个部分的文本拼接起来输出。下面给你3个逐步进阶的doGenerate实现示例,帮你搞清楚怎么操作。

首先先回顾下你的Xtext语法:每个UseStory包含Title、Role、Target、Use四个部分,我们要做的就是把这些部分的文本提取出来,组合成完整的语句。


示例1:基础版——直接拼接所有UseStory语句

这个版本最直白,直接遍历所有UseStory,把每个部分的内容拼接成完整的句子,输出到文件里:

class HellodslGenerator extends AbstractGenerator {
    String code = ""

    override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
        // 重置拼接字符串
        code = ""
        // 获取模型根元素Model
        val model = resource.allContents.filter(Model).head
        // 遍历每个UseStory并处理
        model.usestory.forEach[funktion]
        // 生成输出文件
        fsa.generateFile("test.txt", code)
    }

    // 拼接字符串的工具方法
    def conc(String str) {
        code += str
    }

    // 处理单个UseStory,拼接成完整语句
    def funktion(UseStory story) {
        // 把Title、Role、Target、Use的内容按语法顺序拼接
        conc(story.title.titlen + " " + story.title.titlev.value + ": ")
        conc("Als " + story.role.role + " ")
        conc("möchte ich " + story.target.targetn + " " + story.target.targetv.value + ", ")
        conc("um " + story.use.usen + " zu " + story.use.usev.value + ".\n\n")
    }
}

解释:

  • resource.allContents.filter(Model).head:从资源中获取你的根模型对象Model
  • model.usestory.forEach[funktion]:遍历每个UseStory,调用funktion方法处理
  • 每个funktion(UseStory)方法里,我们直接取出每个属性的文本(比如story.title.titlen是标题里的名词,story.title.titlev.value是标题里的动词),按照你的Xtext语法的格式拼接成完整句子,最后加换行让每个用例分开。

示例2:结构化版——拆分各部分处理

如果后续需要扩展(比如给不同部分加格式),可以把每个组件的处理拆成单独方法,代码更易维护:

class HellodslGenerator extends AbstractGenerator {
    String code = ""

    override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
        code = ""
        val model = resource.allContents.filter(Model).head
        model.usestory.forEach[
            conc(processTitle(it))
            conc(processRole(it))
            conc(processTarget(it))
            conc(processUse(it))
            conc("\n\n")
        ]
        fsa.generateFile("test.txt", code)
    }

    def conc(String str) {
        code += str
    }

    // 单独处理Title部分
    def processTitle(UseStory story) {
        return story.title.titlen + " " + story.title.titlev.value + ": "
    }

    // 单独处理Role部分
    def processRole(UseStory story) {
        return "Als " + story.role.role + " "
    }

    // 单独处理Target部分
    def processTarget(UseStory story) {
        return "möchte ich " + story.target.targetn + " " + story.target.targetv.value + ", "
    }

    // 单独处理Use部分
    def processUse(UseStory story) {
        return "um " + story.use.usen + " zu " + story.use.usev.value + "."
    }
}

解释:

  • 把每个部分的文本生成逻辑拆成单独方法,比如processTitle、processRole,这样如果以后要给标题加特殊格式、或者给角色加前缀,直接修改对应方法就行,不用动主逻辑。
  • 主方法里只需要按顺序调用这些方法,代码结构更清晰,可读性更强。

示例3:增强版——带编号和格式化输出

如果想让输出更易读,比如给每个用例加编号,或者调整格式区分不同部分,可以这样写:

class HellodslGenerator extends AbstractGenerator {
    String code = ""

    override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
        code = "=== 所有用户用例 ===\n\n"
        val model = resource.allContents.filter(Model).head
        // 遍历的时候带索引,生成编号
        model.usestory.forEachIndexed[story, index |
            conc("用例" + (index + 1) + ": ")
            conc(story.title.titlen + " " + story.title.titlev.value + "\n")
            conc("  角色: Als " + story.role.role + "\n")
            conc("  目标: möchte ich " + story.target.targetn + " " + story.target.targetv.value + "\n")
            conc("  用途: um " + story.use.usen + " zu " + story.use.usev.value + "\n\n")
        ]
        fsa.generateFile("test.txt", code)
    }

    def conc(String str) {
        code += str
    }
}

解释:

  • 使用forEachIndexed遍历,获取每个用例的索引,生成直观的编号(比如“用例1:”、“用例2:”)
  • 给每个部分加缩进和标签(比如“角色:”、“目标:”),让输出的文本结构层次分明,方便阅读。

这三个示例从基础到进阶,你可以根据自己的需求选择。核心思路就是从模型中提取各个元素的属性值,然后按照你想要的格式拼接成字符串,最后输出到文件。

内容的提问来源于stack exchange,提问作者Detlef7able

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:17:53