How to get the file path and line number where a method is defined?

Hi! I am generating the documentation for a framework and I would like to obtain the file path and the line number where a method is defined. Then I can have in markdown something like [Read more about opacify](https://github.com/openrndr/openrndr/blob/master/openrndr-color/src/commonMain/kotlin/org/openrndr/color/ColorRGBa.kt#L157)

Basically, I want to programmatically recreate what happens when you ctrl+click any symbol in IntelliJ Idea, so I can then link method names to github URLs including line numbers.

I could do it manually, but it would be tedious to verify if links are up to date after any changes to the source.

// possible signature
fun fqnToPathAndLineNumber(fqn: String): Pair<String, Int> {
  // hardcoded example result...
  val calculatedPath = "openrndr-color/src/commonMain/kotlin/org/openrndr/color/ColorRGBa.kt"
  val calculatedLineNumber = 157
  return Pair(calculatedPath, calculatedLineNumber)
}

println(fqnToPathAndLineNumber("org.openrndr.color.ColorRGBa.WHITE.opacify"))

Any suggestions?

But how do you access and analyze the code? Do you analyze built jar files, source code or maybe Kotlin IR? Do you use some static analysis framework, do you load the jar file using a class loader or do you use some other technique of code analysis?

Thank you, good questions. They make me see the issue a bit clearer.

First I thought that the jar dependencies added to the project were enough, but now I realize that white space and comments would be missing, so decompilation of the jar dependencies is not enough to figure out precise line numbers, I need a local copy of the repository.

Instead of taking the fqn as an argument as I planned above, I will:

  • have the HEAD of the source repo cloned with --depth=1 as part of the build process
  • my function will look more like:
fun findLineNumber(ktFilePath: String, query: String): Int { ... }
...
findLineNumber("openrndr-color/src/commonMain/kotlin/org/openrndr/color/ColorRGBa.kt", 
               "fun opacify")
  • it will search in the provided file in the cloned repo.
    • If the file is not present, or if query is not found exactly 1 time the build will fail requiring me to look into it.
    • On success it wil return the line number then used create a URL to the correct file and line number in GitHub.

This way those URLs in the documentation stay up to date. If the source file is modified, the line number in the URL is updated automatically. If the source file is renamed, build fails until the updated name is provided in the findLineNumber call.