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

https://github.com/lampepfl/dotty/pull/7379

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

  • 869