Skip to content

Commit

Permalink
Improve bad selector error messages a bit, add some docs to originalSrc
Browse files Browse the repository at this point in the history
  • Loading branch information
MateuszKubuszok committed Nov 5, 2023
1 parent 81cc8d9 commit 4921258
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ private[chimney] trait DslMacroUtils {
type Underlying = runtime.Path.Root
val Underlying: WeakTypeTag[runtime.Path.Root] = weakTypeTag[runtime.Path.Root]
})
case _: Ident =>
Left(invalidSelectorErrorMessage(t)) // TODO: error for foo => bar.fieldName
case _: Ident => Left(ignoringInputNotAllowed(t))
case Apply(select @ Select(_, _), Nil) => unpackSelects(select)
case Apply(_, _) => Left(arbitraryFunctionNotAllowed(t))
case Select(t2, fieldName: TermName) =>
unpackSelects(t2).map { instance =>
val name = ExistentialString(fieldName)
Expand All @@ -68,7 +68,14 @@ private[chimney] trait DslMacroUtils {
case _ => Left(invalidSelectorErrorMessage(t))
}

private def invalidSelectorErrorMessage(selectorTree: Tree): String = s"Invalid selector expression: $selectorTree"
private def invalidSelectorErrorMessage(selectorTree: Tree): String =
s"Invalid selector expression: $selectorTree"

private def arbitraryFunctionNotAllowed(selectorTree: Tree): String =
s"Invalid selector expression - only vals, and nullary defs allowed: $selectorTree"

private def ignoringInputNotAllowed(selectorTree: Tree): String =
s"Invalid selector expression - only input value can be extracted from: $selectorTree"
}

// If we try to do:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,14 @@ private[chimney] class DslMacroUtils()(using quotes: Quotes) {
"msg=the type test for DslMacroUtils.this.quotes.reflect.ValDef cannot be checked at runtime because it refers to an abstract type member or type parameter"
)
def parse(t: Tree): Either[String, ExistentialPath] = t match {
// Block(List(DefDef("$anonfun", List(TermParamClause(List(ValDef("_$50", Inferred(), None)))), Inferred(), Some(Apply(Select(Ident("_$50"), "baz1"), Nil)))), Closure(Ident("$anonfun"), None))
case Block(List(DefDef(_, List(List(ValDef(in, _, _))), _, Some(selects))), _) =>
def unpackSelects(selects: Tree): Either[String, ExistentialPath] = selects match {
case Ident(out) if in == out =>
Right(new ExistentialPath {
type Underlying = runtime.Path.Root
val Underlying: Type[runtime.Path.Root] = Type.of[runtime.Path.Root]
})
case _: Ident =>
Left(invalidSelectorErrorMessage(t)) // TODO: error for foo => bar.fieldName
case _: Ident => Left(ignoringInputNotAllowed(t))
case SelectLike(t2, fieldName) =>
unpackSelects(t2).map { instance =>
val name = ExistentialString(fieldName)
Expand All @@ -61,7 +59,8 @@ private[chimney] class DslMacroUtils()(using quotes: Quotes) {
Type.of[runtime.Path.Select[FieldName, Instance]]
}
}
case _ => Left(invalidSelectorErrorMessage(t))
case Apply(_, _) => Left(arbitraryFunctionNotAllowed(t))
case _ => Left(invalidSelectorErrorMessage(t))
}
unpackSelects(selects)
case Inlined(_, _, block) => parse(block)
Expand All @@ -70,6 +69,12 @@ private[chimney] class DslMacroUtils()(using quotes: Quotes) {

private def invalidSelectorErrorMessage(t: Tree): String =
s"Invalid selector expression: ${t.show(using Printer.TreeAnsiCode)}"

private def arbitraryFunctionNotAllowed(t: Tree): String =
s"Invalid selector expression - only vals, and nullary defs allowed: ${t.show(using Printer.TreeAnsiCode)}"

private def ignoringInputNotAllowed(t: Tree): String =
s"Invalid selector expression - only input value can be extracted from: ${t.show(using Printer.TreeAnsiCode)}"
}

def applyFieldNameType[Out](f: [A <: runtime.Path] => Type[A] ?=> Out)(selector: Expr[?]): Out =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ private[compiletime] trait Contexts { this: Derivation =>
val From: Type[From]
val To: Type[To]

/** When using nested paths (_.foo.bar.baz) and recursive derivation this is the original, "top-level" value */
val originalSrc: ExistentialExpr
val runtimeDataStore: Expr[TransformerDefinitionCommons.RuntimeDataStore]
val config: TransformerConfig
Expand Down

0 comments on commit 4921258

Please sign in to comment.