Minor LSP tweaks in preperation for included suggestionSets

Change-Id: I9dff56139754b8a182e906d64dd0bcc009c4b6fc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102701
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
index 674201f..9c4b4d6 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
@@ -49,7 +49,7 @@
       final organizer = new DirectiveOrganizer(code, unit, result.errors);
       final edits = organizer.organize();
 
-      return sendEditsToClient(docIdentifier, unit, edits);
+      return sendSourceEditsToClient(docIdentifier, unit, edits);
     });
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
index 46deabd..0e60476 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
@@ -23,7 +23,7 @@
 
   String get commandName;
 
-  Future<ErrorOr<void>> sendEditsToClient(
+  Future<ErrorOr<void>> sendSourceEditsToClient(
       VersionedTextDocumentIdentifier docIdentifier,
       CompilationUnit unit,
       List<SourceEdit> edits) async {
@@ -38,6 +38,11 @@
       [new FileEditInformation(docIdentifier, unit.lineInfo, edits)],
     );
 
+    return sendWorkspaceEditToClient(workspaceEdit);
+  }
+
+  Future<ErrorOr<void>> sendWorkspaceEditToClient(
+      WorkspaceEdit workspaceEdit) async {
     // Send the edit to the client via a applyEdit request (this is a request
     // from server -> client and the client will provide a response).
     final editResponse = await server.sendRequest(Method.workspace_applyEdit,
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
index 680d466..e1aba44 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/sort_members.dart
@@ -55,6 +55,6 @@
 
     final sorter = new MemberSorter(code, unit);
     final edits = sorter.sort();
-    return await sendEditsToClient(docIdentifier, unit, edits);
+    return await sendSourceEditsToClient(docIdentifier, unit, edits);
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
index 35bc6e9..b7b5f72 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_code_actions.dart
@@ -92,7 +92,7 @@
       assist.change.message,
       CodeActionKind.Refactor,
       const [],
-      createWorkspaceEdit(server, assist.change),
+      createWorkspaceEdit(server, assist.change.edits),
       null,
     ));
   }
@@ -107,7 +107,7 @@
       fix.change.message,
       CodeActionKind.QuickFix,
       [diagnostic],
-      createWorkspaceEdit(server, fix.change),
+      createWorkspaceEdit(server, fix.change.edits),
       null,
     ));
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
index 86c39e9..d997719 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
@@ -137,7 +137,7 @@
             'Document was modified while rename was being computed', null);
       }
 
-      final workspaceEdit = createWorkspaceEdit(server, change);
+      final workspaceEdit = createWorkspaceEdit(server, change.edits);
       return success(workspaceEdit);
     });
   }
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index 53715b7..3719bb2 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -1,8 +1,16 @@
+// Copyright (c) 2019, 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 'dart:collection';
 
+import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart'
+    as lsp;
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart'
     show ResponseError;
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart' as lsp;
 import 'package:analysis_server/lsp_protocol/protocol_special.dart'
     show ErrorOr, Either2, Either4;
@@ -38,10 +46,10 @@
 /// it's important to call this immediately after computing edits to ensure
 /// the document is not modified before the version number is read.
 lsp.WorkspaceEdit createWorkspaceEdit(
-    lsp.LspAnalysisServer server, server.SourceChange change) {
+    lsp.LspAnalysisServer server, List<server.SourceFileEdit> edits) {
   return toWorkspaceEdit(
       server.clientCapabilities?.workspace,
-      change.edits
+      edits
           .map((e) => new FileEditInformation(
               server.getVersionedDocumentIdentifier(e.file),
               server.getLineInfo(e.file),
@@ -102,6 +110,7 @@
     switch (kind) {
       case server.ElementKind.CLASS:
       case server.ElementKind.CLASS_TYPE_ALIAS:
+      case server.ElementKind.MIXIN:
         return const [lsp.CompletionItemKind.Class];
       case server.ElementKind.COMPILATION_UNIT:
         return const [lsp.CompletionItemKind.Module];
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 32ce7a5..ace0a49 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -983,4 +983,10 @@
       'workspaceEdit': {'documentChanges': true}
     });
   }
+
+  WorkspaceClientCapabilities withApplyEditSupport(
+    WorkspaceClientCapabilities source,
+  ) {
+    return extendWorkspaceCapabilities(source, {'applyEdit': true});
+  }
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index 3d6bd02..659921c 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -16,6 +16,10 @@
 
 Note: In LSP the client makes the first request so there is no obvious confirmation that the server is working correctly until the client sends an `initialize` request. Unlike standard JSON RPC, [LSP requires that headers are sent](https://microsoft.github.io/language-server-protocol/specification).
 
+## Initialization Options
+
+- `onlyAnalyzeProjectsWithOpenFiles`: When set to `true`, analysis will only be performed for projects that have open files rather than the root workspace folder. Defaults to `false`.
+
 ## Method Status
 
 Below is a list of LSP methods and their implementation status.
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index 7d6f52d..f0561e0 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -40,8 +40,8 @@
   final String outFolder = path.join(packageFolder, 'lib', 'lsp_protocol');
   new Directory(outFolder).createSync();
 
-  await writeSpecClasses(args, outFolder);
   await writeCustomClasses(args, outFolder);
+  await writeSpecClasses(args, outFolder);
 }
 
 Future writeSpecClasses(ArgResults args, String outFolder) async {
@@ -66,8 +66,8 @@
 
   final String output = generateDartForTypes(types);
 
-  new File(path.join(outFolder, 'protocol_generated.dart'))
-      .writeAsStringSync(generatedFileHeader(2018) + output);
+  new File(path.join(outFolder, 'protocol_generated.dart')).writeAsStringSync(
+      generatedFileHeader(2018, importCustom: true) + output);
 }
 
 /// Writes classes used by Dart's custom LSP methods.
@@ -118,7 +118,7 @@
       comment, new Token.identifier('Method'), methodConstants);
 }
 
-String generatedFileHeader(int year) => '''
+String generatedFileHeader(int year, {bool importCustom = false}) => '''
 // Copyright (c) $year, 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.
@@ -135,6 +135,7 @@
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
 import 'dart:convert' show JsonEncoder;
+${importCustom ? "import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';" : ''}
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/protocol/protocol_internal.dart'
     show listEqual, mapEqual;