diff --git a/docs/docs/contributing/tools/ide.md b/docs/docs/contributing/tools/ide.md new file mode 100644 index 000000000000..3b40501bfc80 --- /dev/null +++ b/docs/docs/contributing/tools/ide.md @@ -0,0 +1,37 @@ +--- +layout: doc-page +title: Using an IDE +--- + +You can use either Metals (VS Code, vim) or IntelliJ IDEA as described on the +[IDE Support](../../usage/ide-support.md) page to work on the Scala 3 codebase. There are however +a few additional considerations to take into account. + + +## Bootstrapping Projects + +The sbt build for dotty implements bootstrapping within the same build, so each component has +two projects: + +``` +sbt:scala3> projects +... +[info] scala3-compiler +[info] scala3-compiler-bootstrapped +... +``` + +These duplicated projects can be confusing and cause issues in IDEs. + +When using Metals, the `-bootstrapped` projects are not exported. + +In IntelliJ IDEA, we recommend importing the dotty codebase through BSP as described on the +[IDE Support page](../../usage/ide-support.md), then the `-bootstrapped` projects are not exported. + + +## Scala Version warning in Metals + +When using VS Code, Metals might show a warning that the Scala version (`3.0.0-[...]-NIGHTLY`) +is not supported. The reason is that the dotty repository sometimes uses a nightly build as +reference compiler. The IDE experience is going to be limited in this case (semantic features will +only within single files). diff --git a/docs/docs/usage/ide-support.md b/docs/docs/usage/ide-support.md index 9eed93fe5904..f78d382f3350 100644 --- a/docs/docs/usage/ide-support.md +++ b/docs/docs/usage/ide-support.md @@ -1,63 +1,66 @@ --- layout: doc-page -title: "IDE support for Dotty" +title: "IDE support for Scala 3" --- -Dotty comes built-in with the Dotty Language Server, an implementation of the -[Language Server Protocol](https://github.com/Microsoft/language-server-protocol), -which means that any editor that implements the LSP can be used as a Dotty IDE. -Currently, the only IDE we officially support is -[Visual Studio Code](https://code.visualstudio.com/). - -Prerequisites -============ -To use this in your own Scala project, you must first get it to compile with -Dotty, please follow the instructions at https://github.com/scala/scala3-example-project - -Usage -===== -1. Install [Visual Studio Code](https://code.visualstudio.com/). -2. Make sure `code`, the binary for Visual Studio Code, is on your `$PATH`, this - is the case if you can start the IDE by running `code` in a terminal. This - is the default on all systems except Mac where you'll need to follow these - instructions: https://code.visualstudio.com/docs/setup/mac#_command-line -3. In your project, run: -```shell -sbt launchIDE -``` - -Status -====== - -## Fully supported features: -- Typechecking as you type to show compiler errors/warnings -- Type information on hover -- Go to definition (in the current project) -- Find all references -- Documentation on hover -- [Worksheet mode](worksheet-mode.md) - -## Partially working features: -- Completion -- Renaming -- Go to definition in external projects - -## Unimplemented features: -- Formatting code (requires integrating with scalafmt) -- Quick fixes (probably by integrating with scalafix) - -## Current limitations, to be fixed: -- Projects should be compiled with sbt before starting the IDE, this is - automatically done for you if you run `sbt launchIDE`. -- Once the IDE is started, source files that are not opened in the IDE - should not be modified in some other editor, the IDE won't pick up - these changes. -- Not all compiler errors/warnings are displayed, just those occurring - during typechecking. - - -Feedback -======== -Please report issues on https://github.com/lampepfl/dotty/issues, -you can also come chat with use on the -[Dotty gitter channel](https://gitter.im/lampepfl/dotty)! +IDE support for Scala 3 is available in IDEs based on [Scala Metals](https://scalameta.org/metals/) +(e.g., Visual Studio Code, vim) and in [IntelliJ IDEA](https://www.jetbrains.com/idea/). + + +## Using Visual Studio Code + +To use Visual Studio Code on a Scala 3 project, ensure you have the +[Metals](https://scalameta.org/metals/docs/editors/vscode.html) plugin installed. Then open the +project directory in VS code and click the "Import build" button in notification. + + +### Under the Hood + +VS Code implements semantic features (such as completions, "go to definition") +using the [Language Server Protocol (LSP)](https://github.com/Microsoft/language-server-protocol), +so it needs a language server implementation. Metals is the implementation of LSP for Scala. It +extracts semantic information from [semanticdb](https://scalameta.org/docs/semanticdb/guide.html), +which is generated directly by the Scala 3 compiler. + +You can read more about Scala 3 support in Metals in +[this blog post](https://medium.com/virtuslab/introduction-to-metals-with-scala-3-79ebf3120a95). + +To communicate with the build tool (e.g., to import the project, trigger builds, run tests), +Metals uses the [Build Server Protocol (BSP)](https://build-server-protocol.github.io/). The +default BSP implementation used by metals is [Bloop](https://scalacenter.github.io/bloop/), which +supports Scala 3 projects. Alternatively, +[sbt can be used as a BSP server](https://scalameta.org/metals/blog/2020/11/06/sbt-BSP-support.html) +as it directly implements BSP since version 1.4. + + +## Using IntelliJ IDEA + +IntelliJ has its own implementation for semantic features, so it does not use Metals or the +Language Server Protocol (LSP). + +In order to import a project into IntelliJ there are two possibilities: + - Use the built-in feature to import sbt builds + - Use IntelliJ's support for the + [Build Server Protocol (BSP)](https://www.jetbrains.com/help/idea/bsp-support.html) + + +### Importing the sbt build + +To use IntelliJ's sbt import, go to "File" - "Open..." and select your project's `build.sbt` file. + +In this mode, IntelliJ starts sbt with a custom plugin to extract the project structure. After +importing, IntelliJ no longer interacts with other sbt sessions. Building and running the project +within the IDE is done by separate processes. + + +### Importing the project using BSP + +To import a project using BSP, go to "File" - "New" - "Project from Existing Sources" and select +the project directory. In the upcoming dialog select "BSP" to import the project. You may be asked +to choose between "sbt" and "sbt with Bloop", the recommended option is "sbt". + +If the project import fails ("Problem executing BSP job"), navigate to your project in a terminal +and just start `sbt`. Once sbt is running, open the "bsp" tab in IntelliJ click the "Reload" button. + +When using IntelliJ's BSP mode, build and run commands from the IDE are executed through sbt, so +they have the same effect as building or running the project through sbt in the terminal. diff --git a/docs/sidebar.yml b/docs/sidebar.yml index f3c0c63a21b9..82b59866ea7e 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -209,6 +209,8 @@ sidebar: url: docs/contributing/debugging.html - title: IDEs and Tools subsection: + - title: IDEs + url: docs/contributing/tools/ide.html - title: Mill url: docs/contributing/tools/mill.html - title: Scalafix diff --git a/project/Build.scala b/project/Build.scala index f983445ea9da..af32f067e048 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -283,7 +283,8 @@ object Build { ) // Settings used when compiling dotty with a non-bootstrapped dotty - lazy val commonBootstrappedSettings = commonDottySettings ++ Seq( + lazy val commonBootstrappedSettings = commonDottySettings ++ NoBloopExport.settings ++ Seq( + bspEnabled := false, unmanagedSourceDirectories in Compile += baseDirectory.value / "src-bootstrapped", version := dottyVersion, @@ -419,9 +420,10 @@ object Build { ), // For convenience, change the baseDirectory when running the compiler - baseDirectory in (Compile, run) := baseDirectory.value / "..", + (Compile / forkOptions) := (Compile / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value), + (Compile / run / forkOptions) := (Compile / run / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value), // And when running the tests - baseDirectory in Test := baseDirectory.value / "..", + (Test / forkOptions) := (Test / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value), test in Test := { // Exclude VulpixMetaTests diff --git a/project/NoBloopExport.scala b/project/NoBloopExport.scala new file mode 100644 index 000000000000..c9949ab0be94 --- /dev/null +++ b/project/NoBloopExport.scala @@ -0,0 +1,31 @@ +import sbt._ +import Keys._ + +/* With <3 from scala-js */ +object NoBloopExport { + private lazy val bloopGenerateKey: Option[TaskKey[Option[File]]] = { + val optBloopKeysClass: Option[Class[_]] = try { + Some(Class.forName("bloop.integrations.sbt.BloopKeys")) + } catch { + case _: ClassNotFoundException => None + } + + optBloopKeysClass.map { bloopKeysClass => + val bloopGenerateGetter = bloopKeysClass.getMethod("bloopGenerate") + bloopGenerateGetter.invoke(null).asInstanceOf[TaskKey[Option[File]]] + } + } + + /** Settings to prevent the project from being exported to IDEs. */ + lazy val settings: Seq[Setting[_]] = { + bloopGenerateKey match { + case None => + Nil + case Some(key) => + Seq( + key in Compile := None, + key in Test := None, + ) + } + } +}