Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 格拉德尔。块插件{}中的自定义函数_Kotlin_Gradle_Gradle Plugin_Gradle Kotlin Dsl - Fatal编程技术网

Kotlin 格拉德尔。块插件{}中的自定义函数

Kotlin 格拉德尔。块插件{}中的自定义函数,kotlin,gradle,gradle-plugin,gradle-kotlin-dsl,Kotlin,Gradle,Gradle Plugin,Gradle Kotlin Dsl,我可以在我的自定义插件中编写一些类似kotlin(“jvm”)的函数吗 我想在我的自定义插件中编写函数myplugin(“foo”),然后像这样使用它 plugins { java kotlin("jvm") version "1.3.71" custom.plugin myplugin("foo") } 我该怎么做?kotlin函数只是一个简单的扩展函数,它包装了传统的id方法,不难定义: fun PluginDependenciesSpec.kotlin(m

我可以在我的自定义插件中编写一些类似kotlin(“jvm”)的函数吗

我想在我的自定义插件中编写函数myplugin(“foo”),然后像这样使用它

plugins {
    java
    kotlin("jvm") version "1.3.71"
    custom.plugin
    myplugin("foo")
}

我该怎么做?

kotlin函数只是一个简单的扩展函数,它包装了传统的
id
方法,不难定义:

fun PluginDependenciesSpec.kotlin(module: String): PluginDependencySpec =
    id("org.jetbrains.kotlin.$module")
然而,这个扩展函数是标准gradle kotlin DSL API的一部分,这意味着它不需要任何插件就可以使用。如果你想让这样的自定义函数可用,你需要一个插件。加载插件的插件。不太实用

我还尝试使用
buildSrc
模块来创建一个类似于上述的扩展函数。但事实证明,pluginsdsl块甚至不能提供
buildSrc
定义,因为它的语法非常有限。无论如何,这都不太实际,您需要为每个希望使用扩展的项目创建一个buildSrc文件夹


我不确定这是否可能。试着问一下。

我认为
插件
块是某种宏表达式。它使用非常有限的上下文进行解析和预编译。也许,魔法发生在世界的某个地方。这可能是从插件获取静态访问器和扩展函数以在Kotlin中工作的唯一方法。我从未在Gradle的文档中提到过这个过程,但让我来解释一下我的想法。也许Gradle的一些聪明人会纠正我

让我们看看一些第三方插件,比如。它允许您在
build.gradle.kts
中编写类似的内容:

液化{
活动{
登记册(“姓名”){
//在此处配置活动
}
}
}
想一想:在像Kotlin这样的静态编译语言中,为了使这个syntaxt工作,在
项目
类型上应该有一个名为
liquibase
的扩展(因为它是每个
build.gradle.kts
中的
这个
对象的类型)在执行构建脚本的Gradle虚拟机的类路径中可用

事实上,如果你点击它,你会看到如下内容:

fun org.gradle.api.Project.`liquibase`(配置:org.liquibase.gradle.LiquibaseExtension.(->单位):单位=
(这是org.gradle.api.plugins.ExtensionAware).extensions.configure(“liquibase”,configure)
但请看一下定义它的文件。在我的例子中,它是
~/.gradle/caches/6.3/gradle-kotlin dsl访问器/cmljl3ridzazieb8fzn553oa8/cache/src/org/gradle/kotlin/dsl/Accessors39qcxru7gldpadn6lvh8lqs7b.kt
。它确实是一个自动生成的文件。在我的例子中,文件树的上面几层-在
~/.gradle/caches/6.3/gradle kotlin dsl accessors/
有几十个类似的目录。我猜,我在Gradle 6.3中使用过的每个插件/版本都有一个。下面是插件的另一个:

fun org.gradle.api.Project.`detekt`(配置:io.gitlab.arturbosch.detekt.extensions.DetektExtension.(->单位):单位=
(这是org.gradle.api.plugins.ExtensionAware).extensions.configure(“detekt”,configure)
因此,我们有一堆
.kt
文件定义了应用于项目的不同插件的所有扩展。文件显然是预缓存和预编译的,它们的内容可以在
build.gradle.kts
中找到。实际上,您可以在这些源旁边找到
目录

源代码是根据应用插件的内容生成的。这可能是一个包含一些魔力、反思和内省的过程。有时这种魔力不起作用(由于太过健谈的Groovy特性),然后您需要使用一些来自的蹩脚DSL

它们是如何产生的?我看没有别的办法,只有

  • 使用嵌入式Kotlin编译器/lexer解析
    build.script.kts
  • 提取所有
    插件
    部分
  • 编译它们,可能是针对一些模拟(记住,
    Project
    还不可用:我们还没有执行
    build.gradle.kts
    本身!)
  • 从解析声明的插件(其中一些来自
    settngs.gradle.kts
  • 内省插件的工件
  • 生成源代码
  • 编译源代码
  • 将结果类添加到脚本的类路径
  • 这里有一个问题:编译
    插件
    块时,可用的上下文非常有限(类路径、类、方法-随便叫什么)。实际上,还没有应用插件!因为,你知道,你正在解析应用插件的块。鸡、蛋和它们的问题,嗯

    因此,我们正在接近您问题的答案,要在
    插件
    块中提供自定义DSL,您需要修改该类路径。它不是
    build.gradle.kts
    的类路径,而是解析
    build.gradle.kts
    的VM的类路径。基本上,它是Gradle自己的类路径——所有类都捆绑在Gradle发行版中

    因此,在
    plugins
    块中提供真正定制DSL的唯一方法可能是创建定制的Gradle发行版

    编辑:

    实际上,完全忘记了测试
    buildSrc
    。我在其中创建了一个文件
    pluginextrains.kt
    ,其中包含一个

    inline val org.gradle.plugin.use.plugindependencesspec.`jawa`:org.gradle.plugin.use.plugindependencespec
    get()=id(“org.gradle.war”)//随机选取
    内联fun org.gradle.plugin.use.plugindependencespec.`jawa`():org.gradle.plugin.use.plugindependencespec{
    返回id(“org.gradle.cunit”)//随机选取
    }
    
    它似乎在起作用:

    插件{
    爪哇
    爪哇
    }
    
    但是,这仅在默认包中包含
    pluginExtrade.kt
    时有效。每当我把它放进
    fun PluginDependenciesSpec.kotlin(module: String): PluginDependencySpec =
        id("org.jetbrains.kotlin.$module")