2016-11-24 33 views
1

我想將XText中另一個文件中的一些對象添加到範圍中。爲了說明我需要什麼,我有這個玩具語法:XText中的簡單導入指令

grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals 
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl" 

Model: 
    (imports += Import)* 
    (classes += ClassDef)*; 

Import: 
    'import' filename += STRING;  

ClassDef: 
    'class' name=ID ('extends' extends=[ClassDef])?; 

可以說,我希望能夠擴展僅是一個給定的類之前定義的類,並且只有那些具有相同的第一個字母爲啓動該類正在被定義。

推薦的方法是通過scoping。這裏是做一個單一文件內的範圍提供:

package org.xtext.example.mydsl.scoping 
import .... 

class MyDslScopeProvider extends AbstractMyDslScopeProvider { 
    override getScope(EObject context, EReference reference){ 
     if(reference == MyDslPackage.Literals.CLASS_DEF__EXTENDS){ 
      if(! (context instanceof ClassDef)) {return IScope.NULLSCOPE } 
      val root = (context as ClassDef).getRootContainer 
      val classes = root.getAllContentsOfType(ClassDef) 
      val before = classes.subList(0, classes.indexOf(context)) 
      val fstLetter = (context as ClassDef).name.charAt(0) 
      val haveSame1stLetter = before.filter[name.charAt(0) == fstLetter]   
      return Scopes::scopeFor(haveSame1stLetter) 
     } 
    } 
} 

我希望能夠從導入的文件訪問類的聲明是這樣的:

// --- c --- 
class Xlib 
class Xextend extends Xlib 

// --- main.mydsl --- 
import "lib.mydsl" 
class A 
class Xmain extends Xlib 

,我發現了一些相互矛盾的建議關於使用importURI的事情,但它似乎並沒有爲我工作,似乎是過時的做事方式。

說明文檔中提到的跨資源引用我可能需要:

  • 創建IGlobalScopeProvider一個實例,一個QualifiedName和它的字符串表示之間
  • 出口元素IResourceDescription
  • 轉換的一部分
  • 執行並綁定我自己IDefaultResourceDescriptionStrategy
  • 獲得​​IContainer.Manager
  • 得到IResourceDescriptions從​​

...還有更多其他的東西(注意是複數形式)。不幸的是,他們沒有把我所要做的事情添加到一個連貫的圖景中,以實現預期的行爲。


編輯:繼斯文的建議,我已經想出瞭解決方案。如果有人有興趣 - 我已經在this gist上發佈了代碼。

回答

1

有體面的默認實現你提到的所有的服務,這樣你就不會需要實現它們,除非你想改變他們的工作方式。

確實不鼓勵使用importUri機制,而應該使用基於名稱的鏈接,這更可靠。

Xtext自動維護一個包含全局可見限定名稱的索引。有索引的兩面:

1.特約指數

在索引ResourceDescriptionManager被要求命名的元素。默認實現將貢獻具有屬性名稱的所有元素。如果你想改變這種行爲,你可以繼承DefaultResourceDescriptionStrategy並覆蓋createEObjectDesciptions。舉例來說,你可以導出使用資源的簡單名稱模型的根元素,以便讓

Import : 
    'import' referencedModel+=[Model|STRING] 
; 

這將只允許導入文件,如果你想支持從不同的文件夾導入文件,我建議使用命名空間。

namespace foo; 
type Bar {} 

其他文件

import foo.Bar 
type Foo extends Bar 

2.自動使用索引

範圍提供商委託給GlobalScopeProvider這將提供從索引的描述。因此,如果確保元素索引正確(請參閱1.),它們將自動結束到範圍提供程序中。

0

嗨,我不能真的跟着你。您可以簡單地使用導入Uri,儘管它不鼓勵https://www.eclipse.org/forums/index.php?t=msg&th=1078818&goto=1736351&#msg_1736351,或者您可以通過調整名稱提供程序(給元素名稱.elementname)和導入的名稱空間範圍的localscopeprovider來使用基於命名空間的範圍設置(不知道是否要支持相對導入或花哨的Uri方案) (轉進口的xxx爲導入XXX。*)

能否請您給您的要求,更多的提示

+0

嗨,我試圖給出一個我想要實現的例子 – Kostya

+0

你有多個文件夾/包/項目和相對/絕對導入或只是當前文件旁邊的文件 –

+0

當前所有文件都是相同的夾。但我希望將文件夾作爲未來的可能性。 – Kostya