Tooling for scala 3
Dotty support in Metals
Tomasz Godzik

Questions!
Please ask in the chat!
Will try to answer all at the end.
Or at the Panel Later on
Why am I Here?

Why am I Here?


Why am I Here?


Why am I Here?

Currently working on Metals as one of the main contributors as a part of the collaboration between VirtusLab and Scala Center.


Who Contributed to what metals is today?








Who Contributed to what metals is today?

















Who Contributed to what metals is today?
















Who Contributed to what metals is today?





Metals - Scala language server with rich ide features

The language server protocol
Your favourite language in you favourite Editor






How does it work
Client Editor


LSP Server
How does it work
Client Editor


LSP Server
object Main{
def adding(a : Int, b : Int) = a + b
val additional = ""
val one = 1
val two = 2
addi_
}How does it work
Client Editor


LSP Server
Completions
object Main{
def adding(a : Int, b : Int) = a + b
val additional = ""
val one = 1
val two = 2
addi_
}How does it work
Client Editor


LSP Server
Completions
object Main{
def adding(a : Int, b : Int) = a + b
val additional = ""
val one = 1
val two = 2
addi_
}How does it work
Client Editor


LSP Server
object Main{
def adding(a : Int, b : Int) = a + b
val additional = ""
val one = 1
val two = 2
addi_
}How does it work
Client Editor


LSP Server
- adding()
- additional
object Main{
def adding(a : Int, b : Int) = a + b
val additional = ""
val one = 1
val two = 2
addi_
}How does it work
Client Editor


LSP Server
- adding()
- additional
object Main{
def adding(a : Int, b : Int) = a + b
val additional = ""
val one = 1
val two = 2
addi_
}How does it work
Client Editor


LSP Server

object Main{
def adding(a : Int, b : Int) = a + b
val additional = ""
val one = 1
val two = 2
addi_
}How does it work
Client Editor


LSP Server
object Main{
def adding(a : Int, b : Int) = a + b
val additional = ""
val one = 1
val two = 2
adding(_)
}Many other features!
- Diagnostics
- Goto definition
- Completions
- Hover
- Parameter hints
- Find references
- Find implementations
- Rename symbol
- Code actions
- Document symbols
- Workspace symbols
- Formatting
- Folding
- Highlight
- Execute command
Many other features!
- Diagnostics
- Goto definition
- Completions
- Hover
- Parameter hints
- Find references
- Find implementations
- Rename symbol
- Code actions
- Document symbols
- Workspace symbols
- Formatting
- Folding
- Highlight
- Execute command
Extensions!
- Worksheets
- Tree view
- Quick pick
- Slow task
The build server protocol

The universe of Build tools
Mill




Seed
The universe of Build tools
Mill




Seed

Metals
Mill
Seed





The universe of Build tools

Bloop

LSP Server
BLOOP AND BSP

Bloop

LSP Server
What is this code a part of!

BLOOP AND BSP

Bloop

LSP Server
Which project?
BLOOP AND BSP

Bloop

LSP Server
BLOOP AND BSP
Which project?

Bloop

LSP Server
BLOOP AND BSP

Bloop

LSP Server
Project Foo
BLOOP AND BSP

Bloop

LSP Server
Project Foo
BLOOP AND BSP

Bloop

LSP Server
I don't know how to compile it!

BLOOP AND BSP

Bloop

LSP Server
Compile Foo!
BLOOP AND BSP

Bloop

LSP Server
Compile Foo!
BLOOP AND BSP

Bloop

LSP Server
BLOOP AND BSP

Bloop

LSP Server
Error report
BLOOP AND BSP

Bloop

LSP Server
Error report
BLOOP AND BSP

Bloop

LSP Server
Diagnostics
BLOOP AND BSP
Dotty

Dotty
project name for technologies that are considered for inclusion in Scala 3.
Dotty
- more opinionated
- simplified
- eliminate inconsistencies and surprising behaviors
- strong foundations
- improve the language’s consistency, safety, ergonomics, and performance.

LAnguage highlights
trait A:
def f: Int
class C(x: Int) extends A:
def f = x
object O:
def f = 3Optional braces
val x: String = ???
val y: String | Null = ???
x == null // error
x eq null // error
"hello" == null // error
y == null // ok
y == x // okEXPLICIT NULLS
-Yexplicit-nulls
@main def helloWorld(
age: Int,
name: String,
others: String*
) = {
println(s"Hello $name!")
println(s"You are $age years old")
}OUTER METHODS
case class Circle(
x: Double,
y: Double,
radius: Double
)
def (c: Circle).circumference: Double =
c.radius * math.Pi * 2EXTENSION METHODS
enum Color(val rgb: Int) {
case Red extends Color(0xFF0000)
case Green extends Color(0x00FF00)
case Blue extends Color(0x0000FF)
}Enums
LAnguage highlights
LAnguage highlights
or
tooling pain points
Main problems
- whole new syntax with optional braces
- new soft keywords
- toplevel method
- complete new structures

Work so far
semanticdb support in dotty
- additional protobuf files generated by a compiler plugin
- those files are used for navigation and indexes
semanticdb support in dotty
Test.scala
----------
Summary:
Schema => SemanticDB v4
Uri => Test.scala
Text => empty
Language => Scala
Symbols => 3 entries
Occurrences => 7 entries
Symbols:
_empty_/Test. => final object Test extends AnyRef { +1 decls }
_empty_/Test.main(). => method main(args: Array[String]): Unit
_empty_/Test.main().(args) => param args: Array[String]
Occurrences:
[0:7..0:11) <= _empty_/Test.
[1:6..1:10) <= _empty_/Test.main().
[1:11..1:15) <= _empty_/Test.main().(args)
[1:17..1:22) => scala/Array#
[1:23..1:29) => scala/Predef.String#
[1:33..1:37) => scala/Unit#
[2:4..2:11) => scala/Predef.println(+1).semanticdb support in dotty
- dotty can generate semanticDB files
- new -Ysemanticdb flag
- automatically added in Bloop for Metals
Thanks to the great work by Martin Odersky and Jamie Thompson
Dotty LSP server
-
typechecking as you type to show compiler errors/warnings
-
Type information on hover
-
Go to definition (in the current project)
-
Find all references

Dotty LSP server
- code reused in metals
- works together with existing features
- can work alongside Scala 2
- separate module compiled with dotty that communicates with the compiler

Metals Server

Dotty compiler interfaces
What is working currently?
Diagnostics
Goto definition
Completions
Hover
Parameter hints
Find references
Run/Debug
document highlight
WORKSPACE SYMBOLS
RENAME SYMBOL
Code actions
Worksheets
Document symbols
Formatting
Folding
FIND IMPLEMENTATIONS
GET STARTED WITH DOTTY
via coursier
> cs install giter8
> g8 lampepfl/dotty.g8
> cd dotty
> code .GET STARTED WITH DOTTY
via coursier
> cs install giter8
> g8 lampepfl/dotty.g8
> cd dotty
> code .via new project wizard (coming soon)

in an online IDE
1. go to https://github.com/tgodzik/dotty-example-project
2. Click on the first link available
or
Just use the ready link:
https://gitpod.io/#https://github.com/tgodzik/dotty-example-project
Tooling ecosystem

more than the compiler
- Scala is not just the compiler
- it's the whole tooling ecosystem
- in order to migrate workspaces we need to provide the same experience
scalameta parser
- basis for a number of developer's tools
- works without the compiler
- fast
- has an easily understandable AST
- a lot projects depending on it
scalafmt
object Main {
def main(args: Array[String]) {
val name: Option[String] = Some("Anne")
name
match {
case None => println("Hello <unknown>")
case Some(x) => println(s"Hello $x")
}
}
}
scalafmt
object Main {
def main(args: Array[String]) {
val name: Option[String] = Some("Anne")
name
match {
case None => println("Hello <unknown>")
case Some(x) => println(s"Hello $x")
}
}
}
object Main {
def main(args: Array[String]) {
val name: Option[String] = Some("Anne")
name match {
case None => println("Hello <unknown>")
case Some(x) => println(s"Hello $x")
}
}
scalafmt
- important to keep consistent style for a team
- runs on CI
- can be considered a blocker to Scala 3 migration
object Main {
def main(args: Array[String]) {
val name: Option[String] = Some("Anne")
name
match {
case None => println("Hello <unknown>")
case Some(x) => println(s"Hello $x")
}
}
}
object Main {
def main(args: Array[String]) {
val name: Option[String] = Some("Anne")
name match {
case None => println("Hello <unknown>")
case Some(x) => println(s"Hello $x")
}
}
mdoc
- evaluates code sample in markdown files
- treats all sample as a single source file
- reused in worksheets

scalafix
- refactoring


- linting
Semantic rules
- ExplicitResultTypes
- NoAutoTupling
- RemoveUnused
Syntactic rules
- DisableSyntax
- LeakingImplicitClassVal
- NoValInForComprehension
- ProcedureSyntax
metals
Scalameta parser used in:
- folding ranges
- document symbols
- breakpoints
- formatting (scalafmt)
- tokenizing the code
- finding definition in dependencies

Roadmap

Roadmap

Roadmap
Milestone 1 (shorterm):
- shorter type names 4-7 days
- completion sorting 4-7 days
- scalameta parser without the optional braces 1-2 months

Roadmap
Milestone 2:
- exact types for generic methods 1-2 weeks
- type signatures for signature help 1-2 weeks
- scalameta optional braces support 1-2 months

Roadmap
Milestone 3:
- option for standalone compiler for dotty 1-2 days
- scalafmt for Scala 3 2-3 months
- auto imports 2-3 weeks
- advanced completions 1-2 months

Roadmap
Milestone 4:
- worksheets alongside Mdoc 2-3 weeks
- scalafix for Scala 3 1-2 months
Roadmap
- VERY ROUGH ESTIMATES
- SHOW THE AMOUNT OF WORK STILL NEEDED
- PUTS FOCUS ON TOOLING
- MAKES SCALA 3 GOALS MORE REALISTIC

Roadmap
Please do comment and let us know what you think!

Recent Work
- support for Scala 3
- GO TO PARENT CODE LENSES
- BETTER SUPPORT FOR LAUNCHING MAIN METHODS AND TESTS
- Improvements related to Bloop/Metals integration
- Code action to import all missing symbols
- Automatically add '+' on newline inside a string
NEWEST Metals FEATURES

Coming soon
- Ammonite script support
- new project provider
- better breakpoint support
- numerous improvements for Scala 3

Future work

Last year Scala Days talk by Ólafur Páll Geirsson
https://tinyurl.com/metals-scala
Presentation: https://slides.com/tomekgodzik/scala3-tooling
Metals documentation: https://scalameta.org/metals/
Bloop documentation: https://scalacenter.github.io/bloop/
Shout at me on Twitter: @TomekGodzik
OR
Ask me about anything on gitter/discord!
QUESTIONS?
Tooling for Scala 3
By Tomek Godzik
Tooling for Scala 3
- 1,080