2014-10-07 58 views
1

我有一個DSL,看起來像這樣:Groovy的DSL越來越匿名字符串賦值

aMethod { 
    "a name" 
    "another name" 
    "and a third name" 
} 

我的問題是,我無法訪問這三個字符串,因爲調用關閉只返回最後一條語句。我試圖重寫字符串(的char []值)時,一個匿名的字符串聲明發生這就是所謂的構造函數:

def original 

// primitive way to get the String(char[])-constructor 
String.class.constructors.each { 
    if(it.toString() == "public java.lang.String(char[])") { 
     original = it 
    } 
} 
// overriding the constructor 
String.metaClass.constructor = { char[] value -> 
    def instance = original.newInstance(value) 
    // ... do some further stuff with the instance ... 
    println "Created ${instance}" 
    instance 
} 
// teststring to call String(char[] value) 
"teststring" 

不幸的是,沒有工作,我認爲不管怎麼說,這是相當複雜的。

+2

我懷疑這工作沒有一定的AST。你可以改變DSL嗎?將字符串作爲參數傳遞給方法調用可以解決這個問題,或者不把它們當作字符串,而是作爲純代碼:'aMethod {a name}' – Will 2014-10-07 18:04:35

+0

+1我認爲你需要一個ast – 2014-10-07 19:03:10

+0

我試過解決方案使用純代碼,但在閉包中,我還允許使用String-params進行方法調用,如下所示:aMethod {forView(other name)}。我認爲這種模式是不允許的,我不想混淆。沒關係,我認爲有一個明顯的解決方案,比如用方法包裝封閉的每一個語句 – user3060729 2014-10-07 20:58:31

回答

0

謝謝您的評論。事實上,將所有內容都定義爲不帶引號會很好。但是:在有了可以轉換爲java對象的dsl之後,我喜歡在開發時使用我的語言添加註釋。我想註釋重複的名字等等。 IDE的我更瞭解,Intellij和Eclipse將Strings「一個名字」作爲一個PSI-Elements處理。拆分這些元素可能會非常不方便......我想。我認爲像aMethod {a name}這樣的閉包語句會導致類似a方法{a.name}的解釋。這將意味着,而不是有一個StringLiteral Psi「一個名稱」,我會有一個Object-Psi和一個MethodCall-Psi或類似的東西。我不知道,我的下一個目標是「解析/創建」我的Java對象。你確定不可能重寫String-Constructor嗎?

被稱爲當你有此內容的Groovy腳本的任何構造函數:

"hello World"