Scalameta


3.7.4 (released on 14 Apr 2018)

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.

Features


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. 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 x and y prevent the programmer from generating invalid code. Learn more about supported quasiquotes features here.

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")
Dialect Syntax Semantic Notes
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
Sbt 1.0 Yes No

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.

Multiple platforms. Scalameta is available as a JVM library and as a JavaScript module via Scala.js. Support for a native library via Scala Native is in the works.

Built with Scalameta


Feel free to add your project to this list.

Releases


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.

Getting started


To get started with scalameta, add the following to your build.sbt:

// 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.

import scala.meta._

Tutorial


To learn more about practical aspects of using scalameta, take a look at our tutorial: http://scalameta.org/tutorial.

Roadmap


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.

Language server protocol. Metals is an experimental project that use Scalameta-based tools to implement the Language Server Protocol.

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.

Not on the roadmap


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.

Talks


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.

Video: Coming soon.
Slides: http://scalameta.org/talks/2018-06-20-HowWeBuiltToolsThatScaleToMillionsOfLoc.pdf

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.

Video: https://www.youtube.com/watch?v=4AkdUhUkHl4
Slides: https://geirsson.com/assets/flatmap-2018.pdf

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 metac, metacp, mtags and mtags to produce and read SemanticDB, and how applications like Scalafix, Metadoc and Metals are using SemanticDB today.

Video: Coming soon.
Slides: https://geirsson.com/assets/scalasphere-2018.pdf

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.

Video: https://www.youtube.com/watch?v=4yqDFsdKciA
Slides: http://scalameta.org/talks/2017-06-01-SemanticToolingAtTwitter.pdf

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.

Video: https://www.youtube.com/watch?v=IPnd_SZJ1nM
Slides: http://scalamacros.org/paperstalks/2016-06-17-Metaprogramming20.pdf

Supporters


               

(c) 2014 - 2018 scalameta contributors
Fork me on GitHub