1. 程式人生 > >(四)Kotlin 領域特定語言 DSL

(四)Kotlin 領域特定語言 DSL

文章目錄

一、領域特定語言 DSL的概念

  • 只在特定領域使用的語言;例如:HTML、Gradle、SQL

二、領域特定語言 DSL的特點

  • 它也是計算機程式語言
  • 具有語言表達能力
  • 表達能力比較有限
  • 關注某個特定領域

三、Html DSL

四、Gradle DSL

以下內容引用自 : Kotlin 語言中文站

使用 Gradle

為了用 Gradle 構建 Kotlin,你應該設定好 kotlin-gradle 外掛將其應用到你的專案中,並且新增 kotlin-stdlib 依賴。這些操作也可以在 IntelliJ IDEA 中通過呼叫 Project action 中的 Tools | Kotlin | Configure Kotlin 自動執行。

外掛和版本

使用 kotlin-gradle-plugin 編譯 Kotlin 原始碼和模組.

要使用的 Kotlin 版本通常定義為 kotlin_version 屬性:

buildscript {
    ext.kotlin_version = '1.3.11'

    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

當通過 Gradle 外掛 DSLGradle Kotlin DSL 使用 Kotlin Gradle 外掛 1.1.1 及以上版本時,這不是必需的。

針對 JVM

針對 JVM,需要應用 Kotlin 外掛:

apply plugin: "kotlin"

或者,從 Kotlin 1.1.1 起,可以使用 Gradle 外掛 DSL 來應用該外掛:

plugins {
    id "org.jetbrains.kotlin.jvm" version "1.3.11"
}

在這個塊中的 version 必須是字面值,並且不能從其他構建指令碼中應用。
對於 Gradle Kotlin DSL,請按以下方式應用外掛:

plugins {
    kotlin("jvm") version "1.3.11"
}

Kotlin 原始碼可以與同一個資料夾或不同資料夾中的 Java 原始碼混用。預設約定是使用不同的資料夾:

project
    - src
        - main (root)
            - kotlin
            - java

如果不使用預設約定,那麼應該更新相應的 sourceSets 屬性:

sourceSets {
    main.kotlin.srcDirs += 'src/main/myKotlin'
    main.java.srcDirs += 'src/main/myJava'
}

對於 Gradle Kotlin DSL,請改用 java.sourceSets { …… } 配置源集。

針對 JavaScript

當針對 JavaScript 時,須應用不同的外掛:

apply plugin: "kotlin2js"

這個外掛只適用於 Kotlin 檔案,因此建議將 Kotlin 和 Java 檔案分開(如果是同一專案包含 Java 檔案的情況)。與針對 JVM 一樣,如果不使用預設約定,我們需要使用 sourceSets 來指定原始碼資料夾:

sourceSets {
    main.kotlin.srcDirs += 'src/main/myKotlin'
}

除了輸出的 JavaScript 檔案,該外掛預設會建立一個帶二進位制描述符的額外 JS 檔案。 如果你是構建其他 Kotlin 模組可以依賴的可重用庫,那麼該檔案是必需的,並且應該與轉換結果一起分發。 其生成由 kotlinOptions.metaInfo 選項控制:

compileKotlin2Js {
    kotlinOptions.metaInfo = true
}

針對 Android

Android 的 Gradle 模型與普通 Gradle 有點不同,所以如果我們要構建一個用 Kotlin 編寫的 Android 專案,我們需要用 kotlin-android 外掛取代 kotlin 外掛:

buildscript {
    ext.kotlin_version = '1.3.11'

    ……

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

不要忘記配置標準庫依賴關係

Android Studio

如果使用 Android Studio,那麼需要在 android 下新增以下內容:

android {
  ……

  sourceSets {
    main.java.srcDirs += 'src/main/kotlin'
  }
}

這讓 Android Studio 知道該 kotlin 目錄是原始碼根目錄,所以當專案模型載入到 IDE 中時,它會被正確識別。或者,你可以將 Kotlin 類放在 Java 原始碼目錄中,該目錄通常位於 src/main/java

配置依賴

除了上面顯示的 kotlin-gradle-plugin 依賴之外,還需要新增 Kotlin 標準庫的依賴:

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib"
}

如果針對 JavaScript,請使用 compile "org.jetbrains.kotlin:kotlin-stdlib-js" 替代之。

如果是針對 JDK 7 或 JDK 8,那麼可以使用擴充套件版本的 Kotlin 標準庫,其中包含為新版 JDK 增加的額外的擴充套件函式。使用以下依賴之一來取代 kotlin-stdlib

compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"

對於 Gradle Kotlin DSL,以下表示法的依賴關係與其等價:

dependencies {
    compile(kotlin("stdlib"))
    // 或者以下之一:
    compile(kotlin("stdlib-jdk7"))
    compile(kotlin("stdlib-jdk8"))
}

在 Kotlin 1.1.x 中,請使用 kotlin-stdlib-jre7kotlin-stdlib-jre8

如果你的專案中使用 Kotlin 反射或者測試設施,你也需要新增相應的依賴:

compile "org.jetbrains.kotlin:kotlin-reflect"
testCompile "org.jetbrains.kotlin:kotlin-test"
testCompile "org.jetbrains.kotlin:kotlin-test-junit"

或者,對於 Gradle Kotlin DSL:

compile(kotlin("reflect"))
testCompile(kotlin("test"))
testCompile(kotlin("test-junit"))

從 Kotlin 1.1.2 起,使用 org.jetbrains.kotlin group 的依賴項預設使用從已應用的外掛獲得的版本來解析。你可以用完整的依賴關係符號 (如 compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version",或者在 Gradle Kotlin DSL 中用 kotlin("stdlib", kotlinVersion))手動提供其版本。

註解處理

請參見 Kotlin 註解處理工具kapt)的描述。

增量編譯

Kotlin 支援 Gradle 中可選的增量編譯。 增量編譯跟蹤構建之間原始檔的改動,因此只有受這些改動影響的檔案才會被編譯。

從 Kotlin 1.1.1 起,預設啟用增量編譯。

有幾種方法來覆蓋預設設定:

  1. kotlin.incremental=true 或者 kotlin.incremental=false 行新增到一個 gradle.properties 或者一個 local.properties 檔案中;

  2. -Pkotlin.incremental=true-Pkotlin.incremental=false 新增到 Gradle 命令列引數。請注意,這樣用法中,該引數必須新增到後續每個子構建,並且任何具有禁用增量編譯的構建將使增量快取失效。

請注意,第一次構建不會是增量的。

Coroutines support

Coroutines support is an experimental feature in Kotlin 1.2, so the Kotlin compiler reports a warning when you use coroutines in your project. To turn off the warning, add the following block to your build.gradle file:

kotlin {
    experimental {
        coroutines 'enable'
    }
}

Or, with Gradle Kotlin DSL:

import org.jetbrains.kotlin.gradle.dsl.Coroutines
// ...

kotlin.experimental.coroutines = Coroutines.ENABLE

Module names

The Kotlin modules that the build produces are named accordingly to the archivesBaseName property of the project. If a project has a broad name like lib or jvm, which is common for subprojects, the Kotlin output files related to the module (*.kotlin_module) might clash with those from third-party modules with the same name. This causes problems when a project is packaged into a single archive (e.g. APK).

To avoid this, consider setting a unique archivesBaseName manually:

archivesBaseName = 'myExampleProject_lib'

With Gradle Kotlin DSL, it is:

setProperty("archivesBaseName", "myExampleProject_lib")

Gradle 構建快取支援(自 1.2.20 起)

Kotlin 外掛支援 Gradle 構建快取(需要 Gradle 4.3 及以上版本;低版本則禁用快取)。

由於註解處理器執行的任意程式碼可能不一定會將任務輸入轉換為輸出、可能訪問與修改 Gradle 未跟蹤的檔案等,因此預設不快取 kapt 註解處理任務。要啟用 kapt 快取,請將以下列幾行新增到構建指令碼中:

kapt {
    useBuildCache = true
}

要禁用所有 Kotlin 任務的快取,請將系統屬性標誌 kotlin.caching.enabled 設定為 false(執行構建帶上引數 -Dkotlin.caching.enabled=false)。

編譯器選項

要指定附加的編譯選項,請使用 Kotlin 編譯任務的 kotlinOptions 屬性。

當針對 JVM 時,對於生產程式碼這些任務稱為 compileKotlin 而對於測試程式碼稱為 compileTestKotlin。對於自定義原始檔集(source set)這些任務稱呼取決於 compile<Name>Kotlin 模式。

Android 專案中的任務名稱包含構建變體 名稱,並遵循 compile<BuildVariant>Kotlin 的模式,例如 compileDebugKotlincompileReleaseUnitTestKotlin

當針對 JavaScript 時,這些任務分別稱為 compileKotlin2JscompileTestKotlin2Js,以及對於自定義原始檔集稱為 compile<Name>Kotlin2Js

要配置單個任務,請使用其名稱。示例:

compileKotlin {
    kotlinOptions.suppressWarnings = true
}

compileKotlin {
    kotlinOptions {
        suppressWarnings = true
    }
}

對於 Gradle Kotlin DSL,首先從專案的 tasks 中獲取任務:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
// ……

val compileKotlin: KotlinCompile by tasks

compileKotlin.kotlinOptions.suppressWarnings = true

相應地,為 JS 與 Common 目標使用型別 Kotlin2JsCompileKotlinCompileCommon

也可以在專案中配置所有 Kotlin 編譯任務:

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java).all {
    kotlinOptions { …… }
}

對於 Gradle 任務的完整選項列表如下:

JVM、JS 與 JS DCE 的公共屬性
名稱 描述 可能的值 預設值
allWarningsAsErrors 任何警告都報告為錯誤 false
suppressWarnings 不生成警告 false
verbose 啟用詳細日誌輸出 false
freeCompilerArgs 附加編譯器引數的列表 []
JVM 與 JS 的公共屬性
Name Description Possible values Default value
apiVersion 只允許使用來自捆綁庫的指定版本中的宣告 “1.0”、 “1.1”、 “1.2”、 “1.3”、 “1.4 (EXPERIMENTAL)”
languageVersion 提供與指定語言版本原始碼相容性 “1.0”、 “1.1”、 “1.2”、 “1.3”、 “1.4 (EXPERIMENTAL)”
JVM 特有的屬性
名稱 描述 可能的值 預設值
javaParameters 為方法引數生成 Java 1.8 反射的元資料 false
jdkHome 要包含到 classpath 中的 JDK 主目錄路徑,如果與預設 JAVA_HOME 不同的話
jvmTarget 生成的 JVM 位元組碼的目標版本(1.6 或 1.8),預設為 1.6 “1.6”、 “1.8” “1.6”
noJdk 不要在 classpath 中包含 Java 執行時 false
noReflect 不要在 classpath 中包含 Kotlin 反射實現 true
noStdlib 不要在 classpath 中包含 Kotlin 執行時 true
JS 特有的屬性
名稱 描述 可能的值 預設值
friendModulesDisabled 禁用內部宣告匯出 false
main 是否要呼叫 main 函式 “call”、 “noCall” “call”
metaInfo 使用元資料生成 .meta.js 與 .kjsm 檔案。用於建立庫 true
moduleKind 編譯器生成的模組型別 “plain”、 “amd”、 “commonjs”、 “umd” “plain”
noStdlib 不使用捆綁的 Kotlin stdlib true
outputFile 輸出檔案路徑
sourceMap 生成原始碼對映(source map) false
sourceMapEmbedSources 將原始碼嵌入到原始碼對映中 “never”、 “always”、 “inlining”
sourceMapPrefix 原始碼對映中路徑的字首
target 生成指定 ECMA 版本的 JS 檔案 “v5” “v5”
typedArrays 將原生陣列轉換為 JS 帶型別陣列 true
生成文件

要生成 Kotlin 專案的文件,請使用 Dokka; 相關配置說明請參見 Dokka README 。Dokka 支援混合語言專案,並且可以生成多種格式的輸出 ,包括標準 JavaDoc。

OSGi

關於 OSGi 支援請參見 Kotlin OSGi 頁

使用 Gradle Kotlin DSL

使用 Gradle Kotlin DSL 時,請使用 plugins { …… } 塊應用 Kotlin 外掛。如果使用 apply { plugin(……) } 來應用的話,可能會遇到未解析的到由 Gradle Kotlin DSL 所生成擴充套件的引用問題。為了解決這個問題,可以註釋掉出錯的用法,執行 Gradle 任務 kotlinDslAccessorsSnapshot,然後解除該用法註釋並重新執行構建或者重新將專案匯入到 IDE 中。

上一篇:(三)Kotlin 高階函式

下一篇:(五)協程 Coroutine