Skip to content
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

Support for Kotlin toplevel functions #528

Open
codecholeric opened this issue Feb 14, 2021 · 3 comments
Open

Support for Kotlin toplevel functions #528

codecholeric opened this issue Feb 14, 2021 · 3 comments

Comments

@codecholeric
Copy link
Collaborator

codecholeric commented Feb 14, 2021

@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
Copy link
Collaborator Author

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 🤔

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 🤔

@v3rm0n
Copy link

v3rm0n commented Mar 23, 2021

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

@codecholeric
Copy link
Collaborator Author

Yes, but what if I also create in Java

class ExampleKt {
  public static final void iJustLookToplevel() {
  }
}

😉 So eventually that is a naming convention, no? I wonder if there are any other signs in the bytecode 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants