26
26
27
27
// LSP feature implementations
28
28
#include < libsolidity/lsp/GotoDefinition.h>
29
+ #include < libsolidity/lsp/SemanticTokensBuilder.h>
29
30
30
31
#include < liblangutil/SourceReferenceExtractor.h>
31
32
#include < liblangutil/CharStream.h>
@@ -64,6 +65,49 @@ int toDiagnosticSeverity(Error::Type _errorType)
64
65
return -1 ;
65
66
}
66
67
68
+ Json::Value semanticTokensLegend ()
69
+ {
70
+ Json::Value legend = Json::objectValue;
71
+
72
+ // NOTE! The (alphabetical) order and items must match exactly the items of
73
+ // their respective enum class members.
74
+
75
+ Json::Value tokenTypes = Json::arrayValue;
76
+ tokenTypes.append (" class" );
77
+ tokenTypes.append (" comment" );
78
+ tokenTypes.append (" enum" );
79
+ tokenTypes.append (" enumMember" );
80
+ tokenTypes.append (" event" );
81
+ tokenTypes.append (" function" );
82
+ tokenTypes.append (" interface" );
83
+ tokenTypes.append (" keyword" );
84
+ tokenTypes.append (" macro" );
85
+ tokenTypes.append (" method" );
86
+ tokenTypes.append (" modifier" );
87
+ tokenTypes.append (" number" );
88
+ tokenTypes.append (" operator" );
89
+ tokenTypes.append (" parameter" );
90
+ tokenTypes.append (" property" );
91
+ tokenTypes.append (" string" );
92
+ tokenTypes.append (" struct" );
93
+ tokenTypes.append (" type" );
94
+ tokenTypes.append (" typeParameter" );
95
+ tokenTypes.append (" variable" );
96
+ legend[" tokenTypes" ] = tokenTypes;
97
+
98
+ Json::Value tokenModifiers = Json::arrayValue;
99
+ tokenModifiers.append (" abstract" );
100
+ tokenModifiers.append (" declaration" );
101
+ tokenModifiers.append (" definition" );
102
+ tokenModifiers.append (" deprecated" );
103
+ tokenModifiers.append (" documentation" );
104
+ tokenModifiers.append (" modification" );
105
+ tokenModifiers.append (" readonly" );
106
+ legend[" tokenModifiers" ] = tokenModifiers;
107
+
108
+ return legend;
109
+ }
110
+
67
111
}
68
112
69
113
LanguageServer::LanguageServer (Transport& _transport):
@@ -81,6 +125,7 @@ LanguageServer::LanguageServer(Transport& _transport):
81
125
{" textDocument/didChange" , bind (&LanguageServer::handleTextDocumentDidChange, this , _2)},
82
126
{" textDocument/didClose" , bind (&LanguageServer::handleTextDocumentDidClose, this , _2)},
83
127
{" textDocument/implementation" , GotoDefinition (*this ) },
128
+ {" textDocument/semanticTokens/full" , bind (&LanguageServer::semanticTokensFull, this , _1, _2)},
84
129
{" workspace/didChangeConfiguration" , bind (&LanguageServer::handleWorkspaceDidChangeConfiguration, this , _2)},
85
130
},
86
131
m_fileRepository (" /" /* basePath */ ),
@@ -266,10 +311,30 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args)
266
311
replyArgs[" capabilities" ][" implementationProvider" ] = true ;
267
312
replyArgs[" capabilities" ][" textDocumentSync" ][" change" ] = 2 ; // 0=none, 1=full, 2=incremental
268
313
replyArgs[" capabilities" ][" textDocumentSync" ][" openClose" ] = true ;
314
+ replyArgs[" capabilities" ][" semanticTokensProvider" ][" legend" ] = semanticTokensLegend ();
315
+ replyArgs[" capabilities" ][" semanticTokensProvider" ][" range" ] = false ;
316
+ replyArgs[" capabilities" ][" semanticTokensProvider" ][" full" ] = true ; // XOR requests.full.delta = true
269
317
270
318
m_client.reply (_id, move (replyArgs));
271
319
}
272
320
321
+ void LanguageServer::semanticTokensFull (MessageID _id, Json::Value const & _args)
322
+ {
323
+ auto uri = _args[" textDocument" ][" uri" ];
324
+
325
+ compile ();
326
+
327
+ auto const sourceName = m_fileRepository.uriToSourceUnitName (uri.as <string>());
328
+ SourceUnit const & ast = m_compilerStack.ast (sourceName);
329
+ m_compilerStack.charStream (sourceName);
330
+ Json::Value data = SemanticTokensBuilder ().build (ast, m_compilerStack.charStream (sourceName));
331
+
332
+ Json::Value reply = Json::objectValue;
333
+ reply[" data" ] = data;
334
+
335
+ m_client.reply (_id, std::move (reply));
336
+ }
337
+
273
338
void LanguageServer::handleWorkspaceDidChangeConfiguration (Json::Value const & _args)
274
339
{
275
340
requireServerInitialized ();
0 commit comments