如何在Xtext中获取输入文件名称 实现文件名与类名一致校验
Xtext实现文件名与类名一致性校验的方案
在校验器中直接获取源文件名
Xtext的声明式校验器本身就支持直接读取当前源文件的名称,不需要额外扩展其他组件,实现逻辑如下:
你自定义的校验器默认继承AbstractDeclarativeValidator,在针对类的校验方法中,通过类实例的eResource()方法获取当前关联的资源对象,再从资源的URI中解析文件名即可,参考代码:
import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.xtext.validation.AbstractDeclarativeValidator; import org.eclipse.xtext.validation.Check; import static com.google.common.base.Objects.equal; // 此处替换为你自己的类包和类定义 @Check public void checkClassNameConsistency(YourTopLevelClass cls) { Resource resource = cls.eResource(); if (resource == null) return; URI uri = resource.getURI(); // 提取不带后缀的纯文件名 String fileNameWithoutExt = uri.trimFileExtension().lastSegment(); String declaredClassName = cls.getName(); if (!equal(fileNameWithoutExt, declaredClassName)) { error("类名必须与源文件名保持一致", YourModelPackage.Literals.YOUR_TOP_LEVEL_CLASS__NAME); } }
以上逻辑在Eclipse插件环境、独立命令行环境均可以正常运行,URI解析逻辑不需要额外适配:
- Eclipse插件环境下URI为
platform:/resource/开头的工作区路径,lastSegment()直接返回带后缀的文件名 - 独立运行环境下URI为
file:/开头的本地文件路径,解析逻辑完全一致
替代方案(特殊场景使用)
如果遇到增量构建、资源延迟加载等极端场景,在校验器中无法正常获取资源对象,可以用以下两种方案实现同样的校验逻辑:
- 自定义
IDerivedStateComputer扩展点,在模型派生状态计算阶段执行校验,该阶段是模型解析完成后最早触发的流程之一,资源对象必然已经绑定,不会出现空指针问题 - 扩展
IResourceServiceProvider的校验逻辑,在资源级别的校验入口统一检查文件内的顶级类名与文件名的匹配关系,适合多文件批量校验的场景
注意事项
- 如果你的语言支持单文件定义多个顶级类,可自行调整逻辑,比如仅要求公共类与文件名一致,其余内部类不做限制
- 跨平台运行时注意文件名大小写匹配问题,Windows系统默认文件名大小写不敏感,可根据你的语言规范选择是否做严格大小写校验
内容的提问来源于stack exchange,提问作者R4de
相关产品推荐
相关产品推荐

