ArchUnit icon indicating copy to clipboard operation
ArchUnit copied to clipboard

Support for Kotlin toplevel functions

Open codecholeric opened this issue 4 years ago • 3 comments

@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()"

codecholeric avatar Feb 14 '21 15:02 codecholeric

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:

codecholeric avatar Feb 14 '21 15:02 codecholeric

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() {
   }
}

v3rm0n avatar Mar 23 '21 11:03 v3rm0n

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:

codecholeric avatar May 24 '21 19:05 codecholeric