Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc #170

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Misc #170

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ object CatsMacros:
val err = s"Don't know how to derive an Eq instance for ${Type.show[A]}: Mirror not found."
log(err)
log("="*120)
quotes.reflect.report.throwError(err)
quotes.reflect.report.errorAndAbort(err)
else
log(result.show)
log("="*120)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,28 +80,28 @@ object CompileTimeInfo {

def envVarOrNull(key: Expr[String])(using Quotes): Expr[String] = {
import quotes.reflect.*
val k = key.valueOrError
val k = key.valueOrAbort
val v = getEnvVar(k)
Expr(v.orNull)
}

def sysPropOrNull(key: Expr[String])(using Quotes): Expr[String] = {
import quotes.reflect.*
val k = key.valueOrError
val k = key.valueOrAbort
val v = getSysProp(k)
Expr(v.orNull)
}

def envVarOrSysPropOrNull(key: Expr[String])(using Quotes): Expr[String] = {
import quotes.reflect.*
val k = key.valueOrError
val k = key.valueOrAbort
val v = getEnvVar(k) orElse getSysProp(k)
Expr(v.orNull)
}

def sysPropOrEnvVarOrNull(key: Expr[String])(using Quotes): Expr[String] = {
import quotes.reflect.*
val k = key.valueOrError
val k = key.valueOrAbort
val v = getSysProp(k) orElse getEnvVar(k)
Expr(v.orNull)
}
Expand All @@ -110,28 +110,28 @@ object CompileTimeInfo {

def envVar(key: Expr[String])(using Quotes): Expr[Option[String]] = {
import quotes.reflect.*
val k = key.valueOrError
val k = key.valueOrAbort
val v = getEnvVar(k)
Expr(v)
}

def sysProp(key: Expr[String])(using Quotes): Expr[Option[String]] = {
import quotes.reflect.*
val k = key.valueOrError
val k = key.valueOrAbort
val v = getSysProp(k)
Expr(v)
}

def envVarOrSysProp(key: Expr[String])(using Quotes): Expr[Option[String]] = {
import quotes.reflect.*
val k = key.valueOrError
val k = key.valueOrAbort
val v = getEnvVar(k) orElse getSysProp(k)
Expr(v)
}

def sysPropOrEnvVar(key: Expr[String])(using Quotes): Expr[Option[String]] = {
import quotes.reflect.*
val k = key.valueOrError
val k = key.valueOrAbort
val v = getSysProp(k) orElse getEnvVar(k)
Expr(v)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package japgolly.microlibs.compiletime

import scala.annotation.targetName
import scala.annotation._
import scala.quoted.*

object MacroEnvStatic {
Expand All @@ -24,7 +24,7 @@ object MacroEnv {

def fail(msg: String)(using Quotes): Nothing =
import quotes.reflect.*
quotes.reflect.report.throwError(msg, Position.ofMacroExpansion)
quotes.reflect.report.errorAndAbort(msg, Position.ofMacroExpansion)

def failNoStack(msg: String): Nothing = {
val e = new RuntimeException(msg)
Expand All @@ -46,7 +46,7 @@ object MacroEnv {
import quotes.reflect.*
Implicits.search(TypeRepr.of[A]) match
case iss: ImplicitSearchSuccess => iss.tree.asExpr.asInstanceOf[Expr[A]]
case isf: ImplicitSearchFailure => report.throwError(isf.explanation)
case isf: ImplicitSearchFailure => report.errorAndAbort(isf.explanation)

def inlineConstNull(using Quotes): Expr[Null] =
import quotes.reflect.*
Expand Down Expand Up @@ -133,6 +133,11 @@ object MacroEnv {

def prependPrintln(msg: Expr[String])(using Quotes, Type[A]): Expr[A] =
prepend('{ println($msg) })

def uninline(using Quotes, Type[A]): Expr[A] = {
import quotes.reflect.*
uninlineTerm(self.asTerm).asExprOf[A]
}
}

// ===================================================================================================================
Expand Down Expand Up @@ -174,22 +179,33 @@ object MacroEnv {
}

// ===================================================================================================================
extension [A](self: Type[A]) {

extension [A <: AnyKind](self: Type[A]) {
def dealias(using Quotes): Type[A] =
_type_dealias[A](using self)

def isUnit(using Quotes): Boolean =
self match {
case '[Unit] => true
case _ => false
}
}

extension [A](self: Type[A]) {
def summonOrError(using Quotes): Expr[A] =
Expr.summonOrError[A](using self)
}

private def _type_dealias[A](using Type[A])(using Quotes): Type[A] =
private def _type_dealias[A <: AnyKind](using Type[A])(using Quotes): Type[A] =
import quotes.reflect.*
TypeRepr.of[A].dealias.asType.asInstanceOf[Type[A]]

// ===================================================================================================================
extension (using q: Quotes)(self: q.reflect.TypeRepr) {

@targetName("asTypeOf_TypeRepr")
def asTypeOf[A <: AnyKind]: Type[A] =
self.asType.asInstanceOf[Type[A]]

def asTypeTree: q.reflect.TypeTree =
q.reflect.TypeTree.of(using self.asType)

Expand All @@ -211,9 +227,13 @@ object MacroEnv {
// ===================================================================================================================
extension (using q: Quotes)(self: q.reflect.TypeTree) {

inline def asType: Type[?] =
def asType: Type[?] =
self.tpe.asType

@targetName("asTypeOf_TypeTree")
def asTypeOf[A <: AnyKind]: Type[A] =
self.asType.asInstanceOf[Type[A]]

@targetName("summon_TypeTree")
def summon: Option[Expr[?]] =
self.tpe.summon
Expand Down Expand Up @@ -259,8 +279,25 @@ object MacroEnv {
val a = self.tpe.show
val msg = s"Can't convert $a to ${Type.show[B]}"
import quotes.reflect.*
report.throwError(msg, Position.ofMacroExpansion)
report.errorAndAbort(msg, Position.ofMacroExpansion)
}

def betaReduce: q.reflect.Term = {
import quotes.reflect.*
Term.betaReduce(self).getOrElse(self)
}

def uninline: q.reflect.Term =
uninlineTerm(self)
}

@tailrec
private def uninlineTerm(using q: Quotes)(self: q.reflect.Term): q.reflect.Term = {
import quotes.reflect.*
self match {
case Inlined(_, _, e) => uninlineTerm(e)
case _ => self
}
}

// ===================================================================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ object QuotingUtils:

def warn(warning: Expr[String])(using Quotes): Expr[Unit] =
import quotes.reflect.*
report.warning(warning.valueOrError)
report.warning(warning.valueOrAbort)
Expr.inlineConstUnit

def replaceFirst(str: Expr[String], regex: Expr[String], repl: Expr[String])(using Quotes): Expr[String] =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package japgolly.microlibs.compiletime

import sourcecode.Line

object MacroLogger {

def apply(): MacroLogger =
new MacroLogger

def apply(enabled: Boolean): MacroLogger = {
val l = new MacroLogger
l.enabled = enabled
l
}
}

class MacroLogger {
import Console._

protected var enabledStack = List.empty[Boolean]

var enabled = false

def pushDisabled(): Unit =
pushEnabled(false)

def pushEnabled(e: Boolean = true): Unit = {
enabledStack ::= enabled
enabled = e
}

def pop(): Unit =
if (enabledStack.nonEmpty) {
enabled = enabledStack.head
enabledStack = enabledStack.tail
}

protected var _hold = false
protected var _pending = Vector.empty[() => String]

def hold(): Unit = {
release()
_hold = true
}

def release(printPending: Boolean = true): Unit = {
val pending = _pending
_pending = Vector.empty
_hold = false
if (printPending && enabled)
for (p <- pending)
_println(p())
}

def apply(): Unit =
if (enabled)
System.out.println()

def apply(a: => Any)(implicit l: Line): Unit =
if (enabled) {
val text = "" + a
// for (line <- text.linesIterator) {
// System.out.printf("%s[%3d]%s %s\n", CYAN, l.value, RESET, line)
// }
val msg = "%s[%3d]%s %s".format(CYAN, l.value, RESET, text.replace("\n", "\n "))
_println(msg)
}

private def _println(a: => Any): Unit =
if (enabled) {
val msg = () => a match {
case s: String => s
case _ => "" + a
}
if (_hold)
_pending :+= msg
else
System.out.println(msg())
}

private def width = 200
private def sep = "=" * width

def header(): Unit =
_println(sep + "\n")

def footer(): Unit =
_println("\n" + sep)

def footer(result: => Any): Unit = {
apply("Result", result)
footer()
}

def apply(name: => Any, value: => Any)(implicit l: Line): Unit =
apply(s"$YELLOW$name:$RESET $value")

def all(name: => Any, values: => Iterable[Any])(implicit l: Line): Unit =
if (enabled) {
val vs = values
if (vs.isEmpty)
apply(s"$name [0/0]")
else {
val total = vs.size
var i = 0
for (v <- vs) {
i += 1
apply(s"$name [$i/$total]", v)
}
}
}
}
5 changes: 4 additions & 1 deletion project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ object Microlibs {
"-language:implicitConversions",
"-language:higherKinds",
"-language:existentials",
"-Wconf:msg=may.not.be.exhaustive:e", // Make non-exhaustive matches errors instead of warnings
"-Wconf:msg=Reference.to.uninitialized.value:e", // Make uninitialised value calls errors instead of warnings
)

def scalac2Flags = Seq(
Expand All @@ -37,6 +39,7 @@ object Microlibs {

def scalac3Flags = Seq(
"-source:3.0-migration",
"-Wconf:msg=unused:s", // Scala 3.1 doesn't support @nowarn("cat=unused")
"-Ykind-projector",
)

Expand Down Expand Up @@ -145,7 +148,7 @@ object Microlibs {
.settings(
moduleName := "compile-time",
scalacOptions --= Seq("-source:3.0-migration"),
libraryDependencies ++= Seq(Dep.sourceCode.value).filterNot(_ => scalaVersion.value.startsWith("3")))
libraryDependencies += Dep.sourceCode.value)

lazy val disjunctionJVM = disjunction.jvm
lazy val disjunctionJS = disjunction.js
Expand Down
Loading