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 = 3
Optional braces
val x: String = ???
val y: String | Null = ???
x == null // error
x eq null // error
"hello" == null // error
y == null // ok
y == x // ok
EXPLICIT 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 * 2
EXTENSION 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
- 938