在迁移到 Xtext 2.4.2 和 Eclipse Kepler 之后,我们的 DSL 的编辑器中出现了一个问题。之前一切正常(Xtext 2.3.x,Juno)。
当我们编辑初始化列表时,我们的 DSL 编辑器会抛出 ClassCastException:
[1,2,3]
重现步骤:
- 创建一个新的“Xtext 状态机示例”项目
- 用下面的语法编辑语法
- 删除包org.eclipse.xtext.example.fowlerdsl.generator(会在4.重新生成)
- 运行 org.eclipse.xtext.example.fowlerdsl.GenerateStatemachine.mwe2 工作流
- 运行eclipse应用程序
- 在一个空项目中创建一个新文件(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 == 0Variable.value
有一个特征 id == 0- 但是这2个特征的类型不同
- 如果我在 中添加一些功能 BEFORE 值
Variable
,则抛出的异常(较早)是 aNullPointerException
,因为只有 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