Is there any standard regarding file naming for KM...
# multiplatform
s
Is there any standard regarding file naming for KMP projects? I’ve seen that for example inside androidx, for compose which provides common/android/desktop support, like here, for example for the android target of material3, they have some (most in this case) files named like “[filename].android.kt” and others just “[filename].kt”. I did check, and it’s not only the ones that do also have a identically named file in the common target, as for example “DatePickerDialog.android.kt” only exists for the android target and is not present in the common directory to require the .android disambiguation there. Yet “SearchBar.kt” doesn’t have it, which is also android-only. And it’s also not that
DatePickerDialog
has any expect/actual keywords or whatnot. So I guess my question is, I’ve seen this “[filename].[platformname].kt” naming convention, but is it specified somewhere how the decision to add the [platformname] is made?
j
It's only needed for the JVM/Android because of the concept of a
.class
and the inability to produce duplicate names. And it's only required when you have the same-named files in common and a jvm or android source set AND those files have top-level declarations (i.e., will produce a classfile with the name
FilenameKt.class
.
I would not pervasively adopt such a system but rather employ it only when necessary. And the easiest way to employ it is only in those jvm or android source sets and only when there is a collision which fails the build.
s
Perfect, so what you are saying is that if there is a problem to be had, I will know in compile-time regardless. Does one need to do something special to bring those collisions to the surface and have the build fail, or will it just happen, in which case I will know that this is the solution?
j
You will see something like this:
Copy code
> Task :mosaic-runtime:compileKotlinJvm FAILED
e: file:///Volumes/dev/JakeWharton/mosaic/mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/platform.kt:1:1 Duplicate JVM class name 'com/jakewharton/mosaic/PlatformKt' generated from: PlatformKt, PlatformKt
e: file:///Volumes/dev/JakeWharton/mosaic/mosaic-runtime/src/jvmMain/kotlin/com/jakewharton/mosaic/platform.kt:1:1 Duplicate JVM class name 'com/jakewharton/mosaic/PlatformKt' generated from: PlatformKt, PlatformKt
The conditions when it happens are even more rare than I stated. You can actually have top-level declarations in both files if they are all `expect`/`actual`.
s
Awesome, thank you a lot for making this make sense for me! So as I am understanding, a lot of these .android. in particular in that m3 file are not actually necessary. But they may be doing it out of convention at this point. For our project, I will simply not do it unless we need to, sounds like a sensible solution for now.
l
iOS also required this if there were any files with a matching name at all when using the compose-jb main method, since that would copy files to the resulting binary. If two had the same name, XCode would fail the build.
I’m not sure if this is still the case, as I switched to cocoapods and an XCode project instead of using the compose-jb packaging.
c
At least for the JVM, another solution than renaming the file is to add
@file:JvmName("FileNameJvm")
at the start of the file. Not sure if it works for Android
j
It does. All of Android goes through class files the same as the JVM.
l
Excluding androidNative* targets, of course.
e
Despite not needing to do it, I've been naming my files like that because it conveys meaning to what the file is
l
It also makes it much easier to figure out which file is which platform when making expect/actuals. A lot of times, I have to scroll up to the top to find imports. When the file is Foo.android.kt, I can easily see.
j
The source set folder conveys the meaning of what target the platform is for. If you are always going to suffix the file then put them all in a single folder and use globs to assign them to target source sets. Otherwise are redundantly specifying the intended platform.
e
I usually search to open files, and the file extension is easier to eyeball than the source set folder
l
I find that the little tab doesn’t always show the source set for repeat files, especially if the files with the same name have a slightly different folder structure.
Also, search. That font they use for the source set/module name gets hard to see with my less than great vision.
j
You should turn off tabs! In the latest IntelliJ I get both the source set name and the file name in the top bar.
l
That’s what I was referring to. If the folder structure doesn’t match, you see the last difference, such as foo/blocking.kt and bar/blocking.kt instead of androidMain/blocking.kt and commonMain/blocking.kt. One could argue that the folder structures should match, but that doesn’t make sense in 100% of situations.
j
That seems like useful feedback for the IntelilJ team. The source set is probably important enough to always be displayed whenever there are multiple source set folders in use.
162 Views