diff --git a/.circleci/config.yml b/.circleci/config.yml
index cda6e58909b7..8123fefe84a0 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -198,6 +198,19 @@ defaults:
- store_artifacts: *artifacts_test_results
- gitter_notify_failure_unless_pr
+ - steps_test_lsp: &steps_test_lsp
+ steps:
+ - checkout
+ - attach_workspace:
+ at: build
+ - run:
+ name: Install dependencies
+ command: pip install --user deepdiff colorama
+ - run:
+ name: Executing solc LSP test suite
+ command: ./test/lsp.py ./build/solc/solc
+ - gitter_notify_failure_unless_pr
+
- steps_soltest_all: &steps_soltest_all
steps:
- checkout
@@ -519,7 +532,7 @@ jobs:
command: apt -q update && apt install -y python3-pip
- run:
name: Install pylint
- command: python3 -m pip install pylint z3-solver pygments-lexer-solidity parsec tabulate
+ command: python3 -m pip install pylint z3-solver pygments-lexer-solidity parsec tabulate deepdiff colorama
# also z3-solver, parsec and tabulate to make sure pylint knows about this module, pygments-lexer-solidity for docs
- run:
name: Linting Python Scripts
@@ -887,6 +900,10 @@ jobs:
parallelism: 15 # 7 EVM versions, each with/without optimization + 1 ABIv1/@nooptions run
<<: *steps_soltest_all
+ t_ubu_lsp: &t_ubu_lsp
+ <<: *base_ubuntu2004_small
+ <<: *steps_test_lsp
+
t_archlinux_soltest: &t_archlinux_soltest
<<: *base_archlinux
environment:
@@ -1288,6 +1305,7 @@ workflows:
- t_ubu_soltest_enforce_yul: *workflow_ubuntu2004
- b_ubu_clang: *workflow_trigger_on_tags
- t_ubu_clang_soltest: *workflow_ubuntu2004_clang
+ - t_ubu_lsp: *workflow_ubuntu2004
# Ubuntu fake release build and tests
- b_ubu_release: *workflow_trigger_on_tags
diff --git a/Changelog.md b/Changelog.md
index c4b67e935b73..9e3526fab86d 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -4,6 +4,7 @@ Language Features:
Compiler Features:
+ * Commandline Interface: Add ``--lsp`` option to get ``solc`` to act as a Language Server (LSP) communicating over stdio.
Bugfixes:
diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt
index 7e3791eab02c..ff82cd9fb5e2 100644
--- a/libsolidity/CMakeLists.txt
+++ b/libsolidity/CMakeLists.txt
@@ -155,6 +155,12 @@ set(sources
interface/StorageLayout.h
interface/Version.cpp
interface/Version.h
+ lsp/LanguageServer.cpp
+ lsp/LanguageServer.h
+ lsp/FileRepository.cpp
+ lsp/FileRepository.h
+ lsp/Transport.cpp
+ lsp/Transport.h
parsing/DocStringParser.cpp
parsing/DocStringParser.h
parsing/Parser.cpp
diff --git a/libsolidity/lsp/FileRepository.cpp b/libsolidity/lsp/FileRepository.cpp
new file mode 100644
index 000000000000..9c7f72e0c4c9
--- /dev/null
+++ b/libsolidity/lsp/FileRepository.cpp
@@ -0,0 +1,64 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+// SPDX-License-Identifier: GPL-3.0
+
+#include
+
+using namespace std;
+using namespace solidity;
+using namespace solidity::lsp;
+
+namespace
+{
+
+string stripFilePrefix(string const& _path)
+{
+ if (_path.find("file://") == 0)
+ return _path.substr(7);
+ else
+ return _path;
+}
+
+}
+
+string FileRepository::sourceUnitNameToClientPath(string const& _sourceUnitName) const
+{
+ if (m_sourceUnitNamesToClientPaths.count(_sourceUnitName))
+ return m_sourceUnitNamesToClientPaths.at(_sourceUnitName);
+ else if (_sourceUnitName.find("file://") == 0)
+ return _sourceUnitName;
+ else
+ return "file://" + (m_fileReader.basePath() / _sourceUnitName).generic_string();
+}
+
+string FileRepository::clientPathToSourceUnitName(string const& _path) const
+{
+ return m_fileReader.cliPathToSourceUnitName(stripFilePrefix(_path));
+}
+
+map const& FileRepository::sourceUnits() const
+{
+ return m_fileReader.sourceUnits();
+}
+
+void FileRepository::setSourceByClientPath(string const& _uri, string _text)
+{
+ // This is needed for uris outside the base path. It can lead to collisions,
+ // but we need to mostly rewrite this in a future version anyway.
+ m_sourceUnitNamesToClientPaths.emplace(clientPathToSourceUnitName(_uri), _uri);
+ m_fileReader.addOrUpdateFile(stripFilePrefix(_uri), move(_text));
+}
diff --git a/libsolidity/lsp/FileRepository.h b/libsolidity/lsp/FileRepository.h
new file mode 100644
index 000000000000..b6aa5ee0855e
--- /dev/null
+++ b/libsolidity/lsp/FileRepository.h
@@ -0,0 +1,53 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+// SPDX-License-Identifier: GPL-3.0
+#pragma once
+
+#include
+
+#include
+#include