Hey from Kotlin team :kotlinnew: Quick question: w...
# gradle
e
Hey from Kotlin team K Quick question: what DSL do you like more Option #1 - changing a task
Copy code
tasks.withType<KotlinCompile>().configureEach {
    kotlinOptions.freeCompilerArgs += "-opt-in=org.mylibrary.OptInAnnotation"
}
Option #2 - using sourceSet
Copy code
sourceSets {
    all {
        languageSettings.optIn("org.mylibrary.OptInAnnotation")
    }
}
Please vote and leave your WHY in thread. Thanks
2️⃣ 6
🤔 1
1️⃣ 6
0️⃣ 8
I mostly like second because it's easy to read. It feels like more declarations, so i don't need to think in what moment it will be run or smth else. Also, I don't need to learn something about
task
and how to use it properly.
g
I vote for none of the options. Of course both should be supported, but the default option should be possible to configure using kotlin plugin extension: kotlin { compiler { freeCompilerArgs += “-opt-in=org.mylibrary.OptInAnnotation” } }
👍 16
s
I prefer the first because it doesnt feel like it should be part of
sourceSets
, I generally think of them as/use them for only handling source locations etc rather than configuring language aspects, but I would prefer to do more than just concating strings for compiler args. I could understand the second if you wanted to only apply certain language settings to certain sourcesets, but dont have a nice solution in mind to do it another way, nor do I know how common that use case even is, id probably end up making a subproject instead
a
I also agree with @gildor
g
it’s true for all options for Kotlin plugin I think usability of Kotlin plugin is affected a lot by the fact that there is no way to configure all default options using plugin extension. I think it goes against modern Gradle practices. Individual task should be configured only for some custom configs, and never as default way to configure things, even big projects usually want to set default value on level of extension, and only adjust some custom stuff
But I also probably would say that way to configure optIn only would be nice, like: kotlin { languageSettings.optInt += “org.mylibrary.OptInAnnotation” } But I think it’s a minor change comparing to general paradigm, that all settings should be available on level of plugin extension
👍 6
j
I like this last one from Andrew
e
1. thanks for the comments 2. survivor's mistake detected. You all are quite experienced folks. Would you be mind to create the same slack-survey in your company to get feedback not only form seniors, but jun/middle developers? It's very important to fit newcomers expectations, hope you can understand me) 3. Interesting topic about config sourceSet vs config from plugin. On a one hand I thinks some sourceSet have to have specific settings to run, however it may create some obstacles if we'd like to reuse such sources in other project. Any ideas here?
m
Option #2 feels super weird to me as a Kotlin compilation unit is different from a sourceSet, right? I would expect that compiling JVM classes uses both the
jvmMain
and
commonMain
sourceSets so if I have conflicting compiler options there, I don't know how they're going to be resolved.
Or is there actually a separate compiler invocation for each source set?
@Eugene the more I think about it, the more I'm confused about why it makes sense to set compiler params on SourceSets. The same with dependencies actually. If I have 2 SourceSets "jvmMain" and "jvmExtra" that are compiled together, how does IntelliJ knows that "jvmExtra" has access to all the dependencies from "jvmMain" and vice versa ?
It gets even more weird if the same SourceSet is included in different compilation units with different dependencies. Ctrl-clicking can lead to two possible destinations in these cases...
Do you have more insight about how this stuff work and if the above is supported/will be in the future?
d
Fair disclcaimer: some pretty advanced nitty-gritty details below (you’ll like it, Martin, I know 😁 ) That’s a very good (and a very advanced!) observation that currently the compilation unit is different from one source-set 🙂 Knowing this is especially commendable because we try to avoid directly mentioning it — and yeah, we try to hide it as “implementation detail” exactly because it was never meant to be an ideal solution for the Kotlin Of The Future. Actually, you can see that even know this approach is flawed. Yes, indeed, currently Kotlin Compiler compiles
commonMain
together with
jvmMain
. So it might seem that compiler options for
commonMain
are redundant and/or unnatural But then you have an IDE, which does analyze
commonMain
on its own. Should usages of
OptIn
be allowed there? What if JVM-compilation and JS-compilation declare different sets of OptIns? (or any other compiler options, for that matter)? (actually, even now we compile common source sets alone into .kotlin_metadata for our internal technical purposes of helping IDE further, but that’s probably can be seen as implementation detail) Moreover, in future we’d like to turn source sets a proper compilation unit in Kotlin.
commonMain
would be compiled into
.klib
(pure-Kotlin format of distributing Kotlin code) and then used as a dependency during compilation of
jvmMain
. This brings a lot of nice things, like an ability to distribute your pure-Kotlin library as just common-code, leaving consumers ability to link it to any supported platform. In such future, Kotlin Options will have to be declared on source sets. And as you’ve correctly mentioned, they should obey some consistency rules. For example, it’s obvious that if some language feature, like
InlineClasses
is enabled in
commonMain
, it can’t be disabled in
jvmMain
(how the hell
jvmMain
would be supposed to read
commonMain.klib
?). Of course, we will make sure that our tooling checks for those rules, points to violations and explains what you should do instead.
❤️ 3
😁 2
👍 3
This thread is also very helpful to us in that regard (thanks to everyone responded!), because we do see and hear that declaring kotlin options for source sets seems unnatural — and I definitely can get behind that! So, it shows that in Kotlin team we should think how we can either make such change look more natural, or communicate it very clear at the very least. We will keep that in mind!
m
Thanks for the insights! That makes a lot of sense 👍 . If the future is to compile each sourceSet differently separately then I think it's perfectly ok to set the compiler options on SourceSets.
Maybe just add a top-level global way to set options? Maybe the suggestion from @gildor
Copy code
kotlin {
   languageSettings.optInt += "org.mylibrary.OptInAnnotation"
}
that would this under the hood:
Copy code
sourceSets.all {
   languageSettings.optInt += "org.mylibrary.OptInAnnotation"
}
Or maybe some documentation is enough. I think what is also surprising is that some of the API uses compiler flags (
freeCompilerArgs
) while other seem to wrap them in user-friendly APIs (
languageSettings.optIn(...)
). I'd prefer if there'd be only one way to do it. Either string flags or more strongly typed APIs but the mix seems arbitrary there
d
Yep, and I think that’s a perfect point about configuring defaults. Can’t guarantee anything about particular DSL (don’t get me wrong, I like the suggestions here, but “I like it” isn’t enough when designing DSLs 🙂 ), but we’ll definitely try to tackle the mentioned problem itself.
💯 1
👍 2
g
I also think a general way outside of source sets would be good to have. In AGP you have
defaultConfig
to set your general options and then you can override that in specific flavors/buildTypes/variants if needed.
3