All Downloads are FREE. Search and download functionalities are using the official Maven repository.

arrow.meta.plugins.proofs.phases.Proof.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0-alpha.6
Show newest version
package arrow.meta.plugins.proofs.phases

import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.types.KotlinType

sealed class Proof(open val to: KotlinType, open val through: DeclarationDescriptor) {

  inline fun  fold(given: GivenProof.() -> A): A =
    when (this) {
      is GivenProof -> given(this)
    }

  abstract fun isContextAmbiguous(other: Proof): Boolean
}

sealed class GivenProof(override val to: KotlinType, override val through: DeclarationDescriptor) :
  Proof(to, through) {
  abstract val callableDescriptor: CallableDescriptor
  val contexts: Set
    get() = through.contextualAnnotations()
  override fun isContextAmbiguous(other: Proof): Boolean =
    other is GivenProof && contexts == other.contexts
}

data class ClassProof(override val to: KotlinType, override val through: ClassDescriptor) :
  GivenProof(to, through) {
  override val callableDescriptor: CallableDescriptor
    get() =
      through.unsubstitutedPrimaryConstructor ?: TODO("no primary constructor for ${through.name}")
}

data class ObjectProof(override val to: KotlinType, override val through: ClassDescriptor) :
  GivenProof(to, through) {
  override val callableDescriptor: CallableDescriptor
    get() = FakeCallableDescriptorForObject(through)
}

data class CallableMemberProof(
  override val to: KotlinType,
  override val through: CallableMemberDescriptor
) : GivenProof(to, through) {
  override val callableDescriptor: CallableDescriptor
    get() = through
}

fun DeclarationDescriptor.contextualAnnotations(): Set =
  annotations.mapNotNull { if (it.isGivenContextProof()) it.fqName else null }.toSet()

fun DeclarationDescriptor.asProof(): Sequence =
  when (this) {
    is PropertyDescriptor -> asProof()
    is ClassConstructorDescriptor -> containingDeclaration.asProof()
    is FunctionDescriptor -> asProof()
    is ClassDescriptor -> asProof()
    is FakeCallableDescriptorForObject -> classDescriptor.asProof()
    else -> emptySequence()
  }

fun AnnotationDescriptor.isGivenContextProof(): Boolean =
  type.constructor.declarationDescriptor?.annotations?.hasAnnotation(FqName("arrow.Context")) ==
    true

fun ClassDescriptor.asProof(): Sequence =
  annotations.asSequence().mapNotNull {
    when {
      it.isGivenContextProof() -> asGivenProof()
      else -> TODO("asProof: Unsupported proof declaration type: $this")
    }
  }

fun PropertyDescriptor.asProof(): Sequence =
  annotations.asSequence().mapNotNull {
    when {
      it.isGivenContextProof() -> if (!isExtension) asGivenProof() else null
      else -> TODO("asProof: Unsupported proof declaration type: $this")
    }
  }

fun FunctionDescriptor.asProof(): Sequence =
  annotations.asSequence().mapNotNull {
    when {
      it.isGivenContextProof() -> if (!isExtension) asGivenProof() else null
      else -> TODO("asProof: Unsupported proof declaration type: $this")
    }
  }

internal fun ClassDescriptor.asGivenProof(): GivenProof =
  if (kind == ClassKind.OBJECT) ObjectProof(defaultType, this) else ClassProof(defaultType, this)

internal fun CallableMemberDescriptor.asGivenProof(): GivenProof? =
  returnType?.let { CallableMemberProof(it, this) }

data class ProofsCache(val proofs: List)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy