forked from ethereum/solidity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLanguageServer.h
133 lines (106 loc) · 4.77 KB
/
LanguageServer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
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 <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#pragma once
#include <libsolidity/lsp/Transport.h>
#include <libsolidity/lsp/FileRepository.h>
#include <libsolidity/interface/CompilerStack.h>
#include <libsolidity/interface/FileReader.h>
#include <libsolutil/JSON.h>
#include <functional>
#include <map>
#include <optional>
#include <string>
#include <vector>
namespace solidity::lsp
{
class RenameSymbol;
enum class ErrorCode;
/**
* Enum to mandate what files to take into consideration for source code analysis.
*/
enum class FileLoadStrategy
{
/// Takes only those files into consideration that are explicitly opened and those
/// that have been directly or indirectly imported.
DirectlyOpenedAndOnImported = 0,
/// Takes all Solidity (.sol) files within the project root into account.
/// Symbolic links will be followed, even if they lead outside of the project directory
/// (`--allowed-paths` is currently ignored by the LSP).
///
/// This resembles the closest what other LSPs should be doing already.
ProjectDirectory = 1,
};
/**
* Solidity Language Server, managing one LSP client.
* This implements a subset of LSP version 3.16 that can be found at:
* https://microsoft.github.io/language-server-protocol/specifications/specification-3-16/
*/
class LanguageServer
{
public:
/// @param _transport Customizable transport layer.
explicit LanguageServer(Transport& _transport);
/// Re-compiles the project and updates the diagnostics pushed to the client.
void compileAndUpdateDiagnostics();
/// Loops over incoming messages via the transport layer until shutdown condition is met.
///
/// The standard shutdown condition is when the maximum number of consecutive failures
/// has been exceeded.
///
/// @return boolean indicating normal or abnormal termination.
bool run();
FileRepository& fileRepository() noexcept { return m_fileRepository; }
Transport& client() noexcept { return m_client; }
std::tuple<frontend::ASTNode const*, int> astNodeAndOffsetAtSourceLocation(std::string const& _sourceUnitName, langutil::LineColumn const& _filePos);
frontend::ASTNode const* astNodeAtSourceLocation(std::string const& _sourceUnitName, langutil::LineColumn const& _filePos);
frontend::CompilerStack const& compilerStack() const noexcept { return m_compilerStack; }
private:
/// Checks if the server is initialized (to be used by messages that need it to be initialized).
/// Reports an error and returns false if not.
void requireServerInitialized();
void handleInitialize(MessageID _id, Json const& _args);
void handleInitialized(MessageID _id, Json const& _args);
void handleWorkspaceDidChangeConfiguration(Json const& _args);
void setTrace(Json const& _args);
void handleTextDocumentDidOpen(Json const& _args);
void handleTextDocumentDidChange(Json const& _args);
void handleTextDocumentDidClose(Json const& _args);
void handleRename(Json const& _args);
void handleGotoDefinition(MessageID _id, Json const& _args);
void semanticTokensFull(MessageID _id, Json const& _args);
/// Invoked when the server user-supplied configuration changes (initiated by the client).
void changeConfiguration(Json const&);
/// Compile everything until after analysis phase.
void compile();
std::vector<boost::filesystem::path> allSolidityFilesFromProject() const;
using MessageHandler = std::function<void(MessageID, Json const&)>;
Json toRange(langutil::SourceLocation const& _location);
Json toJson(langutil::SourceLocation const& _location);
// LSP related member fields
enum class State { Started, Initialized, ShutdownRequested, ExitRequested, ExitWithoutShutdown };
State m_state = State::Started;
Transport& m_client;
std::map<std::string, MessageHandler> m_handlers;
/// Set of files (names in URI form) known to be open by the client.
std::set<std::string> m_openFiles;
/// Set of source unit names for which we sent diagnostics to the client in the last iteration.
std::set<std::string> m_nonemptyDiagnostics;
FileRepository m_fileRepository;
FileLoadStrategy m_fileLoadStrategy = FileLoadStrategy::ProjectDirectory;
frontend::CompilerStack m_compilerStack;
/// User-supplied custom configuration settings (such as EVM version).
Json m_settingsObject;
};
}