1

在迁移到 Xtext 2.4.2 和 Eclipse Kepler 之后,我们的 DSL 的编辑器中出现了一个问题。之前一切正常(Xtext 2.3.x,Juno)。

当我们编辑初始化列表时,我们的 DSL 编辑器会抛出 ClassCastException: [1,2,3] Xtext 错误弹出窗口

重现步骤:

  1. 创建一个新的“Xtext 状态机示例”项目
  2. 用下面的语法编辑语法
  3. 删除包org.eclipse.xtext.example.fowlerdsl.generator(会在4.重新生成)
  4. 运行 org.eclipse.xtext.example.fowlerdsl.GenerateStatemachine.mwe2 工作流
  5. 运行eclipse应用程序
  6. 在一个空项目中创建一个新文件(example.statemachine)并复制以下内容

语法:

grammar org.eclipse.xtext.example.fowlerdsl.Statemachine
    with org.eclipse.xtext.common.Terminals
generate statemachine "http://www.eclipse.org/xtext/example/fowlerdsl/Statemachine"

Statemachine : {Statemachine}
    (vars += VarDeclWithOptionalInit)*
;
VarDeclWithOptionalInit returns Variable:
    VarDecl ('=' value=AstExpression)?
;
VarDecl returns Variable:
    'var' name = ID
;
AstExpression:
      ExpressionList
    | {AstExpression} INT
;
ExpressionList:
    '[' expressions+=AstExpression (',' expressions+=AstExpression)* ']'
;

example.statemachine 的内容

//Adding space between chars inside [] cause Exception
var example1 = [1, 2, 3]

//Doing the same in [10, 20] or [30, 40] is Ok, but modifying
//the top-level list cause the Exception
var example2 = [[10, 20], 0, [30, 40], 1, 2]

我认为示例文件的内容是正确的。但是,当我使用新值编辑列表时,或者当我在逗号或值周围添加空格时,编辑器会从 XtextReconcilierJob 中弹出一个带有 ClassCastException 的错误。

您认为我的语法有问题,还是 Xtext 方面的错误?

附加信息

我与这个斗争了几天,我收集了一些有趣的信息:

  • 在示例中,编辑器仅在编辑顶级列表中的元素时抛出,而不是内部列表中的元素(参见 example2 变量)
  • 在我的测试中,有时NullPointerException在调用堆栈中较早地抛出了 a 。
    • 我怀疑该方法PartialParsingHelper.reparse(IParser parser, IParseResult prev, ReplaceRegion cr)有奇怪的行为
    • 此方法在模型中找到当前修改元素的父元素,并使用新值对此调用 eSet()。但在我们的例子中,它尝试调用Statemachine.eSet()而不是Variable.eSet()
    • 来自ClassCastException一个相同的特征 id:
      • StateMachine.vars有一个特征 id == 0
      • Variable.value有一个特征 id == 0
      • 但是这2个特征的类型不同
    • 如果我在 中添加一些功能 BEFORE 值Variable,则抛出的异常(较早)是 a NullPointerException,因为只有 2 个功能(0 和 1)Variable.value时具有功能 id == 2 或 3StateMachine

错误的堆栈跟踪:

Thread [Worker-2] (Suspended (exception ClassCastException))
    StatemachineImpl.eSet(int, Object) line: 128
    StatemachineImpl(BasicEObjectImpl).eSet(EStructuralFeature, Object) line: 1071
    PartialParsingHelper.reparse(IParser, IParseResult, ReplaceRegion) line: 161
    StatemachineParser(AbstractAntlrParser).doReparse(IParseResult, ReplaceRegion) line: 136
    StatemachineParser(AbstractParser).reparse(IParseResult, ReplaceRegion) line: 48
    LazyLinkingResource(XtextResource).update(int, int, String) line: 220
    XtextDocumentReconcileStrategy.doReconcile(IRegion) line: 125
    XtextDocumentReconcileStrategy.reconcile(IRegion) line: 55
    XtextReconciler.doRun(XtextResource, IProgressMonitor) line: 329
    XtextReconciler.access$3(XtextReconciler, XtextResource, IProgressMonitor) line: 316
    XtextReconciler$1.process(XtextResource) line: 273
    XtextReconciler$1.process(Object) line: 1
    XtextReconciler$1(IUnitOfWork$Void<T>).exec(T) line: 36
    XtextDocument$XtextDocumentLocker(AbstractReadWriteAcces<P>).modify(IUnitOfWork<T,P>) line: 81
    XtextDocument$XtextDocumentLocker.modify(IUnitOfWork<T,XtextResource>) line: 201
    XtextDocument.internalModify(IUnitOfWork<T,XtextResource>) line: 98
    XtextReconciler.run(IProgressMonitor) line: 270
    Worker.run() line: 53
4

2 回答 2

1

xText bugzilla 中已经有一个错误修复。它是一个补丁org.eclipse.parser.impl.PartialParsingHelper。要解决此问题:

  1. 从补丁中获取文件。
  2. 将内容放在 xText 项目中的单独类中
  3. public Class bindIPartialParserHelper()通过在 RuntimeModule 中重写来注册此类(项目中的一个生成类,扩展 org.eclipse.xtext.service.DefaultRuntimeModule)

问题在于重新解析您的语言中已解析的部分:旧元素的父容器未正确设置。新元素与旧元素链接,而不是与旧元素的父元素链接。

我猜你自己已经想通了,但是这个说明可能会帮助下一个遇到同样问题的人。

于 2013-09-13T16:30:16.150 回答
0

Xtext 团队确认这是 2.4.x 版本的错误。有关错误修复的更多详细信息和通知,请参阅相关问题。

于 2013-09-13T08:15:14.163 回答