2016-05-02 19 views
4

DSLの拡張メソッドを制限する方法はありますか?Kotlin - 拡張メソッドのスコープを制限する

は、私はこのようなクラス構造を持っていると言う:

class Outer { 
    fun middle(op: Middle.() -> Unit): Middle { 
     val middle = Middle() 
     middle.op() 
     return middle 
    } 
} 

class Middle { 
    fun inner(op: Inner.() -> Unit): Inner { 
     val inner = Inner() 
     inner.op() 
     return inner 
    } 
} 

class Inner 

fun outer(op: Outer.() -> Unit): Outer { 
    val outer = Outer() 
    outer.op() 
    return outer 
} 

ので、同様に、私は、呼び出しを作成することができます。

outer { 
    middle { 
     inner { 
      middle { } // Here is the problem 
     } 
    } 
} 

私の問題は、それが追加としてマークされmiddle { }呼び出しは、混乱を招くということですMiddleからに変更すると、Innerに追加されているように見えます。

middle { }コールを許可しない方法はありますか。

+2

これは現時点では不可能ですが、https://youtrack.jetbrains.com/issue/KT-11551 –

答えて

8

あなたはdeprecatedと回避策を使用することができます。

class Outer { 
    fun middle(op: Middle.() -> Unit): Middle {...} 

    @Deprecated("can not be used inside a Outer block", level = DeprecationLevel.ERROR) 
    fun outer(op: Outer.() -> Unit): Outer = TODO() 
} 

class Middle { 
    fun inner(op: Inner.() -> Unit): Inner {...} 

    @Deprecated("can not be used inside a Middle block", level = DeprecationLevel.ERROR) 
    fun middle(op: Middle.() -> Unit): Middle = TODO() 
} 

class Inner { 
    @Deprecated("can not be used inside a Inner block", level = DeprecationLevel.ERROR) 
    fun inner(op: Inner.() -> Unit): Inner = TODO() 
} 

今、コンパイラはあなたにエラーを与えるだろう、とIDEは完了で間違っ機能示唆しています:

outer { 
    middle { 
     inner { 
      middle { } // error 
     } 
    } 
} 

をしかし、あなた大きなDSLに対しては本当にそれをしてはいけません。 @KirillRakhmanが提案するように、https://youtrack.jetbrains.com/issue/KT-11551を待つ方が良いです。

編集:私の例を修正した後は、はるかに小さくなりました。クラスのための1つのダミー関数では、あまりにも多くの定型文はありません。

+0

@KirillRakhmanによると1.1の予定です。編集を参照してください。今度はn個のクラスのために(n^2)/ 2ではなく、n個のダミー関数しかありません。そして 'level'パラメータのおかげでそれらの非推奨は警告ではなくエラーです。それで、KT-11551のようなそのユースケースの言語レベル機能のメリットはありません – voddan

関連する問題