blob: 28ae74c7b5850172e529b5f9d818cf9e16065f2a [file] [log] [blame]
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analysis_server/src/lsp/source_edits.dart';
class TextDocumentChangeHandler
extends MessageHandler<DidChangeTextDocumentParams, void> {
TextDocumentChangeHandler(LspAnalysisServer server) : super(server);
Method get handlesMessage => Method.textDocument_didChange;
@override
DidChangeTextDocumentParams convertParams(Map<String, dynamic> json) =>
DidChangeTextDocumentParams.fromJson(json);
ErrorOr<void> handle(DidChangeTextDocumentParams params) {
final path = pathOf(params.textDocument);
return path.mapResult((path) => _changeFile(path, params));
}
ErrorOr<void> _changeFile(String path, DidChangeTextDocumentParams params) {
final oldContents = server.fileContentOverlay[path];
// TODO(dantup): Should we be tracking the version?
// Visual Studio has been seen to skip didOpen notifications for files that
// were already open when the LSP server initialized, so handle this with
// a specific message to make it clear what's happened.
if (oldContents == null) {
return error(
ErrorCodes.InvalidParams,
'Unable to edit document because the file was not previously opened: $path',
null,
);
}
final newContents = applyEdits(oldContents, params.contentChanges);
return newContents.mapResult((newcontents) {
server.updateOverlay(path, newContents.result);
return success();
});
}
}
class TextDocumentCloseHandler
extends MessageHandler<DidCloseTextDocumentParams, void> {
TextDocumentCloseHandler(LspAnalysisServer server) : super(server);
Method get handlesMessage => Method.textDocument_didClose;
@override
DidCloseTextDocumentParams convertParams(Map<String, dynamic> json) =>
DidCloseTextDocumentParams.fromJson(json);
ErrorOr<void> handle(DidCloseTextDocumentParams params) {
final path = pathOf(params.textDocument);
return path.mapResult((path) {
server.updateOverlay(path, null);
return success();
});
}
}
class TextDocumentOpenHandler
extends MessageHandler<DidOpenTextDocumentParams, void> {
TextDocumentOpenHandler(LspAnalysisServer server) : super(server);
Method get handlesMessage => Method.textDocument_didOpen;
@override
DidOpenTextDocumentParams convertParams(Map<String, dynamic> json) =>
DidOpenTextDocumentParams.fromJson(json);
ErrorOr<void> handle(DidOpenTextDocumentParams params) {
final doc = params.textDocument;
// TODO(dantup): This needs similar error handling to pathOf()
final path = Uri.parse(doc.uri).toFilePath();
// TODO(dantup): Keep track of versions, so that when we compute fixes etc.
// we can send them back versions so the client can drop them if the document
// has been modified.
server.updateOverlay(path, doc.text);
// If the file did not exist, and is "overlay only", it still should be
// analyzed. Add it to driver to which it should have been added.
server.contextManager.getDriverFor(path)?.addFile(path);
return success();
}
}