Using VS Code as an Editor for the Swift Compiler

Sam Lazarus
5 min readApr 28, 2019

--

Visual Studio Code is a fantastic tool that can be used as anything from lightweight text editor to a IDE suited for even heavy development tasks. When I started working on the Swift compiler, I needed to determine what tooling I wanted to use. When selecting the tooling I would use to contribute, I knew that I needed an editor which could provide type information and intelligent code completion, use lldb for debugging, and have modern text editing and refactoring capabilities. VS Code seemed like a good tool for the job, however it needs a good deal of configuration out of the box before it’s ready to work on such a heavy weight task. Here’s a quick walkthrough of setting up VS Code to work on the Swift compiler.

Aside: This guide is angled towards macOS, however the majority of the steps here are cross platform with slight modification.

The finished product

Environment Setup

Before we can set up VS Code, we need to have a successful version of the Swift compiler. To get this set up, I would recommend forking the swift repository, then following these instructions but with the initial clone pointed at your fork of the repository.

When you get to the build step, make sure to build with a debug configuration for the part of the compiler you plan to work on. Without doing so, you won’t be able to easily use the debugger we’ll set up.

The documentation here mentions that it may be helpful to save your build directory as an environment variable. I would highly recommend you do so as it will make VS Code configuration significantly easier.

Setting up VS Code Workspace

Once your environment is set up, you can create your VS Code workspace. Open up VS Code, select add workspace folder, then navigate to the directory you cloned Swift into.

This will open up a VS Code workspace. Start out by saving the workspace File > Save Workspace As... I placed mine in the folder containing swift-sources but where you save this doesn’t matter much as long as it’s not in the project folder itself.

Once your workspace is set up, install the following extensions (we’ll set them up in a bit):

  • C/C++ by Microsoft (Language server integration)
  • Cmake by twxs (Language support for CMake files)
  • CodeLLDB by Vadim Chugunov (Debugging with LLDB)

Ignore VS Code Configuration in Git

We need to add VS Code configuration files to the list of locally ignored files in git. To do this, from the main project directory, open .git/info/exclude and add a line containing:

.vscode/

Add file associations

Open your VS Code settings (This can be easily found by opening Code > Preferences > Settings and clicking the { } icon in the top right) and add the following to your configuration:

This will allow C++ and swift gyb and swift test result files to get syntax highlighting from their associated language. For gyb files, the highlighting won’t be perfect, but it’s better than nothing.

Configuring IntelliSense

In order to get useful code completion, signature popovers, symbol searching, go to definition, error highlighting, and more useful code navigation features, you’ll need to give the Microsoft C/C++ plugin the information it needs to run clangd on the project.

If you’re on macOS, you’ll need to make sure that you install the macOS SDK headers for your OS version. If you’re on macOS 10.14, you would run the following:

sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /

This will install header files for the macOS SDK into usr/include .

If you’re on another operating system, ensure you have the headers for the standard library accessible in a folder somewhere.

Additionally, make sure you also have the following set. These will tell Intellisense to use clang:

Setting up the Debugger

At this point, I would create a directory where I put swift example code that I would like to run the compiler on for debugging. I would recommend saving that folder in an environment variable called ${SWIFT_EXAMPLES_DIR} .

Once you’ve done this, go to the debug panel in VS Code, and click the gear icon in the top left. If prompted, select the option to make a new launch.json file. Copy and paste the following into that file:

Now when you click the green play button in the debug panel, you will be prompted for a file to run the compiler on, and then the debugger will start.

Useful Tasks

VS Code allows you to specify tasks that it can run for you. The rest of the setup is all optional, but having these tasks in your editor will make your life a lot easier as they’ll automate some common tasks.

To add one of the tasks seen below, perform any setup specified, and then add the shown JSON to the list titled "tasks" in tasks.json .

If you want to assign keyboard shortcuts to any of these, go to Code > Preferences > Keyboard Shortcuts then click the { } symbol in the top right, then add the following to the JSON File with <keyboard shortcut> replaced with the desired shortcut, and <task name> replaced with the desired task’s name:

Format Your Changes

The Swift codebase uses clang-format with the LLDB style to format C++. Using the built in C/C++ formatter would work, however you’ll also fix formatting in parts of the file you didn’t touch which is likely outside of the scope of any changes you’ll be making. To solve this, we’re going to use git-clang-format .

First, you’ll have to add git-clang-format to your path. A copy of the git-clang-format binary can be found in swift-source/clang/tools/clang-format . Add that folder to your path.

Finally, add the following task to your list of tasks:

Build The Project

Once you’ve performed an initial build, you can use the build system ninja to perform much faster incremental builds. The following task adds build tasks for two of the most common targets, and sets the default build task (which can easily be run with Command + Shift + B to build the compiler itself.

Run Tests

Swift tests can be easily run using LLVM lit. In order to set up the following tasks, first, you’ll need to save the directory containing lit as an environment variable. Lit can be found in swift-source/llvm/utils/lit . Save that directory as the environment variable LLVM_LIT_DIR . Then, add the following to your tasks:

You’ll also need to add the following to the list called "inputs” in the same file:

Full tasks.json File

For reference, my full tasks.json file looks like this:

Conclusion

Thank you for reading! I hope you found this guide helpful. If you have any questions or notice anything in this post that needs correcting, feel free to leave a comment and I’d be happy to respond.

--

--