Scalameta is a modern metaprogramming library for Scala that supports a wide range of language versions and execution platforms. Originally, Scalameta was founded to become a better macro system for Scala, but over time we shifted focus to developer tools and spun off the new macro system into a separate project.
High-fidelity parsing. Note how the abstract syntax trees in the printout below contain comprehensive information about formatting and comments. This is an exclusive feature of Scalameta.
scala> "x + y /* adds x and y */".parse[Term] res0: scala.meta.parsers.Parsed[scala.meta.Term] = x + y /* adds x and y */ scala> "List[ Int ]".parse[Type] res1: scala.meta.parsers.Parsed[scala.meta.Type] = List[ Int ]
Tokens. Scalameta takes even the finest details of Scala code into account. We achieve this by attaching tokens, data structures representing atomic units of Scala syntax, to our abstract syntax trees. Note that the abstract syntax tree in the printout doesn't have the comment per se - it is stored in tokens instead.
scala> val tree = "x + y /* adds x and y */".parse[Term].get tree: scala.meta.Term = x + y /* adds x and y */ scala> tree.syntax res0: String = x + y /* adds x and y */ scala> tree.structure res1: String = Term.ApplyInfix(Term.Name("x"), Term.Name("+"), Nil, List(Term.Name("y"))) scala> tree.tokens.structure res2: String = Tokens(BOF [0..0), x [0..1), [1..2), + [2..3), [3..4), y [4..5), [5..6), /* adds x and y */ [6..24), EOF [24..24))
Quasiquotes have proven to be an amazing productivity booster in scala.reflect,
so we implemented them in Scalameta and now they are better than ever.
Note the precise types for
prevent the programmer from generating invalid code.
Learn more about supported quasiquotes features
scala> val addition = q"x + y" addition: meta.Term.ApplyInfix = x + y scala> val q"$x + $y" = addition x: scala.meta.Term = x y: scala.meta.Term = y scala> q"def y: $x" <console>:19: error: type mismatch when unquoting; found : scala.meta.Term required: scala.meta.Type q"def y: $x" ^
Dialects. Scalameta is designed from the ground up to understand different versions of the base language: Scala 2.10, Scala 2.11, Scala 2.12 and even Dotty. We also support Sbt build files to make sure we cover as much Scala code as possible.
scala> import scala.meta.dialects.Sbt0137 import scala.meta.dialects.Sbt0137 scala> Sbt0137(""" lazy val root = (project in file(".")). settings(name := "hello") """).parse[Source] res0: scala.meta.parsers.Parsed[scala.meta.Source] = lazy val root = (project in file(".")). settings(name := "hello")
|Scala 2.10||Yes||Yes*||Requires an external module|
|Scala 2.11||Yes||Full support|
|Scala 2.12||Yes||Full support|
|Dotty||Partial||No||Partial support for new language features.|
|Sbt 0.13||Yes||Yes*||Requires an external module|
Semantic API. Scalameta supports SemanticDB - a data format for semantic information about programs in Scala and other languages. This ensures that our Semantic API works consistently across compilers and even across languages. Learn more about SemanticDB here.
Feel free to add your project to this list.
Semantic versioning. With Scalameta 2.0.0 onwards, we follow semantic versioning. Breaking changes to the public API bump the major version (e.g., 2.0.0 -> 3.0.0), backward compatible changes to the public API bump the minor version (e.g., 2.0.0 -> 2.1.0), bugfixes bump the patch version (e.g. 2.0.0 -> 2.0.1). For details, check out our versioning policy.
Strong compatibility guarantees. With Scalameta 2.0.0 onwards, we take a strong stance on compatibility. We communicate changes to the public API in version numbers and we have set up our build to make sure that no mistakes are made. For details, check out our compatibility policy.
To get started with scalameta, add the following to your
// Latest stable version libraryDependencies += "org.scalameta" %% "scalameta" % "3.7.3"
Next, you'll need to add a single wildcard import to the files where you'll be using scalameta.
To learn more about practical aspects of using scalameta, take a look at our tutorial: http://scalameta.org/tutorial.
Rewriting and linting. Scalafix is a rewrite and linting tool for Scala developed at the Scala Center. Scalafix rewrites use the Scalameta to automate migration between different library and compiler versions.
Scala Native support. Slow startup time for JVM command-line tools is a big blocker for many exciting editor integrations, such as code formatting. Scala Native opens possiblities to implement command-line tools that run in milliseconds instead of seconds. We have validated that scalafmt can run on native, see tweet, we "just" need to get our tests ported to know it works as expected. See https://github.com/scalameta/scalameta/issues/772.
Scala macros. Originally, Scalameta was founded to become a better macro system for Scala, but over time we shifted focus to developer tools and spun off the new macro system into a separate project.
Semantic Tooling at Twitter (ScalaDays Copenhagen 2017). This talk introduces semantic databases, the cornerstone of the scalameta semantic API, and explains how semantic databases can be used to integrate with Kythe, a language-agnostic ecosystem for developer tools. In this talk, we presented our vision of next-generation semantic tooling for the Scala ecosystem.
Metaprogramming 2.0 (ScalaDays Berlin 2016). This talk explains the status of scalameta, demonstrates key features, presents the early adopters and publishes our plans for the future. The centerpiece of the talk is the demo of a new macro system for Scala, which is no longer part of Scalameta. Nonetheless, the talk still does a good job of showcasing potential usecases for Scalameta and highlighting contributions from our amazing community.