Kotlin 進(jìn)階之路10 領(lǐng)域特定語言 DSL

Kotlin 進(jìn)階之路 目錄

DSL 的概念

  • 只在特定領(lǐng)域使用的語言
  • 例如:
- HTML、Gradle、SQL等等

DSL的特點(diǎn)

  • 計(jì)算機(jī)編程語言
  • 具有語言的表達(dá)能力
  • 有限的表達(dá)能力
  • 關(guān)注某個(gè)特定領(lǐng)域

HTML Kotlin

import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

class MapDelegate(val map: MutableMap<String, String>) : ReadWriteProperty<Any, String> {
    override fun getValue(thisRef: Any, property: KProperty<*>): String {
        return map[property.name] ?: ""
    }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: String) {
        map[property.name] = value
    }
}
 interface Node {
    fun render(): String
}
fun html(block: Tag.() -> Unit): Tag {
    return Tag("html").apply(block)
}

fun Tag.head(block: Head.() -> Unit) {
    this + Head().apply(block)
}

fun Tag.body(block: Body.() -> Unit) {
    this + Body().apply(block)
}

class StringNode(val content: String) : Node {
    override fun render() = content
}

class Head : Tag("head")

class Body : Tag("body") {
    var id by MapDelegate(proerties)

    var `class` by MapDelegate(proerties)
}
open class Tag(val name: String) : Node {

    val children = ArrayList<Node>()

    val proerties = HashMap<String, String>()

    operator fun String.invoke(value: String) {
        proerties[this] =value
    }

    operator fun String.invoke(block:Tag.()->Unit){
        children.add(Tag(this).apply(block))
    }

    operator fun String.unaryPlus(){
        children.add(StringNode(this))
    }

    operator fun plus(node: Node){
        children.add(node)
    }



    // <html id ="htmlId' style=''><head></head><body></body></html>
    override fun render(): String {
        return StringBuffer()
                .append("<")
                .append(name)
                .let { stringBuffer ->
                    if (!this.proerties.isEmpty()) {
                        stringBuffer.append(" ")
                        this.proerties.forEach {
                            stringBuffer.append(it.key)
                                    .append("=\"")
                                    .append(it.value)
                                    .append("\" ")
                        }
                    }
                    stringBuffer
                }
                .append(">")
                .let { stringBuffer ->
                    children.map(Node::render).map(stringBuffer::append)
                    stringBuffer
                }
                .append("</$name>")
                .toString()
    }
}

fun main(args: Array<String>) {
//    Tag("html").apply {
//    proerties["id"] = "HtmlId"
//    children.add(Tag("head"))
//}.render().let ( ::println )

//    html {
//        proerties["id"] = "HtmlId"
//        children.add(Tag("head"))
//
//    }.render().let(::println)

    html {
        "id"("HtmlId") //執(zhí)行 Tag中的invoke方法
        "head"{
            "id"("headId")
        }
        body {
            id = "bodyId"
            `class` = "bodyClass"
            "a"{
                "href"("https://www.kotliner.cn")
                +"Kotlin 中文博客"
            }
        }
        "div"{
        }
    }.render().let(::println)
}

運(yùn)行結(jié)果

<html id="HtmlId" ><head id="headId" ></head><body id="bodyId" class="bodyClass" ><a  >Kotlin 中文博客</a></body><div></div></html>

Gradle Kotlin 腳本

group = "cn.kotliner.kotlin"
version = "1.0-SNAPSHOT"

buildscript {
    extra["kotlin_version"] = "1.1.2"

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${extra["kotlin_version"]}")
    }
}

apply {
    plugin("java")
    plugin("kotlin")
}

configure<JavaPluginConvention>{
    setSourceCompatibility(1.5)
}

repositories {
    mavenCentral()
}

dependencies {
    compile("org.jetbrains.kotlin:kotlin-stdlib-jre8:${extra["kotlin_version"]}")
    testCompile("junit", "junit", "4.12")
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容