Skip to content

Commit

Permalink
dev: Add better compile-time diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
Iltotore committed May 5, 2024
1 parent 9c114fe commit adb7c99
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.github.iltotore.iron.internal

import scala.quoted.*

enum DecodingFailure:
case Unknown
case NotInlined(term: Term)
case HasRuntimeBindings(bindings: List[Quotes.reflectModule.Definition])(using Quotes)
case HasStatements(statements: List[quotes.reflect.Statement])(using Quotes)
32 changes: 32 additions & 0 deletions main/src/io/github/iltotore/iron/internal/ExprDecoder.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.github.iltotore.iron.internal

import io.github.iltotore.iron.compileTime.NumConstant
import scala.quoted.*

trait ExprDecoder[T]:

def decode(expr: Expr[T])(using Quotes): Either[DecodingFailure, T]

object ExprDecoder:

given [T](using fromExpr: FromExpr[T]): ExprDecoder[T] with

override def decode(expr: Expr[T])(using Quotes): Either[DecodingFailure, T] =
fromExpr.unapply(expr).toRight(DecodingFailure.Unknown)

private class PrimitiveExprDecoder[T <: NumConstant | Byte | Short | Boolean | String] extends ExprDecoder[T]:

override def decode(expr: Expr[T])(using Quotes): Either[DecodingFailure, T] =
import quotes.reflect.*

def rec(tree: Term): Either[DecodingFailure, T] = tree match
case Block(stats, e) => if stats.isEmpty then rec(e) else Left(DecodingFailure.HasStatements(stats))
case Inlined(_, bindings, e) => if bindings.isEmpty then rec(e) else Left(DecodingFailure.HasRuntimeBindings(bindings))
case Typed(e, _) => rec(e)
case Ident(name) => Left(DecodingFailure.NotInlined(Symbol()))
case _ =>
tree.tpe.widenTermRefByName match
case ConstantType(c) => Right(c.value.asInstanceOf[T])
case _ => Left(DecodingFailure.Unknown)

rec(expr.asTerm)

0 comments on commit adb7c99

Please sign in to comment.