JetBrains-Research / reflekt

A plugin for Kotlin compiler for compile-time reflection
Apache License 2.0
363 stars 11 forks source link

Consider replacing `KClass` with custom information class as DSL result #112

Closed CommanderTvis closed 2 years ago

CommanderTvis commented 2 years ago

The idea is that WithX.toList should return not a KClass, which assumes further runtime reflection, but an information class storing all the information about the class available to Reflekt plus the old KClass reference.

This is particularly useful to implement #71, because actually KClass has the sealedSubclasses property that does that thing; however, this data can be collected at compile time, and it's helpful in cases where run-time reflection isn't available or too slow.

Rough API:

class ReflektClass<T> {
  val kotlin: KClass<T>
  val qualifiledName: String
  val simpleName: String
  val sealedSubclasses: List<ReflektClass<*>>
  val isOpen: Boolean
  ...
}

Possible usage:

Reflekt.classes().withSuperType<B1>().toList().map { /* it: ReflektClass<B1> */ it.qualifiedName }.forEach { println(it) }

Also, to not bloat the ReflektImpl file, there must be a registry of such classes to have them available in many DSL calls simultaneously (basically, val classData: HashMap<String, ReflektClass<*>>).

nbirillo commented 2 years ago

Hm.. it looks great, but I have to think about the case with ReflektImpl - Do we really can store such classes in the case of the library. I will answer a little bit later. But maybe do you have some ideas?

nbirillo commented 2 years ago

Also, I can add some details about the case with ReflektImpl if you want

CommanderTvis commented 2 years ago

I'm quite sure it should be placed into ReflektImpl somehow.

CommanderTvis commented 2 years ago

Hm.. it looks great, but I have to think about the case with ReflektImpl - Do we really can store such classes in the case of the library. I will answer a little bit later. But maybe do you have some ideas?

You mean creating a class registry may cause problems with library's API compatibility?

nbirillo commented 2 years ago

I am about a case where we don't replace IR and generate ReflektImpl with query results, e.g. if we have a library A with reflekt queries and a project B that uses A and we want to use entities from B in the queries from A. But I have checked this case, I think it is ok and we can replace it.

btw we are going to add some wrappers for the internal classes for SmartReflekt queries, I think we should create a universal wrapper for the both cases

CommanderTvis commented 2 years ago

the internal classes for SmartReflekt queries

For example?

nbirillo commented 2 years ago

We use KtObjectDeclaration in lamda bodies to access its fields, next we run KotlinScript. In this case, we would like to use our wrappers and don't use some internal compiler classes

nbirillo commented 2 years ago

Next, we should make the same for objects and functions