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. Semantic analysis of Scala programs has typically been tricky business, requiring intimate familiarity with compiler internals. Scalameta involves none of that. Our semantic API is powered by Semantic DB, a simple schema for persisting semantic information extracted from the Scala compiler. Saved semantic information can then be used in multiple applications running on different platforms, potentially in a distributed fashion.
|Inferred type arguments||Yes|
|Symbol at position||Yes|
|Type at position||No|
Feel free to add your project to this list.
Train model. Every six weeks, we publish a release with the latest changes.
Semantic versioning. With Scalameta 2.0 onwards, we follow semantic versioning enforced with MiMa. Binary breaking changes bump up the major version (e.g., 2.0 -> 3.0), binary compatible improvements bump up the minor version (e.g., 2.0 -> 2.1).
Milestone releases. At any point in the release cycle, we may cut milestone releases to test out work-in-progress changes.
To get started with scalameta, add the following to your
// Latest stable version libraryDependencies += "org.scalameta" %% "scalameta" % "2.1.2"
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 that is based on a workshop given by Ólafur Pall Geirsson at Scala World 2016: http://scalameta.org/tutorial.
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.