kotlin-power-assert icon indicating copy to clipboard operation
kotlin-power-assert copied to clipboard

Experiment with dynamic call origin information

Open bnorm opened this issue 2 years ago • 5 comments

Experimenting with what an annotation driven form of kotlin-power-assert would look like, and what form the data structure would take for getting call source information.

@OptIn(ExperimentalContracts::class)
@Introspected
fun assertTrue(condition: Boolean, message: String? = null) {
  contract {
    returns() implies condition
  }

  if (!condition) {
    val diagram = CallOrigin.get()?.toSimpleDiagram()
    val errorMessage = when {
      message == null -> diagram
      diagram != null -> "$message:\n$diagram"
      else -> null
    }
    throw AssertionError(errorMessage)
  }
}

// Compiler plugin should generate the following function:

@JvmSynthetic
internal fun assertTrue__introspected(condition: Boolean, message: String? = null, callOrigin: CallOrigin) {
  if (!condition) {
    val diagram = callOrigin?.toSimpleDiagram() // CallOrigin.get() replaced with `callOrigin` parameter
    val errorMessage = when {
      message == null -> diagram
      diagram != null -> "$message:\n$diagram"
      else -> null
    }
    throw AssertionError(errorMessage)
  }
}

Goal is to handle as much boiler-plate as possible and not exposing the mechanics of how call-site information is passed. This also hopefully means that libraries which have @Introspected functions would only need to include the support library as a compileOnly dependency, since any calling code would also need to include the compiler plugin anyways.

bnorm avatar Apr 06 '23 13:04 bnorm

looks good. what do you think of a different name for @Introspected, which seems very generic. I like @Empowered

christophsturm avatar Apr 08 '23 08:04 christophsturm

Or keep it close to the lib... @PowerAssert?

TWiStErRob avatar Apr 08 '23 09:04 TWiStErRob

I've been thinking about renaming this repository for a while since it is starting to handle so many use-cases outside of just asserts. Especially with this new annotation driven stuff, I see it as a chance to do some rebranding. So I'm hesitant to go with @PowerAssert.

I do like @Empowered, though. Fits with the power-assert name most people know this functionality under from various languages. It may be a good enough name to eventually rebrand the entire repository under as well.

But nothing is set in stone yet; naming ideas are very welcome for everything related to this PR!

bnorm avatar Apr 09 '23 16:04 bnorm

what about merging this to master and releasing it as an experimental feature for people to play with it? as far as i can see it should not interfere with the current stable functionality.

christophsturm avatar Apr 24 '23 10:04 christophsturm

what about merging this to master and releasing it as an experimental feature for people to play with it? as far as i can see it should not interfere with the current stable functionality.

I plan to do that, but right now I've only created the constructs people will use and not implemented anything on the compiler plugin side of things yet. Still lots of work to do before this is useable.

bnorm avatar Apr 24 '23 14:04 bnorm