Xtext中的交叉引用非常慢.我如何改进它



这是在论坛中提到的问题继续进行的:Xtext-could无法解决引用。

我正在使用的样本模型如下

grammar org.xtext.example.testdsl.TestDsl with org.eclipse.xtext.common.Terminals
generate testDsl "http://www.test.com/test/example/TestDsl"
Model:
prog+=Program*;
Program: g=Greeting  de+=DataEntry* s+=Statement*;
Greeting: 'Hello' t=ProgPara '!';
ProgPara: 'PROGRAM'  pname=Progname ';';
Progname : name=ID;
DataEntry:  a=INT (v=Varname| in=Indexname) ';';   
Varname : name = ID;
Statement: c=CopyStmt ';';
CopyStmt: 'COPY' 'TO' qname=[IndexVarname|ID] ;
IndexVarname : (Indexname|Varname);   
Indexname : '(' name = ID ')';
Named:Progname|Indexname|Varname;

我有一个使用类似语法的文件,并且该文件非常大,大约有12000行代码和2000个奇数progname或varname,在每个实例中,它都在尝试解决范围提供商中的类型。语法中有大约326个元素。

 val candidates1 = EcoreUtil2.getAllContentsOfType(rootElement, Indexname);
 val candidates2 = EcoreUtil2.getAllContentsOfType(rootElement, Varname);
 val candidates = candidates1 + candidates2;
 return Scopes.scopeFor(candidates);

由于反复调用 getScope((,该文件正在始终在编辑器中打开。即使打开任何小编辑的速度太慢。请建议我如何解决此问题。

我尝试添加以下代码的缓存支持:

class TestDslScopeProvider extends AbstractTestDslScopeProvider {
  @Inject
    IResourceScopeCache cache;
  override getScope(EObject context, EReference reference) {
    if (context instanceof CopyStmt) {
        if (reference.featureID == TestDslPackage.COPY_STMT__QNAME) {
            val candidates = cache.get(
                context,
                reference.eResource,
                [|findQNameCandidates(context, reference)]
            );
            return Scopes.scopeFor(candidates);
        }   
      }
      return super.getScope(context, reference);        
  }
  def findQNameCandidates(EObject context, EReference reference) {
    val rootElement = EcoreUtil2.getRootContainer(context);
    val candidates1 = EcoreUtil2.getAllContentsOfType(rootElement, Indexname);
    val candidates2 = EcoreUtil2.getAllContentsOfType(rootElement, Varname);
    return candidates1 + candidates2;
  }
}

即使到现在,它仍然非常慢。没有区别。如果我将上下文用参考对象替换为缓存的键,那么速度很快,但是所有交叉引用的链接都会丢失,我会遇到错误。我无法指出我在哪里做正确的事。

谢谢,
Anitha

以下对我有效

@Inject
IResourceScopeCache cache;
override getScope(EObject context, EReference reference) {
    if (context instanceof CopyStmt) {
        if (reference.featureID == MyDslPackage.COPY_STMT__QNAME) {
            val candidates = cache.get(
                "COPY_STMT__QNAME_scope",
                context.eResource,
                [|findQNameCandidates(context, reference)]
            );
            return Scopes.scopeFor(candidates);
        }
    }
    return super.getScope(context, reference);
}
def findQNameCandidates(EObject context, EReference reference) {
    val rootElement = EcoreUtil2.getRootContainer(context);
    val candidates1 = EcoreUtil2.getAllContentsOfType(rootElement, IndexVarname);
    return candidates1;
}

最新更新