1 /* 2 *Copyright (C) 2018 Laurent Tréguier 3 * 4 *This file is part of DLS. 5 * 6 *DLS is free software: you can redistribute it and/or modify 7 *it under the terms of the GNU General Public License as published by 8 *the Free Software Foundation, either version 3 of the License, or 9 *(at your option) any later version. 10 * 11 *DLS is distributed in the hope that it will be useful, 12 *but WITHOUT ANY WARRANTY; without even the implied warranty of 13 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 *GNU General Public License for more details. 15 * 16 *You should have received a copy of the GNU General Public License 17 *along with DLS. If not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 module dls.protocol.messages.text_document; 22 23 import dls.protocol.definitions; 24 import dls.protocol.interfaces.text_document; 25 import std.json : JSONValue; 26 import std.typecons : Nullable; 27 28 void didOpen(DidOpenTextDocumentParams params) 29 { 30 import dls.protocol.interfaces : PublishDiagnosticsParams; 31 import dls.protocol.jsonrpc : send; 32 import dls.protocol.logger : logger; 33 import dls.protocol.messages.methods : TextDocument; 34 import dls.tools.analysis_tool : AnalysisTool; 35 import dls.tools.symbol_tool : SymbolTool; 36 import dls.util.document : Document; 37 import dls.util.uri : Uri, sameFile; 38 import std.algorithm : canFind; 39 import std.uni : toLower; 40 41 auto uri = new Uri(params.textDocument.uri); 42 logger.info("Document opened: %s", uri.path); 43 44 if (!SymbolTool.instance.workspacesFilesUris.canFind!sameFile(uri)) 45 { 46 send(TextDocument.publishDiagnostics, new PublishDiagnosticsParams(uri, 47 AnalysisTool.instance.diagnostics(uri))); 48 } 49 50 if (!Document.open(params.textDocument)) 51 { 52 logger.warning("Document %s is already open", uri.path); 53 } 54 } 55 56 void didChange(DidChangeTextDocumentParams params) 57 { 58 import dls.protocol.logger : logger; 59 import dls.util.document : Document; 60 import dls.util.uri : Uri; 61 62 auto uri = new Uri(params.textDocument.uri); 63 logger.info("Document changed: %s", uri.path); 64 65 if (!Document.change(params.textDocument, params.contentChanges)) 66 { 67 logger.warning("Document %s is not open", uri.path); 68 } 69 } 70 71 void willSave(WillSaveTextDocumentParams params) 72 { 73 } 74 75 TextEdit[] willSaveWaitUntil(WillSaveTextDocumentParams params) 76 { 77 return []; 78 } 79 80 void didSave(DidSaveTextDocumentParams params) 81 { 82 import dls.protocol.interfaces : PublishDiagnosticsParams; 83 import dls.protocol.jsonrpc : send; 84 import dls.protocol.logger : logger; 85 import dls.protocol.messages.methods : TextDocument; 86 import dls.tools.analysis_tool : AnalysisTool; 87 import dls.util.uri : Uri; 88 89 auto uri = new Uri(params.textDocument.uri); 90 logger.info("Document saved: %s", uri.path); 91 send(TextDocument.publishDiagnostics, new PublishDiagnosticsParams(uri, 92 AnalysisTool.instance.diagnostics(uri))); 93 } 94 95 void didClose(DidCloseTextDocumentParams params) 96 { 97 import dls.protocol.interfaces : PublishDiagnosticsParams; 98 import dls.protocol.jsonrpc : send; 99 import dls.protocol.logger : logger; 100 import dls.protocol.messages.methods : TextDocument; 101 import dls.tools.symbol_tool : SymbolTool; 102 import dls.util.document : Document; 103 import dls.util.uri : Uri, sameFile; 104 import std.algorithm : canFind; 105 106 auto uri = new Uri(params.textDocument.uri); 107 logger.info("Document closed: %s", uri.path); 108 109 if (!Document.close(params.textDocument)) 110 { 111 logger.warning("Document %s is not open", uri.path); 112 } 113 114 if (!SymbolTool.instance.workspacesFilesUris.canFind!sameFile(uri)) 115 { 116 send(TextDocument.publishDiagnostics, new PublishDiagnosticsParams(uri, [])); 117 } 118 } 119 120 CompletionItem[] completion(CompletionParams params) 121 { 122 import dls.tools.symbol_tool : SymbolTool; 123 import dls.util.uri : Uri; 124 125 return SymbolTool.instance.completion(new Uri(params.textDocument.uri), params.position); 126 } 127 128 @("completionItem", "resolve") 129 CompletionItem completionItem_resolve(CompletionItem item) 130 { 131 import dls.tools.symbol_tool : SymbolTool; 132 133 return SymbolTool.instance.completionResolve(item); 134 } 135 136 Hover hover(TextDocumentPositionParams params) 137 { 138 import dls.tools.symbol_tool : SymbolTool; 139 import dls.util.uri : Uri; 140 141 return SymbolTool.instance.hover(new Uri(params.textDocument.uri), params.position); 142 } 143 144 SignatureHelp signatureHelp(TextDocumentPositionParams params) 145 { 146 return null; 147 } 148 149 Location[] declaration(TextDocumentPositionParams params) 150 { 151 return definition(params); 152 } 153 154 Location[] definition(TextDocumentPositionParams params) 155 { 156 import dls.tools.symbol_tool : SymbolTool; 157 import dls.util.uri : Uri; 158 159 return SymbolTool.instance.definition(new Uri(params.textDocument.uri), params.position); 160 } 161 162 Location[] typeDefinition(TextDocumentPositionParams params) 163 { 164 import dls.tools.symbol_tool : SymbolTool; 165 import dls.util.uri : Uri; 166 167 return SymbolTool.instance.typeDefinition(new Uri(params.textDocument.uri), params.position); 168 } 169 170 Location implementation(TextDocumentPositionParams params) 171 { 172 return null; 173 } 174 175 Location[] references(ReferenceParams params) 176 { 177 import dls.tools.symbol_tool : SymbolTool; 178 import dls.util.uri : Uri; 179 180 return SymbolTool.instance.references(new Uri(params.textDocument.uri), 181 params.position, params.context.includeDeclaration); 182 } 183 184 DocumentHighlight[] documentHighlight(TextDocumentPositionParams params) 185 { 186 import dls.tools.symbol_tool : SymbolTool; 187 import dls.util.uri : Uri; 188 189 return SymbolTool.instance.highlight(new Uri(params.textDocument.uri), params.position); 190 } 191 192 JSONValue documentSymbol(DocumentSymbolParams params) 193 { 194 import dls.protocol.state : initState; 195 import dls.tools.symbol_tool : SymbolTool; 196 import dls.util.json : convertToJSON; 197 import dls.util.uri : Uri; 198 199 auto uri = new Uri(params.textDocument.uri); 200 201 if (!initState.capabilities.textDocument.isNull && !initState.capabilities.textDocument.documentSymbol.isNull 202 && !initState.capabilities.textDocument.documentSymbol.hierarchicalDocumentSymbolSupport.isNull 203 && initState.capabilities.textDocument.documentSymbol.hierarchicalDocumentSymbolSupport) 204 { 205 return convertToJSON(SymbolTool.instance.symbol!DocumentSymbol(uri, null)); 206 } 207 else 208 { 209 return convertToJSON(SymbolTool.instance.symbol!SymbolInformation(uri, null)); 210 } 211 } 212 213 JSONValue codeAction(CodeActionParams params) 214 { 215 import dls.protocol.state : initState; 216 import dls.tools.analysis_tool : AnalysisTool; 217 import dls.util.json : convertToJSON; 218 import dls.util.uri : Uri; 219 220 if (initState.capabilities.textDocument.isNull || initState.capabilities.textDocument.codeAction.isNull 221 || initState.capabilities.textDocument.codeAction.codeActionLiteralSupport.isNull) 222 { 223 return convertToJSON(AnalysisTool.instance.codeAction(new Uri(params.textDocument.uri), 224 params.range, params.context.diagnostics, true)); 225 } 226 else 227 { 228 return convertToJSON(AnalysisTool.instance.codeAction(new Uri(params.textDocument.uri), 229 params.range, params.context.diagnostics, 230 params.context.only.isNull ? [] : params.context.only.get())); 231 } 232 } 233 234 CodeLens[] codeLens(CodeLensParams params) 235 { 236 return []; 237 } 238 239 @("codeLens", "resolve") 240 CodeLens codeLens_resolve(CodeLens codeLens) 241 { 242 return codeLens; 243 } 244 245 DocumentLink[] documentLink(DocumentLinkParams params) 246 { 247 return []; 248 } 249 250 @("documentLink", "resolve") 251 DocumentLink documentLink_resolve(DocumentLink link) 252 { 253 return link; 254 } 255 256 ColorInformation[] documentColor(DocumentColorParams params) 257 { 258 return []; 259 } 260 261 ColorPresentation[] colorPresentation(ColorPresentationParams params) 262 { 263 return []; 264 } 265 266 TextEdit[] formatting(DocumentFormattingParams params) 267 { 268 import dls.tools.format_tool : FormatTool; 269 import dls.util.uri : Uri; 270 271 return FormatTool.instance.formatting(new Uri(params.textDocument.uri), params.options); 272 } 273 274 TextEdit[] rangeFormatting(DocumentRangeFormattingParams params) 275 { 276 import dls.tools.format_tool : FormatTool; 277 import dls.util.uri : Uri; 278 279 return FormatTool.instance.rangeFormatting(new Uri(params.textDocument.uri), 280 params.range, params.options); 281 } 282 283 TextEdit[] onTypeFormatting(DocumentOnTypeFormattingParams params) 284 { 285 import dls.tools.format_tool : FormatTool; 286 import dls.util.uri : Uri; 287 288 return FormatTool.instance.onTypeFormatting(new Uri(params.textDocument.uri), 289 params.position, params.options); 290 } 291 292 WorkspaceEdit rename(RenameParams params) 293 { 294 import dls.tools.symbol_tool : SymbolTool; 295 import dls.util.uri : Uri; 296 297 return SymbolTool.instance.rename(new Uri(params.textDocument.uri), 298 params.position, params.newName); 299 } 300 301 Range prepareRename(TextDocumentPositionParams params) 302 { 303 import dls.tools.symbol_tool : SymbolTool; 304 import dls.util.uri : Uri; 305 306 return SymbolTool.instance.prepareRename(new Uri(params.textDocument.uri), params.position); 307 } 308 309 FoldingRange[] foldingRange(FoldingRangeParams params) 310 { 311 return []; 312 }