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.4"
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.
How We Built Tools That Scale to Millions of Lines of Code (ScalaDays New York 2018). This talk outlines the work that we did at Twitter to add semantic functionality to code browsing, code review and code evolution tools. We use SemanticDB - an opensource data model for semantic information developed in Scalameta. We have implemented experimental improvements to the Twitter development workflow, integrating opensource and closed-source solutions.
Six Steps from Zero to IDE (flatMap(Oslo) and ScalaDays Berlin 2018). This talk is about the Language Server Protocol and Metals, a language server for Scala that we are building with SemanticDB. The talk explains the architecture of Metals and what components are needed to build a good interactive editing experience for Scala.
SemanticDB for Scala developer tools
(ScalaSphere Krakow 2018). This talk covers what SemanticDB is and how it enables a new
way to build developer tools for Scala. We show how SemanticDB data looks like,
explain how to use the utilities
to produce and read SemanticDB, and how applications like
Metals are using SemanticDB today.
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.