https://kotlinlang.org logo
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
scripting
  • c

    cedric

    08/02/2019, 12:23 AM
    I'm seeing a strange problem with this:
    fun gitComplete(line: String, cursorIndex: Int): List<String> {
        val words = line.split(" ")
        if (words[0] == "git") return listOf("commit", "status")
                else return emptyList()
    }
    
    val result = if (args.size == 2) gitComplete(args[0], args[1].toInt())
        else emptyList()
    
    result
    The script above returns a valid result (a list of strings), but if I remove the intermediate
    result
    variable:
    fun gitComplete(line: String, cursorIndex: Int): List<String> {
        val words = line.split(" ")
        if (words[0] == "git") return listOf("commit", "status")
                else return emptyList()
    }
    
    if (args.size == 2) gitComplete(args[0], args[1].toInt())
        else emptyList()
    then the result of the evaluation by the engine is
    null
    .
    i
    • 2
    • 6
  • j

    jdemeulenaere

    08/02/2019, 2:06 PM
    Is there any documentation on how to customize completions, etc inside a script ? 🙂
    i
    • 2
    • 8
  • c

    cedric

    08/02/2019, 5:55 PM
    @ilya.chernikov I tried to trim down that example and stumbled upon a different error (1.3.41):
    // ~/t/a.kts
    fun hello() = "hello"
    hello()
    and
    $ kotlinc -script ~/t/a.kts
    exception: java.lang.ArrayIndexOutOfBoundsException: Index 10912 out of bounds for length 10912
    	at org.jetbrains.org.objectweb.asm.ClassReader.readUnsignedShort(ClassReader.java:2464)
    i
    • 2
    • 1
  • j

    jdemeulenaere

    08/06/2019, 9:50 AM
    Is it possible to configure script dependencies using package (with wildcard) instead of jar name ? (I don't have the jar name because of the build system I am using [bazel])
    i
    g
    • 3
    • 6
  • j

    jdemeulenaere

    08/07/2019, 12:08 PM
    Can we make concurrent calls to BasicScriptingHost#eval ? Or should I create a host for each thread ?
    i
    • 2
    • 1
  • e

    efemoney

    08/08/2019, 10:12 AM
    Does kotlin-main-kts support Maven repos? resolve maven
    @DependsOn
    or is it still Ivy for now? Like can we add maven repositories with the repo annotation?
    i
    • 2
    • 2
  • d

    DALDEI

    08/09/2019, 7:07 AM
    When an extension function is defined outside of any class, script evaluation is not resolving it e.g. class X() operator fun X.plus(x:X) = 1 I cannot get + or plus to be resolved from within a script, but when I put the method in the class like class X () { operator fun plus( x: X) = 1 } then X() + X() works although a fully qualified X().packagename.plus( X()) cannot resolve 'plus' Im guessing this has to do with how extension functions are named and imported -- but I havent found the 'trick' to import them. Any suggestions ?
    i
    • 2
    • 3
  • j

    jdemeulenaere

    08/09/2019, 10:53 AM
    I am trying to get IDE support for my script but I get this error : https://pastebin.com/SdHtVmCD
    i
    • 2
    • 1
  • j

    jdemeulenaere

    08/09/2019, 11:57 AM
    Hopefully last questions for this week: is it possible to create an IntelliJ plugin that restricts the suggestions ? (I want to remove all suggestions coming from the stdlib). Also is it possible to easily create a plugin instead of relying on host discovery that doesn't seem to always work ? (especially once we add compilation configuration, etc)
    i
    • 2
    • 6
  • a

    altavir

    08/10/2019, 2:42 PM
    I was not touching my scripting example for some time and not (probably after version upgrade I get
    Expecting 'hostConfiguration' property in the script compilation configuration for the script KtFile: script.kts
    I tried to somehow provide this
    hostConfiguration
    , but I just do not understand how it works. My configuration looks like this:
    val workspaceScriptConfiguration = ScriptCompilationConfiguration {
                baseClass(Any::class)
                implicitReceivers(WorkspaceBuilder::class)
                defaultImports("hep.dataforge.workspace.*")
                jvm {
                    dependenciesFromCurrentContext(wholeClasspath = true)
                }
            }
    
            val evaluationConfiguration = ScriptEvaluationConfiguration {
                implicitReceivers(builder)
            }
    
            BasicJvmScriptingHost().eval(source, workspaceScriptConfiguration, evaluationConfiguration)
    i
    • 2
    • 7
  • j

    jdemeulenaere

    08/16/2019, 8:15 AM
    Any reason why kotlin-scripting-jvm-host is the only scripting related JAR that is not shipped with the compiler release ? (https://github.com/JetBrains/kotlin/releases/tag/v1.3.41). Also, is there an official release for this JAR ? (I know it is available in maven central but I need an "official" release link, if there is any)
    l
    i
    • 3
    • 11
  • f

    fogone

    08/17/2019, 4:48 PM
    I have strange script problem. I use
    implicitReceivers()
    and trying to import another script using
    @file:Import("..")
    annotation. In
    evalWithConfigAndOtherScriptsResults()
    -- it's part of
    kotlin.script.experimental.jvm.BasicJvmScriptEvaluator
    there is next code:
    val ctor = java.constructors.single() // <-- generated constructor which expects (imported script result, implicit receiver)
    val instance = ctor.newInstance(*args.toArray()) // <--- args here reversed, so (implicit receiver, imported script result)
    did somebody meet this problem?
    i
    • 2
    • 9
  • e

    efemoney

    08/20/2019, 9:46 AM
    Seems
    kotlin-scripting-jvm-host
    is missing a dependency on
    kotlin-scripting-compiler(-embeddable)
    in the pom. Had to explicitly specify it.
    g
    i
    • 3
    • 9
  • j

    josephivie

    08/22/2019, 5:33 AM
    How do I run a standalone Kotlin script like the one shown in the examples here: https://github.com/Kotlin/KEEP/blob/master/proposals/scripting-support.md ? I'm writing
    kotlinc -cp kts.jar -script test.kts
    , where
    test.kts
    is my script file and
    kts.jar
    is the
    kotlin-main-kts
    JAR from Maven, but I get 'Unable to find script definitions' and a bunch of errors related to it not knowing what the dependency annotations are. I'm following the tutorial as exactly as I understand it - what's missing?
    g
    • 2
    • 8
  • j

    josephivie

    08/22/2019, 5:42 AM
    Follow up question: if the standard/most common way of running
    .kts
    files will be with this script runner, why is it not default? The complexity of use is keeping scripting from becoming widely useful. I'd like the equivalent
    python script.py
    , and I'd like it to be part of installing Kotlin. Until it's that simple, I can't rely on distributing
    .kts
    files to others as a consistent, portable, easy way of giving other people scripts. I know
    kscript
    exists, but it only supports *nix.
    g
    i
    c
    • 4
    • 51
  • j

    josephivie

    08/23/2019, 1:05 AM
    I could put together a temporary solution with these features: - Maven dependency resolution via future-standard
    @Repository
    and such, possibly with Maven Central and JCenter just implied - future-compatible support with normal Kotlin scripts top priority - Interactive mode - load the KT/KTS file and then get a REPL - Line Argument - run the KT/KTS file, providing the expression you wish to be executed in that context. - Open in IntelliJ - creates a project in a temp folder, including needed files using hard links. Full auto-complete. Does not use Gradle under the hood, but rather direct IML files. - Fully platform independent, running in Java without any platform-specific features nor a separate installation of Kotlin (use embedded compiler instead) - Perhaps platform-specific GUI integration - double click on script file to run, context-menu edit... Is this something people would be interested in? I think it wouldn't take me too long - I've experimented with similar things already. I already know how to create IntelliJ projects from XML, running Kotlin scripts, running the embedded Kotlin compiler, etc. I'd primarily use it for build-scripts, personally. It would be nice to ditch Gradle and anything Gradle-like in favor of straight-up using libraries from Maven to compile your stuff. That would be some nice standard reuse there. I can imagine creating a
    build.kts
    file and then opening it in interactive mode in the terminal of IntelliJ to run tasks like
    build()
    ,
    run()
    ,
    publish()
    , etc. It would be so much faster to edit (Gradle's KTS editing isn't too speedy and resolving plugins can be tricky) and would make build files easier to follow, as they'd just be more normal Kotlin without extra bulky configuration systems and magic plugins. No build system, just... Kotlin. I'd have to make a couple of Maven libraries to make it more convenient to set up, but that's not too bad.
    i
    e
    • 3
    • 2
  • j

    josephivie

    08/23/2019, 2:19 AM
    Give me until the end of Saturday! I already have most of the parts working; I'm now working on platform-specific GUI integration (installation, more or less) and then tying it all together in one main function. I'll distribute it as a fat JAR. I wasn't kidding when I said I've been experimenting with stuff already! The IDE stuff was the most troublesome to experiment with (I was working on that earlier this week, wanted to know how IMLs worked) because I couldn't find any documentation on the format of it. I had to kinda just guess my way through it.
    g
    • 2
    • 4
  • j

    josephivie

    08/23/2019, 2:21 AM
    UX question: should the default action (double click) be to edit a script or run it?
    n
    • 2
    • 2
  • d

    DALDEI

    08/24/2019, 1:25 PM
    @tateisu re scripting on android. Great question ! No Answer 😞 Ignorant Guess: Maybe -- if you dont use the JSR232 interface ?? (just the native one). Ignorant count-guess: No idea if even the embeded scripting compiler will run on android
    m
    i
    • 3
    • 6
  • j

    josephivie

    08/25/2019, 7:51 AM
    Project Skate, my experimental scripting-oriented project with Kotlin, is available as stated above. https://github.com/UnknownJoe796/skate I still recommend KScript if you're not on Windows, but learning from this has been well worth my time. Hopefully there are some things that could be pulled out into KScript and perhaps other projects. There's several well-separated modules in here for making IntelliJ projects, compiling Kotlin, and resolving Maven dependencies. I couldn't get
    .kts
    proper files working - for whatever reason, the embedded compiler wouldn't compile them but the standalone one would. Also couldn't figure out how to get them playing well with plain IntelliJ projects. I'd love to learn more about the topic if anyone has information I couldn't find.
    n
    j
    • 3
    • 2
  • e

    Egor

    08/25/2019, 11:55 AM
    Hi, I have some issues with executing scripts from our kotlin code. 1. Script evaluating consumes a lot of memory, we evaluate around 100 scripts and and it consumes about 2G of memory. Before 1.3.50 we noticed that if we use engine #compile, after that #eval(bindings) and after that we clear the bindings the memory consumption has been reduced to 700M (Not ideal but something). After upgrading to 1.3.50 this work-around does not work anymore. 2. I thought that using ‘kotlin-main-kts’ might reduce memory consumption, but I can not get it working with bindings. It works with executing simple scripts but not with using bindings ( or external params through engine.put(,)) I’d appreciate any any help, guys. Thanks in advance.
    i
    c
    d
    • 4
    • 8
  • l

    Leon K

    08/26/2019, 2:01 PM
    Hey! i'm currently working on a server, where i need to be able to configure rather complicated actions. I've currently built a proof of concept DSL for that, and it's great. But i need to be able to reconfigure it without having to restart / recompile my server, so just putting the DSL into the server is no option. I thought about using Kotlin-script for that purpose. I'd need to somehow expose my DSL api to kotlin-script, evaluate that script from my Kotlin-server and get the configuration back. is this currently possible, or say practical with Kotlinscript? there are two questions: - how can i get my type-safe DSL API into kotlinscript? - how could i get the generated objects back from the script? any help would be appreciated ;D
    n
    j
    • 3
    • 5
  • i

    ILakeful

    08/26/2019, 9:23 PM
    Just tried the evaluation via "kotlin-scripting-jsr223" (1.3.50) and found out that trying to call a binding named e.g. "example" from within a coroutine (I presume it's about everything accepting a suspending lambda) throws NoSuchMethodError with a message like:
    Exception in thread "..." java.lang.NoSuchMethodError: Line_1.access$getExample$p(LLine_1;)Ljava/lang/String;
    i
    • 2
    • 3
  • d

    darkmoon_uk

    09/01/2019, 12:44 AM
    Surprised this wasn't reported already - is everyone affected? https://youtrack.jetbrains.com/issue/KT-33636
    i
    i
    • 3
    • 2
  • d

    DALDEI

    09/01/2019, 11:48 PM
    Request Reference to 'Current' Working self-contained sample of basic JVM Scripting Host build I have tried, unsuccessfully, many times over the last 2 years to put together a very 'basic' JVM Scripting 'host' that can do a 'Eval' of a .kts file or script body (and parameters). I was able to get the JSR223 samples to work (which I have working now) but they are not ideal and have a lot of dependencies and resource use which I've learned recently (From this list) that are not issues with the native scripting host. The problem I find is that I cannot locate a 'current working example' anywhere -- Ive found many that probably worked at some time but by the time I find them them they do not, Or examples , such as from the intellij and kotlin distributions that might work -- -- if only I could decipher the chain of dependencies in the whole project -- And many of those simply didnt work even when built directly within the project cleanly cloned from github. I know its a moving target, and that dependencies are either not shipped or expected to be replaced by others or 'internal only' or some other combination of magic - all for good reasons. Or that the code-in-question 'Works For Me' where 'Me' is an internal developer or someone with a dependency resolver that I cannot locate or reverse engineer. At this point in the 'Kotlin Scripting Story' surely theirs a basic stable example to use ? Probably LOTS -- but which one is valid right now ? Any suggestions welcome. (And yes I've RTFM's every article, blog, KEEP, reference etc I can find -- without locating this magic bean)
    ➕ 1
    i
    • 2
    • 5
  • d

    DALDEI

    09/05/2019, 11:58 AM
    Bare minimal self-contained kotlin program that evaluates kotlin script using 'current' gradle/kotlin/intellij Thanks to @Egor for patience Note: This is NOT an example of 'best practice' -- I dont know what that is, its an example of "I Finally got the non-223 script host to compile and run" https://github.com/DALDEI/kotlin-script-sample
    👍 1
    👏 1
    d
    i
    • 3
    • 4
  • n

    Nikky

    09/06/2019, 3:47 PM
    on the way home today i was thinking about.. how does the embedded compiler integrate with eg. compile plugins ? i assume using kotlinx-serialization would work since its bundled in the normal compiler, but does it have to be enabled? (never tried) and what about potential 3rd party plugins?
    i
    • 2
    • 1
  • p

    Paul Woitaschek

    09/17/2019, 8:41 AM
    Can I configure an annotation processor in kscript somehow?
    e
    • 2
    • 5
  • j

    jdemeulenaere

    09/22/2019, 12:07 PM
    Hi guys! I have a question about changing the definition of a class/jar used by my scripts. I have a server that takes code (a String) as input, compiles/evaluates the code and returns some result. To do that I instantiate a BasicJvmScriptingHost that is shared between requests (code of the script host is more or less https://pastebin.com/gtPvPaT1). Scripts are allowed to depend on some JARs, and one of those JARs contains a single generated class whose definition will change during the server lifetime. Is it possible to make my scripts depend on the latest definition of this JAR without needing to restart my server or recreating a host ? If necessary this generated class could also be contained in a Kotlin Script that we would make accessible to the other scripts (if it's possible). Thanks 🙂
    c
    e
    • 3
    • 6
  • b

    bamboo

    09/23/2019, 8:26 PM
    Hello, We’re in the process of migrating the Gradle Kotlin DSL from the legacy Kotlin script API to the latest experimental one so we can take advantage of the new implicit receivers feature but I’m having a little trouble figuring out how to migrate one of our script templates. In the troublesome scenario the list of default imports must be computed dynamically from data passed from the outside to the compiler. With the legacy API we were able to achieve it via a custom
    ScriptDependenciesResolver
    that reads the data from the given script resolver environment which can be configured via the
    -Xscript-resolver-environment
    command line argument. The custom resolver is setup via the
    ScriptTemplateDefinition
    annotation: https://github.com/gradle/gradle/blob/6f683805c6b782b1eb91c01591aecabe6fe535fb/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/precompile/PrecompiledProjectScript.kt#L52-L54 My understanding is that it is NOT possible to mix the legacy
    ScriptTemplateDefinition
    annotation with the new
    KotlinScript
    one to get both, the dynamic implicit imports computed from the script resolver environment plus the implicit receivers from a custom
    compilationConfiguration
    setup. So the question is then, does the experimental API allow for the list of default imports for a given script to be computed based on command line arguments passed to the compiler?
    @KotlinScript(
            compilationConfiguration = DynamicDefaultImportsConfiguration::class
            // other settings
        )
        open class ScriptWithDynamicDefaultImports
    
        object DynamicDefaultImportsConfiguration : ScriptCompilationConfiguration({
            refineConfiguration {
                beforeCompiling {
                    it.compilationConfiguration.with {
                        defaultImports(
                            // How to read arguments passed to the compiler from here?
                            TODO()
                        )
                    }.asSuccess()
                }
            }
        })
    n
    i
    t
    • 4
    • 128
Powered by Linen
Title
b

bamboo

09/23/2019, 8:26 PM
Hello, We’re in the process of migrating the Gradle Kotlin DSL from the legacy Kotlin script API to the latest experimental one so we can take advantage of the new implicit receivers feature but I’m having a little trouble figuring out how to migrate one of our script templates. In the troublesome scenario the list of default imports must be computed dynamically from data passed from the outside to the compiler. With the legacy API we were able to achieve it via a custom
ScriptDependenciesResolver
that reads the data from the given script resolver environment which can be configured via the
-Xscript-resolver-environment
command line argument. The custom resolver is setup via the
ScriptTemplateDefinition
annotation: https://github.com/gradle/gradle/blob/6f683805c6b782b1eb91c01591aecabe6fe535fb/subprojects/kotlin-dsl/src/main/kotlin/org/gradle/kotlin/dsl/precompile/PrecompiledProjectScript.kt#L52-L54 My understanding is that it is NOT possible to mix the legacy
ScriptTemplateDefinition
annotation with the new
KotlinScript
one to get both, the dynamic implicit imports computed from the script resolver environment plus the implicit receivers from a custom
compilationConfiguration
setup. So the question is then, does the experimental API allow for the list of default imports for a given script to be computed based on command line arguments passed to the compiler?
@KotlinScript(
        compilationConfiguration = DynamicDefaultImportsConfiguration::class
        // other settings
    )
    open class ScriptWithDynamicDefaultImports

    object DynamicDefaultImportsConfiguration : ScriptCompilationConfiguration({
        refineConfiguration {
            beforeCompiling {
                it.compilationConfiguration.with {
                    defaultImports(
                        // How to read arguments passed to the compiler from here?
                        TODO()
                    )
                }.asSuccess()
            }
        }
    })
n

nastelaz

09/24/2019, 9:16 AM
cc @ilya.chernikov
i

ilya.chernikov

09/24/2019, 11:54 AM
Hi @bamboo! The previous solution is a bit hacky anyway, and we haven’t yet found time to analyze and maybe design a better way to access the compiler command line from scripts. But, first of all, the old “environment” is still accessible internally via
get(ScriptCompilationConfiguration.hostConfiguration)?.get(ScriptingHostConfiguration.getEnvironment)?.invoke()
but more importantly, since you can use your own host, you can add a new key to the compilation configuration and pass required parameters via it directly, without using command line. But maybe it’s a bit too early for gradle to switch to the new API anyway: I had an intention to implement a refinement callback for “sections”, to remove necessity to use the lexer directly on your side. But if you’re eager to use new API, I can probably try to prioritize this task as well.
b

bamboo

09/24/2019, 11:58 AM
Hey @ilya.chernikov!
Using the old environment should get things going for now, I’ll give it a try, thanks!
since you can use your own host, you can add a new key to the compilation configuration and pass required parameters via it directly, without using command line.
This is very interesting
Do you have any pointers to the specific place in the docs or maybe an example that would make things a little more concrete? 🙂
i

ilya.chernikov

09/24/2019, 12:08 PM
I fixed environment access code above a bit.
b

bamboo

09/24/2019, 12:08 PM
I see 👍
i

ilya.chernikov

09/24/2019, 12:12 PM
About examples: Here is how you’re using a basic host implementation to compile your script - https://github.com/JetBrains/kotlin/blob/master/libraries/examples/scripting/jvm-simple-script/host/src/org/jetbrains/kotlin/script/examples/jvm/simple/host/host.kt#L18 And you can have a look at any definition of a configuration key, to see how to define your own. The configuration is a polymorphic container, which you can extend as you like just by defining new keys.
b

bamboo

09/24/2019, 12:14 PM
Is it possible to use those same configuration keys to configure the Gradle Kotlin plugin
compileKotlin
tasks somehow?
i

ilya.chernikov

09/24/2019, 12:16 PM
You mean in the case when you compile scripts with gradle?
b

bamboo

09/24/2019, 12:16 PM
The scenario for these templates is a little different
It’s not Gradle compiling the scripts directly
but a regular
compileKotlin
task which has its configuration augmented by the
kotlin-dsl
plugin
the
kotlin-dsl
plugin adds the required script templates to the classpath and configures the script environment via
freeCompilerArgs
i

ilya.chernikov

09/24/2019, 12:22 PM
As far as I remember you’ve been calling our compiler directly from gradle to compile build scripts. Is something changed here or we’re talking about different type of scripts?
b

bamboo

09/24/2019, 12:27 PM
right, this is a different scenario
this is to allow folks to implement Gradle plugins by writing Gradle scripts instead of classes
so the templates are used for scripts in a regular Kotlin sourceset
we call them precompiled script plugins
or precompiled scripts
we still have the scenario where Gradle compiles build script by calling the Kotlin compiler directly
that scenario was mostly migrated to the new script API, except for the IDE support
i

ilya.chernikov

09/24/2019, 12:30 PM
Ok, I see.
First about precompiled scripts: if you want to use compileKotlin, then the compiler will use the script compilation configuration it can extract for the given script name. There are several ways to provide this configuration, but there is no direct functionality I can think of, that would allow you to pass data from
kotlin-dsl
extension to it. So you can either continue to use “environment” hack, until we’ll come up with anything, or can create your own out-of-band data exchange.
b

bamboo

09/24/2019, 12:37 PM
As long as the hack is working it shouldn’t be a problem. This is not directly exposed to users in any way.
Meaning, we can evolve the internal protocol when we’re ready to.
About the IDE support, the problem is a little similar
We currently expose a
ScriptDependenciesResolver
to compute the classpath
and we would like to tell the IDE the template has implicit receivers
i

ilya.chernikov

09/24/2019, 12:39 PM
About the compilation from gradle, it will be nice if you can switch to the compilation via a host (or via more low-level script compiler & evaluator), as in the linked sample, rather than calling the compiler internals. And I will eventually make a replacement for the lexer usage, so you’ll be able to rely on the supported API instead (when it become really supported after graduating from experimental status, anyway).
➕ 1
b

bamboo

09/24/2019, 12:40 PM
Yes, absolutely, we’re planning to switch to the new compilation method after 6.0 is released.
i

ilya.chernikov

09/24/2019, 12:42 PM
And in all cases it will be nice if you’ll provide proper script templates with configurations attached with the
KotlinScript
annotation, In this case the IDE support should work out of box.
b

bamboo

09/24/2019, 12:42 PM
We are switching to new template mechanism internally so we can replace the interface delegation we use in our templates by an implicit receiver instead
In this case the IDE support should work out of box.
It’s just not clear to me at this point what the replacement for the
ScriptDependenciesResolver
in that case would be
i

ilya.chernikov

09/24/2019, 12:44 PM
I see the problem with script naming though - your precompiled scrips seems have the same file patter as the build scripts. We will have problems at the moment in distinguishing them.
b

bamboo

09/24/2019, 12:47 PM
Maybe we should move the precompiled script templates to a separate module. For the batch compilation case we use the
-script-templates
compiler argument to tell exactly which templates should be used.
i

ilya.chernikov

09/24/2019, 12:49 PM
It’s just not clear to me at this point what the replacement for the
ScriptDependenciesResolver
in that case would be
In your example above, the block:
refineConfiguration {
            beforeCompiling {
is one of the “resolvers” in the old API - it is a callback that is called by the compiler, so you can change compilation configuration according to your needs. So, e.g. now in this block you can add dependencies to the configuration.
b

bamboo

09/24/2019, 12:49 PM
OR better, have a single set of templates and use them for precompiled scripts
So, e.g. now in this block you can add dependencies to the configuration.
I see, so we could make a blocking TAPI model call at that point
i

ilya.chernikov

09/24/2019, 12:50 PM
Maybe we should move the precompiled script templates to a separate module.
The problem with distinction is IDE-specific, we can easily separate compilation, but in the IDE we have a single set of templates per project.
b

bamboo

09/24/2019, 12:50 PM
there’s also ongoing work on the TAPI models
The problem with distinction is IDE-specific, we can easily separate compilation, but in the IDE we have a single set of templates per project.
Conceptually, the API exposed by the templates should be exactly the same
and that’s why the IDE support currently work just fine with a single set of templates
i

ilya.chernikov

09/24/2019, 12:52 PM
With dependencies?
b

bamboo

09/24/2019, 12:52 PM
what do you mean?
the dependencies are computed differently depending on where in the source tree we find the scripts
(if it’s in a Kotlin sourceset we return the compileKotlin compile dependencies, otherwise we return the regular per script dependencies)
the single resolver can handle it because the decision is taken by the TAPI model builder
I hope that’s in the direction of your question 🙂
i

ilya.chernikov

09/24/2019, 1:03 PM
More or less, except that in the IDE it is processed differently, the one in a sourceset are probably a part of a module, so the module dependencies are calculated via the project model. But we’re not decided what to do with scripts in this case. For a moment we ignore (in the IDE) all dependencies that are coming from the configuration for scripts and use module dependencies instead. But this blocks certain interesting use cases. So we may consider taking configuration dependencies into account. For the out-of-sources scripts we’re using dependencies from configuration only. So if you’ll have same base configuration for both script types, in the future you’ll need to decide which dependencies to add to the configuration.
b

bamboo

09/24/2019, 1:04 PM
For a moment we ignore (in the IDE) all dependencies that are coming from the configuration for scripts
Ah, I didn’t know that
i

ilya.chernikov

09/24/2019, 1:05 PM
I mean only the scripts which are a part of a module/sourceset.
b

bamboo

09/24/2019, 1:06 PM
Right. What about the default imports? Because I think we do compute them on the fly for different scripts and the IDE seems to honour them.
I mean, different scripts which are part of a module sourceset.
We give them different default imports to make certain extensions visible or not depending on the set of plugins they apply
i

ilya.chernikov

09/24/2019, 1:08 PM
Everything else is fine, dependencies are not, because such “extending dependencies for a subset of the sources in the sourceset” seems not supported in the IDEA project model.
b

bamboo

09/24/2019, 1:08 PM
I see 👍
i

ilya.chernikov

09/24/2019, 1:11 PM
Coming back to the lexer stuff, what I’m planning to do is to have a callback like:
refineConfiguration {
            onSections("plugins", "dependencies") {
that would allow you to process sections of the scripts without using the lexer directly. What do you think about such an API?
b

bamboo

09/24/2019, 1:18 PM
Currently, we compile the
plugins
/
buildscript
/
initscript
sections as separate scripts
so we would basically need to be able to “cancel” the compilation of certain sections
i

ilya.chernikov

09/24/2019, 1:20 PM
I don’t think you need a cancel, in this
onSections
block, you need to execute another compiler for the section before continuing with the results.
b

bamboo

09/24/2019, 1:20 PM
also, I’m not sure we would be able to give up using the lexer completely because we take different decisions on how to compile scripts depending on which sections are present
i

ilya.chernikov

09/24/2019, 1:21 PM
What in particular changing?
b

bamboo

09/24/2019, 1:23 PM
to speed up repeated executions, we emit a class (that gets cached) that knows exactly which parts of the script need to be compiled
this class is like a specialized interpreter for the script
it makes loading scripts from the cache uniform
and helps with keeping some things precompiled
for a concrete example, take the following script:
plugins { java }

java { }
upon analysing this script, we see that we always have to run the
plugins
block before we can compile the rest of the script
so what we do is, we emit a
Program
(that’s what we call this uniform façade to the scripts)
we compile the
plugins
section at this point because we know it needs to run every time
and we make a
Program
that executes the precompiled
plugins
script and THEN compiles the rest after the plugins have been applied
that strategy saves a few cycles when plugins or buildscript block changes cause the body of the script to be recompiled
it is complicated though
i

ilya.chernikov

09/24/2019, 1:42 PM
Ok, I see. Sounds complicated, yes. So, seems this
onSections
callback doesn’t fit your use case. I’ll think about it further. I still don’t like the fact that you’re using compiler internals. Maybe the old (and still unused) solution with the
source-sections
compiler plugin should be revived after all.
b

bamboo

09/24/2019, 1:43 PM
Hm, the compiler doesn’t seem to recognise the template configured via
-script-templates
anymore now that I changed from
ScriptTemplateDefintion
to
KotlinScript
(trying to test that environment access snippet)
ok, it works if I use both annotations 🙂
i

ilya.chernikov

09/24/2019, 1:47 PM
🙂 a nice hack
🤘 1
b

bamboo

09/24/2019, 1:47 PM
for now it seems this will do
I’ll play a bit more with it and let you know
thanks again, Ilya
i

ilya.chernikov

09/24/2019, 1:48 PM
Actually, you can use a complicated plugin option format:
-Pplugin:kotlin.scripting:script-definitions=...
or - better - use script definitions discovery mechanism.
👍 2
b

bamboo

10/07/2019, 5:18 PM
Status update: the migration to new
KotlinScript
annotation for compilation worked out great and Gradle 6.0 will ship with the new implicit receiver based script templates. Thanks again!
We are still using the old style templates for the IDE support and now I’m looking into migrating those.
Does IntelliJ already handle custom `compilationConfiguration`s?
i

ilya.chernikov

10/08/2019, 6:20 AM
Thank you for the great news!
Yes, IDE support should now be on the same or better level as with old templates.
b

bamboo

10/08/2019, 2:37 PM
Great. I got IntelliJ to recognize my new
@KotlinScript
based template yesterday but I didn’t manage to get it to see the
baseClass(...)
I gave the template, will continue to investigate it later.
One question though:
is it possible to get the IDE to continue to use the resolver from
@ScriptTemplateDefinition
to get the classpath and default imports but get the remaining settings (mainly
implicitReceivers
) from the `@KotlinScript`’s
compilationConfiguration
?
i

ilya.chernikov

10/08/2019, 2:56 PM
No, mixing is not possible, unfortunately. Why would you need it?
b

bamboo

10/08/2019, 3:10 PM
As long as a refinement handler can make a blocking TAPI call to Gradle to get the data, there’s no need for it.
Almost there! I got the IDE to recognize my template with an implicit receiver and the implicit receiver is taken into account for error checking BUT it is NOT taken into account for content assistance
meaning, I don’t get suggestions for members of an implicit receiver type
any thoughts?
also it seems
annotationsForSamWithReceivers
has no effect in IntelliJ, should it be supported already?
the experiment is here: https://github.com/gradle/gradle/pull/10977/files#
maybe you can spot whether I’m doing something wrong
ping @ilya.chernikov ☝️
i

ilya.chernikov

10/09/2019, 10:19 AM
@bamboo, I see what is missing with
annotationsForSamWithReceivers
- will check whether I can fix it quickly. About the implicit receiver - I need to dig a bit deeper.
b

bamboo

10/09/2019, 12:13 PM
Thanks! Let me know if you’d like me create an YT issue for it.
i

ilya.chernikov

10/10/2019, 3:15 PM
@bamboo, the problem with
samWithReceiver
is a bit worse then I thought. I need some more time to implement required functionality for the new scripting API. I’ll try to do it as soon as possible, but I’m by far not sure if it is not already too late for 1.3.60. Anyway, here is the issue to watch - https://youtrack.jetbrains.com/issue/KT-34294
b

bamboo

10/10/2019, 4:07 PM
Thanks, @ilya.chernikov
My plan is to finish converting the remaining templates to uncover any remaining issues and give you a proper nightly you can use to validate the changes and the IntelliJ UX
then we can see if the new templates go with Gradle 6.1 and Kotlin 1.3.60 OR if we have to wait for the next release train
in parallel to this, there’s the new TAPI model work happening to optimize the script classpath computation
I imagine there might be some overlap and the migration to the new templates might cause some rework on your side
which is why I think getting a 6.0 compatible Gradle nightly with the new templates will be key
how does that sound to you?
i

ilya.chernikov

10/10/2019, 4:36 PM
Sounds good to me. Will try to push my part through as soon as possible.
Hi @bamboo! I think I fixed the problem with sam-with-receiver, although maybe the wrong one. 🙂 What I’ve meant with KT-34294 is that SAM with receiver is not properly processed then using the new API to compile it, rather than calling the internal compiler API directly, as you seems still doing. I fixed the processing, so if you will ever be able to switch to the new API - it should work. But I also hopefully fixed the problem with IDEA, which wasn’t mentioned in the issue - I’m now configuring the sam-with-receiver annotation for IDEA as well. But I haven’t been able to test it yet - I have problems with trying to build your branch with locally-built kotlin. The fixes will be in the next 1.3.60 EAP (in the next few days) so as soon as it is out and I have some time - I’ll try to test it again on your branch. Or you can try it yourself then.
The problem with implicit receiver is being investigated by @nastelaz now.
t

Tmpod

01/25/2020, 11:26 PM
@ilya.chernikov any update on implicit receivers recognition by IntelliJ? I'm trying to use them but I can't get the IDE to stop erroring on unknown references and to give me completion suggestions.
i

ilya.chernikov

01/27/2020, 10:41 AM
@Tmpod the problem is fixed for upcoming 1.3.70 - https://youtrack.jetbrains.com/issue/KT-34740 (although unresolved references could be a sign of the different problem, so maybe it help if you'll give some more details, in a new thread.)
t

Tmpod

01/27/2020, 10:47 AM
Great! The unresolved references are connected with the implicit receivers since I only get those on the methods the wrapping class has.
Is there any ETA for 1.3.70?
i

ilya.chernikov

01/27/2020, 10:47 AM
~ Feb.
t

Tmpod

01/27/2020, 10:49 AM
Cool
I'll just ignore those errors while 1.3.70 doesn't come out :p
i

ilya.chernikov

01/27/2020, 10:59 AM
BTW, meanwhile you can try the EAP https://discuss.kotlinlang.org/t/kotlin-1-3-70-early-access-preview/15876
t

Tmpod

02/11/2020, 7:14 PM
will do, thanks! totally missed this message too :/
View count: 4