2012-04-25 130 views
3

我试图让交叉引用在我的DSL中工作。下面是语法的一个精简版(标准例如DSL的修改版本):因为我没有使用标准的name = ID模式使用自定义终端规则的Xtext交叉引用

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals 

generate myDsl "http://www.xtext.org/example/mydsl/MyDsl" 

Releases: 
    releases+=Release* 
; 

terminal VERSION : ('0'..'9')+'.'('0'..'9')+('.'('0'..'9'|'x')+)?; 

Release: 
    'release' version = VERSION ('extends' parent = [Release|VERSION])? 
    ; 

,我也跟着this blog post有关如何创建自己的IQualifiedNameProvider

public class MyDslQNP extends DefaultDeclarativeQualifiedNameProvider { 
    QualifiedName qualifiedName(Release e) { 
     Package p = (Package) e.eContainer(); 
     return QualifiedName.create(p.getName(), e.getVersion()); 
    } 
} 

从上SO另一个答案,我得知我要实现自己的范围内提供:

public class MyDslScopeProvider extends AbstractDeclarativeScopeProvider { 
    IScope scope_Release_parent(Release release, EReference ref) { 
     Releases releases = (Releases) release.eContainer(); 
     return Scopes.scopeFor(releases.getReleases()); 
    } 
} 

我有一个LSO运行时模块中结合这些:

public class MyDslRuntimeModule extends 
     org.xtext.example.mydsl.AbstractMyDslRuntimeModule { 
    @Override 
    public Class<? extends IQualifiedNameProvider> bindIQualifiedNameProvider() { 
     return MyDslQNP.class; 
    } 

    @Override 
    public Class<? extends IScopeProvider> bindIScopeProvider() { 
     return MyDslScopeProvider.class; 
    } 

} 

运行时所产生的编辑器创建一个文件,该文件是这样的:

release 1.2.3 
release 1.2.2 extends 1.2.3 

的问题是,(1)编辑器不会自动完成(2)编辑器显示错误消息Couldn't resolve reference to Release '1.2.3'

我错过了什么?

回答

1

Scopes.scopeFor是一个静态方法,因此不使用配置的IQualifiedNameProvider。 你需要将它传递明确使用 Scopes.scopeFor(可迭代,函数的iScope)

但在你的情况,你不需要在范围内提供特殊处理可言,因为本地元素具有限定名称提供者正在被自动放在范围内。

+0

好了,所以去除范围提供商使得自动完成的工作,但它仍然未能解决的参考。 – JesperE 2012-04-26 07:52:25

2

您的QualifiedNameProvider似乎创建了伪造的限定名称,例如1.2.2版本的名称将包含两个[release] [1.2.2]段落,其中查找将搜索[release] [1] [2] [2]。

请尽量像这样建立一个适当的限定名称:

QualifiedName qualifiedName(Release e) { 
    Package p = (Package) e.eContainer(); 
    QualifiedName release = getConverter().toQualifiedName(e.getVersion()); 
    return QualifiedName.create(pack.getName()).append(releaseSuffix);   
}