-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#49 adds extension functions module #53
Conversation
@morki I think that makes sense, yeah. Thank you for already doing so, and thank you for your contribution! |
This looks like a good start but I think we need more documentation in the user guide and also I would restructure the extensions so that they are not all in As more extensions are built this kind of organization will become important IMO |
That's definitely doable @graemerocher , I will get on that! |
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.10.2", { | ||
exclude group:"org.jetbrains.kotlin", module:'kotlin-reflect' | ||
} | ||
implementation "io.micronaut:micronaut-inject:$micronautVersion" | ||
implementation "io.micronaut:micronaut-runtime:$micronautVersion" | ||
implementation "io.micronaut:micronaut-http-server:$micronautVersion" | ||
implementation "io.micronaut:micronaut-http-client:$micronautVersion" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding this module will add all of these dependencies on the runtime classpath of applications that use them. I don't think we can safely assume users want runtime, http-server, or http-client. What can be done to only enable the extensions if the dependency is present?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super familiar with all the various gradle lifecycle configurations for dependencies; is there a alternative to implementation
(and something corresponding in source?) to mark classes to be optionally loaded only if something they depend on is present? Perhaps that's possible, I'm not sure, but I don't think I've heard of such a thing.
Alternatively, I could separate the extensions for those modules into corresponding kotlin modules (like having a micronaut-runtime-kotlin-ext
subproject, a micronaut-http-client-kotlin-ext
subproject, etc).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a alternative to implementation (and something corresponding in source?) to mark classes to be optionally loaded only if something they depend on is present?
I think what you want is compileOnly
. It will allow the code to compile but will not load these dependencies at runtime, allowing users to optionally include them on their project's dependencies. More info here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@edrd-f Yes, however I don't know how Kotlin handles extension classes for classes that aren't on the classpath. If it simply ignores them then great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jameskleeh did a test now. It compiles and at runtime behaves just like Java: NoClassDefFoundError
, which makes sense since it's not possible to get an instance of the class prior to the extension call.
Will try to review soon |
Any progress here? :) |
@jameskleeh @willbuck is there anything blocking? |
@morki I've been assigned to working on other things lately, apologies for the late reply; I think the hangup was around making sure there was a way to not require I've tried out something that might accomplish the former, but need to double check @edrd-f 's assertion that this will not damage dependent apps, and also confer w/ the team that the |
Hi @willbuck. Sorry for not giving more info on my previous comment. Extension functions are compiled to static functions, receiving the instance of the extended type as first argument. So, for example: Main.ktfun String.removeSpaces(): String {
return this.replace(" ", "")
} Will produce a bytecode that when decompiled to Java looks like: @Metadata(...)
public final class MainKt {
@NotNull
public static final String removeSpaces(@NotNull String $this$removeSpaces) {
Intrinsics.checkParameterIsNotNull($this$removeSpaces, "$this$removeSpaces");
return StringsKt.replace$default($this$removeSpaces, " ", "", false, 4, (Object)null);
}
} As you can see, it's a new class, not a modification of the original class' bytecode. In this case, since the extended type is received as argument, if it's not present in the classpath at runtime, a |
@edrd-f @morki @jameskleeh Did my latest commit address the primary concerns around merging this new module, so we can provide these extension functions to folks? |
@willbuck for me this is ok, but I didn't have any concerns, I would just love to use those functions, thank you very much for your work :) |
Looks good to me. And by the way, great work! |
No description provided.