scala.reflect.macros.TypecheckException Scala Examples
The following examples show how to use scala.reflect.macros.TypecheckException.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: Macro.scala From monadless with Apache License 2.0 | 5 votes |
package io.monadless.impl import language.higherKinds import scala.reflect.macros.blackbox.Context import scala.reflect.macros.TypecheckException private[monadless] class Macro(val c: Context) { import c.universe._ def lift[M[_], T](body: Expr[T])(implicit m: WeakTypeTag[M[_]]): Tree = { val tree = Transformer[M](c)(body.tree) Trees.traverse(c)(tree) { case tree @ q"$pack.unlift[$t]($v)" => c.error(tree.pos, "Unsupported unlift position") } try c.typecheck(tree) catch { case e: TypecheckException => val msg = s"""Can't typecheck the monadless transformation. Please file a bug report with this error and your `Monadless` instance. |Failure: ${e.msg} |Tree: $tree""".stripMargin c.abort(c.enclosingPosition, msg) } } }
Example 2
Source File: TestSupport.scala From monadless with Apache License 2.0 | 5 votes |
package io.monadless.impl import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context import org.scalamacros.resetallattrs._ import language.higherKinds import scala.reflect.macros.TypecheckException private[monadless] trait TestSupport[M[_]] { def get[T](m: M[T]): T def showTree[T](t: T): Unit = macro TestSupportMacro.showTree def showRawTree[T](t: T): Unit = macro TestSupportMacro.showRawTree def forceLift[T](t: T): T = macro TestSupportMacro.forceLift def runLiftTest[T](expected: T)(body: T): Unit = macro TestSupportMacro.runLiftTest[M, T] } private[monadless] class TestSupportMacro(val c: Context) { import c.universe._ def showTree(t: Tree): Tree = { c.warning(c.enclosingPosition, t.toString) q"()" } def showRawTree(t: Tree): Tree = { c.warning(c.enclosingPosition, showRaw(t)) q"()" } def forceLift(t: Tree): Tree = c.resetAllAttrs { Trees.Transform(c)(t) { case q"$pack.unlift[$t]($v)" => q"${c.prefix}.get($v)" } } def runLiftTest[M[_], T](expected: Tree)(body: Tree): Tree = c.resetAllAttrs { val lifted = q"${c.prefix}.get(${c.prefix}.lift($body))" val forceLifted = forceLift(body) q""" val expected = scala.util.Try($expected) assert(expected == ${typecheckToTry(lifted, "lifted")}) assert(expected == ${typecheckToTry(forceLifted, "force lifted")}) () """ } def typecheckToTry(tree: Tree, name: String): Tree = { try { val typeCheckedTree = c.typecheck(c.resetAllAttrs(tree)) c.info(c.enclosingPosition, s"$name: $typeCheckedTree", force = false) q"scala.util.Try($typeCheckedTree)" } catch { case e: TypecheckException => val msg = s""" |$name fails typechecking: $e |tree: $tree |""".stripMargin c.info(e.pos.asInstanceOf[Position], msg, force = true) q"""scala.util.Failure(new Exception($msg))""" } } }
Example 3
Source File: TestMacros.scala From udash-core with Apache License 2.0 | 5 votes |
package io.udash package macros import com.avsystem.commons.macros.AbstractMacroCommons import scala.reflect.macros.{TypecheckException, blackbox} class TestMacros(val ctx: blackbox.Context) extends AbstractMacroCommons(ctx) { import c.universe._ private def stringLiteral(tree: Tree): String = tree match { case StringLiteral(str) => str case Select(StringLiteral(str), TermName("stripMargin")) => str.stripMargin case _ => abort(s"expected string literal, got $tree") } def typeErrorImpl(code: Tree): Tree = { val codeTree = c.parse(stringLiteral(code)) try { c.typecheck(codeTree) abort("expected typechecking error, none was raised") } catch { case TypecheckException(_, msg) => q"$msg" } } }
Example 4
Source File: Macros.scala From zio with Apache License 2.0 | 5 votes |
package zio.test import scala.reflect.macros.TypecheckException import scala.reflect.macros.blackbox.Context import zio.UIO private[test] object Macros { def typeCheck_impl(c: Context)(code: c.Expr[String]): c.Expr[UIO[Either[String, Unit]]] = { import c.universe._ try { c.typecheck(c.parse(c.eval(c.Expr[String](c.untypecheck(code.tree))))) c.Expr(q"zio.UIO.succeed(Right(()))") } catch { case e: TypecheckException => c.Expr(q"zio.UIO.succeed(Left(${e.getMessage}))") case t: Throwable => c.Expr(q"""zio.UIO.die(new RuntimeException("Compilation failed: " + ${t.getMessage}))""") } } }
Example 5
Source File: typechecking.scala From perf_tester with Apache License 2.0 | 5 votes |
package shapeless.test import scala.language.experimental.macros import java.util.regex.Pattern import scala.reflect.macros.{ whitebox, ParseException, TypecheckException } object illTyped { def apply(code: String): Unit = macro IllTypedMacros.applyImplNoExp def apply(code: String, expected: String): Unit = macro IllTypedMacros.applyImpl } @macrocompat.bundle class IllTypedMacros(val c: whitebox.Context) { import c.universe._ def applyImplNoExp(code: Tree): Tree = applyImpl(code, null) def applyImpl(code: Tree, expected: Tree): Tree = { val Literal(Constant(codeStr: String)) = code val (expPat, expMsg) = expected match { case null => (null, "Expected some error.") case Literal(Constant(s: String)) => (Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.DOTALL), "Expected error matching: "+s) } try { val dummy0 = TermName(c.freshName) val dummy1 = TermName(c.freshName) c.typecheck(c.parse(s"object $dummy0 { val $dummy1 = { $codeStr } }")) c.error(c.enclosingPosition, "Type-checking succeeded unexpectedly.\n"+expMsg) } catch { case e: TypecheckException => val msg = e.getMessage if((expected ne null) && !(expPat.matcher(msg)).matches) c.error(c.enclosingPosition, "Type-checking failed in an unexpected way.\n"+expMsg+"\nActual error: "+msg) case e: ParseException => c.error(c.enclosingPosition, s"Parsing failed.\n${e.getMessage}") } q"()" } }
Example 6
Source File: ShouldNotTypecheck.scala From lagom with Apache License 2.0 | 5 votes |
package com.lightbend.lagom.macrotestkit import scala.language.experimental.macros import java.util.regex.Pattern import scala.reflect.macros.TypecheckException import scala.reflect.macros.blackbox object ShouldNotTypecheck { def apply(name: String, code: String): Unit = macro ShouldNotTypecheck.applyImplNoExp def apply(name: String, code: String, expected: String): Unit = macro ShouldNotTypecheck.applyImpl } final class ShouldNotTypecheck(val c: blackbox.Context) { import c.universe._ def applyImplNoExp(name: Expr[String], code: Expr[String]): Expr[Unit] = applyImpl(name, code, c.Expr(EmptyTree)) def applyImpl(name: Expr[String], code: Expr[String], expected: Expr[String]): Expr[Unit] = { val Expr(Literal(Constant(codeStr: String))) = code val Expr(Literal(Constant(nameStr: String))) = name val (expPat, expMsg) = expected.tree match { case EmptyTree => (Pattern.compile(".*"), "Expected some error.") case Literal(Constant(s: String)) => (Pattern.compile(s, Pattern.CASE_INSENSITIVE), "Expected error matching: " + s) } try c.typecheck(c.parse("{ " + codeStr + " }")) catch { case e: TypecheckException => val msg = e.getMessage if (!expPat.matcher(msg).matches) { c.abort(c.enclosingPosition, s"$nameStr failed in an unexpected way.\n$expMsg\nActual error: $msg") } else { println(s"$nameStr passed.") return reify(()) } } c.abort(c.enclosingPosition, s"$nameStr succeeded unexpectedly.\n$expMsg") } }
Example 7
Source File: ShouldNotTypecheck.scala From scala-parallel-collections with Apache License 2.0 | 5 votes |
package testutil import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context import scala.reflect.macros.TypecheckException import java.util.regex.Pattern object ShouldNotTypecheck { def apply(code: String): Unit = macro applyImplNoExp def apply(code: String, expected: String): Unit = macro applyImpl def applyImplNoExp(ctx: Context)(code: ctx.Expr[String]) = applyImpl(ctx)(code, null) def applyImpl(ctx: Context)(code: ctx.Expr[String], expected: ctx.Expr[String]): ctx.Expr[Unit] = { import ctx.universe._ val Expr(Literal(Constant(codeStr: String))) = code val (expPat, expMsg) = expected match { case null => (null, "Expected some error.") case Expr(Literal(Constant(s: String))) => (Pattern.compile(s, Pattern.CASE_INSENSITIVE | Pattern.DOTALL), "Expected error matching: "+s) } try ctx.typecheck(ctx.parse("{ "+codeStr+" }")) catch { case e: TypecheckException => val msg = e.getMessage if((expected ne null) && !(expPat.matcher(msg)).matches) ctx.abort(ctx.enclosingPosition, "Type-checking failed in an unexpected way.\n"+ expMsg+"\nActual error: "+msg) else return reify(()) } ctx.abort(ctx.enclosingPosition, "Type-checking succeeded unexpectedly.\n"+expMsg) } }
Example 8
Source File: MacroCompat.scala From pureconfig with Mozilla Public License 2.0 | 5 votes |
package pureconfig.derivation import scala.reflect.macros.{ TypecheckException, whitebox } import pureconfig.Derivation trait MacroCompat { val c: whitebox.Context import c.universe._ // since we are inside a whitebox implicit macro, error messages from `c.abort` as not printed. A trick must be used // to make the compiler print our custom message. That's done by setting a @implicitNotFound annotation on our // `Derivation` class (idea taken from shapeless `Lazy`). def setImplicitNotFound(msg: String): Unit = { import c.internal.decorators._ val infTree = c.typecheck(q"""new _root_.scala.annotation.implicitNotFound($msg)""", silent = false) typeOf[Derivation[_]].typeSymbol.setAnnotations(Annotation(infTree)) } // This should be simply defined as `c.inferImplicitValue(c.weakTypeOf[A])`, but divergent implicits are wrongly // reported up to Scala 2.12.2. See https://github.com/scala/bug/issues/10398 for more information. def inferImplicitValueCompat(typ: Type): Tree = { val cc = c.asInstanceOf[scala.reflect.macros.contexts.Context] val enclosingTree = cc.openImplicits.headOption.map(_.tree) .orElse(cc.enclosingMacros.lastOption.map(_.macroApplication)) .getOrElse(EmptyTree).asInstanceOf[cc.universe.analyzer.global.Tree] val res: cc.Tree = cc.universe.analyzer.inferImplicit( enclosingTree, typ.asInstanceOf[cc.Type], false, cc.callsiteTyper.context, true, false, cc.enclosingPosition, (pos, msg) => throw TypecheckException(pos, msg)) res.asInstanceOf[c.Tree] } }
Example 9
Source File: BodyElementCollectorMacro.scala From cornichon with Apache License 2.0 | 5 votes |
package com.github.agourlay.cornichon.dsl import scala.reflect.macros.{ TypecheckException, blackbox } class BodyElementCollectorMacro(context: blackbox.Context) { val c: blackbox.Context = context import c.universe._ private val initTreeFold: (Tree, List[Tree]) = q"Nil" -> Nil def collectImpl(body: Tree): Tree = { val contextType = c.prefix.tree.tpe val validContext = typeOf[BodyElementCollector[_, _]] if (!(contextType <:< validContext)) c.abort(c.enclosingPosition, s"Macro only allowed to be used directly inside of a `$validContext`") else { val elementType = contextType.typeArgs.head blockOrApplyExpressionList(body, elementType) { elements => val (finalTree, rest) = elements.foldLeft(initTreeFold) { case ((accTree, accSingle), elem) => if (elem.tpe <:< elementType) accTree -> (accSingle :+ elem) //todo avoid List.append else q"$accTree ++ $accSingle ++ $elem" -> Nil } q"${c.prefix.tree}.get($finalTree ++ $rest)" } } } private def blockOrApplyExpressionList(body: Tree, elementType: Type)(typesTreesFn: List[Tree] => Tree): c.universe.Tree = body match { case block: Block => blockExpressionList(block, elementType)(typesTreesFn) case app: Apply => singleExpressionList(app, elementType)(typesTreesFn) case Typed(app: Apply, _) => singleExpressionList(app, elementType)(typesTreesFn) case s @ Select(_, _) => singleExpressionList(s, elementType)(typesTreesFn) case e => val unsupportedMessage = s"Unsupported expression. Only expressions of type `$elementType` are allowed here." c.abort(e.pos, s"$unsupportedMessage\nfound '$e' of type '${e.tpe}'") } private def singleExpressionList(app: Tree, elementType: Type)(typesTreesFn: List[Tree] => Tree): c.universe.Tree = typeCheck(elementType, seqElementType(elementType))(app) match { case Right(checked) => typesTreesFn(checked :: Nil) case Left((pos, error)) => c.abort(pos, error) } private def seqElementType(elementType: Type): Type = c.typecheck(q"Seq[$elementType]()").tpe private def blockExpressionList(block: Block, elementType: Type)(typesTreesFn: List[Tree] => Tree): c.universe.Tree = { val allStats = block.stats :+ block.expr //todo avoid List.append val seq = seqElementType(elementType) val checked = allStats.map(typeCheck(elementType, seq)) if (checked.exists(_.isLeft)) { val errors = checked.collect { case Left(error) => error } errors.dropRight(1).foreach { case (pos, error) => c.error(pos, error) } val lastError = errors.last c.abort(lastError._1, lastError._2) } else typesTreesFn(checked.collect { case Right(typed) => typed }) } private def typeCheck(elementType: Type, seq: Type)(tree: Tree): Either[(c.universe.Position, String), c.Tree] = { val checked = c.typecheck(tree) // checked.tpe is null if the statement is an import if (checked.tpe == null) Left(tree.pos -> s"Expected expression of either `$elementType` or `$seq` but found '$tree'") else if (checked.tpe <:< elementType || checked.tpe <:< seq) Right(checked) else try Right(c.typecheck(tree, pt = elementType)) catch { case TypecheckException(_, msg) => Left(tree.pos -> (s"Result of this expression can be either `$elementType` or `$seq`. " + msg)) } } }