ArchUnit
ArchUnit copied to clipboard
Support for Kotlin toplevel functions
@clojj I took the liberty of creating a new issue for this, since I don't think it matches the other issue title very well
Hi, I am using ArchUnit with Kotlin and I would like an easy way of addressing top-level functions, which are seen by AU right now as methods of the Kotlin-compiler-generated Class named like the containing File (someFile.kt will generate Class "SomeFileKt").
One can work around this by querying JavaClass about the sourcefile etc., but it's a bit awkward. In the end, especially when doing functional programming, I'd like an API like:
ArchRuleDefinition.functions().that()
.areAnnotatedWith(WhatEver::class.java)
.should().resideInAPackage("com.ddd.service")
where "functions()" obviously means "Kotlin toplevel functions". As for the Java-compatibility: functions() could of course return nothing... or could be named "kotlinFunctions()"
Thanks for raising this! I could imagine this to be useful, but I would not put it into the general rule API, because either "functions" that really means "Kotlin toplevel functions" or kotlinFunctions() feels like a way too specific thing to have in the general API (and calling it only "functions" would be utterly confusing for all non-Kotlin users).
To me it feels like the clean thing would be an artifact archunit-kotlin to support something like this, only that it feels like a lot of overhead at the moment for only one rule syntax element :thinking:
Other than that, are you sure toplevel functions are actually distinguishable from methods? I'm just wondering, if I create a class
ExampleKt.kt
--------
class ExampleKt {
fun actuallyAMethod() {...}
}
Can I then distinguish actuallyAMethod from this Kotlin file?
example.kt
--------
fun actuallyAMethod() {...}
Or would this have to rely on a pure naming convention :thinking:
Example decompilation of Kotlin file Example.kt:
package some.pkg
class Example {
fun exampleMethod() {}
}
fun exampleMethodTopLevel() {}
is (with metadata omitted):
package some.pkg;
public final class Example {
public final void exampleMethod() {
}
}
// ExampleKt.java
package some.pkg;
public final class ExampleKt {
public static final void exampleMethodTopLevel() {
}
}
Yes, but what if I also create in Java
class ExampleKt {
public static final void iJustLookToplevel() {
}
}
:wink: So eventually that is a naming convention, no? I wonder if there are any other signs in the bytecode :thinking: