Socket
Book a DemoInstallSign in
Socket

com.github.dmytromitin:scala3-compiler-patched_3

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

com.github.dmytromitin:scala3-compiler-patched_3

Patched Scala-3/Dotty compiler and Eval library

Source
mavenMaven Central
Version
3.2.1
Version published
Maintainers
1
Source

Dotty-patched and Eval

Maven Central Maven Central Sonatype Snapshots javadoc Scaladex Scaladex Scaladex Scaladex Join the chat at https://gitter.im/DmytroMitin/eval

mvnrepository repo1.maven

Background

https://github.com/lampepfl/dotty

https://stackoverflow.com/questions/71390113/get-annotations-from-class-in-scala-3-macros

https://stackoverflow.com/questions/70945320/how-to-compile-and-execute-scala-code-at-run-time-in-scala3

https://github.com/DmytroMitin/dotty-patched/commit/fdf010ca4901b22961f3ae1cb3459b5fa194652e

Dotty-patched and multi-staging in Scala 3 macros

staging.run evaluates a typed tree (wrapped into an Expr) into a value (this seems similar to context.eval/toolbox.eval evaluating an untyped tree in Scala 2). This functionality exists in Scala 3/Dotty but is deliberately blocked in macros (because of the phase consistency principle). To unblock, a code expanding macros should be compiled with the compiler patched. Macros themselves can be compiled with the standard compiler. Staging dependency didn't have to be patched so far.

scalaVersion := "3.2.1" // 3.2.0, 3.1.3, ...
libraryDependencies += scalaOrganization.value %% "scala3-staging" % scalaVersion.value
// custom Scala settings
managedScalaInstance := false
ivyConfigurations += Configurations.ScalaTool
libraryDependencies ++= Seq(
  scalaOrganization.value  %  "scala-library"  % "2.13.10",
  scalaOrganization.value  %% "scala3-library" % "3.2.1",
  "com.github.dmytromitin" %% "scala3-compiler-patched-assembly" % "3.2.1" % "scala-tool"
)
import scala.quoted.*

inline def printAtCompileTime[A](a: A): Unit = ${impl[A]('a)}

def impl[A: Type](a: Expr[A])(using Quotes): Expr[Unit] =
  import quotes.reflect.*
  given staging.Compiler = staging.Compiler.make(this.getClass.getClassLoader)
  val aValue = staging.run(a) // evaluating a tree
  println(aValue)
  '{()}
sbt clean compile
printAtCompileTime(1 + 1) // 2 (at compile time)

Eval

On contrary to staging.run, Eval evaluates into a value a source code rather than a tree. So it works on standard Scala 3.

scalaVersion := "3.2.1" // or 3.2.0
libraryDependencies += "com.github.dmytromitin" %% "eval" % "0.1"
sbt clean compile run
import com.github.dmytromitin.eval.Eval

Eval[Int]("1 + 1") // 2 (at runtime)

Eval in Scala 3 macros

import com.github.dmytromitin.eval.Eval
import scala.quoted.*

inline def printAtCompileTime[A](a: A): Unit = ${impl[A]('a)}

def impl[A: Type](a: Expr[A])(using Quotes): Expr[Unit] = 
  import quotes.reflect.*
  val str = a.asTerm.pos.sourceCode.getOrElse(
    report.errorAndAbort(s"No source code for ${a.show}")
  )
  val aValue = Eval[A](str) // evaluating source code
  println(aValue)

  '{()}
sbt clean compile
printAtCompileTime(1 + 1) // 2 (at compile time)

Some built-in Scala 3 macros

import com.github.dmytromitin.macros.eval.AnnotationsMacro.getAnnotations
import com.github.dmytromitin.macros.eval.PrintValueMacro.printAtCompileTime

printAtCompileTime(1 + 1)
//2
getAnnotations(classOf[scala.CanEqual[?, ?]])
//new scala.annotation.internal.SourceFile("library/src/scala/CanEqual.scala"), new scala.annotation.internal.Child[scala.CanEqual.derived.type](), new scala.annotation.implicitNotFound("Values of types ${L} and ${R} cannot be compared with == or !=")
// add custom Scala settings to build.sbt, see above
import com.github.dmytromitin.macros.run.AnnotationsMacro.getAnnotations
import com.github.dmytromitin.macros.run.PrintValueMacro.printAtCompileTime

printAtCompileTime(1 + 1)
//2
getAnnotations(classOf[scala.CanEqual[?, ?]])
//scala.List.apply[java.lang.String]("new scala.annotation.internal.SourceFile(\"library/src/scala/CanEqual.scala\")", "new scala.annotation.internal.Child[scala.CanEqual.derived.type]()", "new scala.annotation.implicitNotFound(\"Values of types ${L} and ${R} cannot be compared with == or !=\")")

FAQs

Package last updated on 30 Oct 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts