[analysis_server] Support dart.updateImportsOnRename setting for updating directives on renames

This setting is already supported in VS Code but accidentally stopped working in the switch to LSP. This change prevents/removes the registration for willRenameFiles so that a client won't call the server when files are renamed if this setting is `false`.

Change-Id: Ia7b22b9fc2f119d0e7f98f4e2c5f0bac994a28af
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/247544
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Danny Tuppeny 2022-06-08 16:06:52 +00:00 committed by Commit Bot
parent 595ec38f27
commit 88c2f888ea
4 changed files with 85 additions and 2 deletions

View file

@ -213,5 +213,17 @@ class LspResourceClientConfiguration {
/// Values are "always", "prompt", "never". Any other values should be treated
/// like "never".
String get renameFilesWithClasses =>
_settings['renameFilesWithClasses'] as String? ?? 'never';
_settings['renameFilesWithClasses'] as String? ??
_fallback?.renameFilesWithClasses ??
'never';
/// Whether to update imports and other directives when files are renamed.
///
/// This setting works by controlling whether the server registers for
/// `willRenameFiles` requests from the client. Changing the value after
/// initialization will register/unregister appropriately.
bool get updateImportsOnRename =>
_settings['updateImportsOnRename'] as bool? ??
_fallback?.updateImportsOnRename ??
true;
}

View file

@ -341,6 +341,8 @@ class ServerCapabilitiesComputer {
_server.clientConfiguration.global.enableSdkFormatter;
final previewCommitCharacters =
_server.clientConfiguration.global.previewCommitCharacters;
final updateImportsOnRename =
_server.clientConfiguration.global.updateImportsOnRename;
/// Helper for creating registrations with IDs.
void register(bool condition, Method method, [ToJsonable? options]) {
@ -486,7 +488,7 @@ class ServerCapabilitiesComputer {
TextDocumentRegistrationOptions(documentSelector: fullySupportedTypes),
);
register(
dynamicRegistrations.fileOperations,
updateImportsOnRename && dynamicRegistrations.fileOperations,
Method.workspace_willRenameFiles,
fileOperationRegistrationOptions,
);

View file

@ -18,6 +18,74 @@ void main() {
@reflectiveTest
class WillRenameFilesTest extends AbstractLspAnalysisServerTest {
bool isWillRenameFilesRegistration(Registration registration) =>
registration.method == Method.workspace_willRenameFiles.toJson();
Future<void> test_registration_defaultsEnabled() async {
final registrations = <Registration>[];
await monitorDynamicRegistrations(
registrations,
() => initialize(
workspaceCapabilities: withAllSupportedWorkspaceDynamicRegistrations(
emptyWorkspaceClientCapabilities),
),
);
expect(
registrations.where(isWillRenameFilesRegistration),
hasLength(1),
);
}
Future<void> test_registration_disabled() async {
final registrations = <Registration>[];
await provideConfig(
() => monitorDynamicRegistrations(
registrations,
() => initialize(
textDocumentCapabilities:
withAllSupportedTextDocumentDynamicRegistrations(
emptyTextDocumentClientCapabilities),
workspaceCapabilities: withAllSupportedWorkspaceDynamicRegistrations(
withConfigurationSupport(emptyWorkspaceClientCapabilities)),
),
),
{'updateImportsOnRename': false},
);
expect(
registrations.where(isWillRenameFilesRegistration),
isEmpty,
);
}
Future<void> test_registration_disabledThenEnabled() async {
// Start disabled.
await provideConfig(
() => initialize(
textDocumentCapabilities:
withAllSupportedTextDocumentDynamicRegistrations(
emptyTextDocumentClientCapabilities),
workspaceCapabilities: withAllSupportedWorkspaceDynamicRegistrations(
withConfigurationSupport(emptyWorkspaceClientCapabilities)),
),
{'updateImportsOnRename': false},
);
// Collect any new registrations when enabled.
final registrations = <Registration>[];
await monitorDynamicRegistrations(
registrations,
() => updateConfig({'updateImportsOnRename': true}),
);
// Expect that willRenameFiles was included.
expect(
registrations.where(isWillRenameFilesRegistration),
hasLength(1),
);
}
Future<void> test_rename_updatesImports() async {
final otherFilePath = join(projectFolderPath, 'lib', 'other.dart');
final otherFileUri = Uri.file(otherFilePath);

View file

@ -40,6 +40,7 @@ Client workspace settings are requested with `workspace/configuration` during in
- `dart.showTodos` (`bool?`): Whether to generate diagnostics for TODO comments. If unspecified, diagnostics will not be generated.
- `dart.renameFilesWithClasses` (`String`): When set to `"always"`, will include edits to rename files when classes are renamed if the filename matches the class name (but in snake_form). When set to `"prompt"`, a prompt will be shown on each class rename asking to confirm the file rename. Otherwise, files will not be renamed. Renames are performed using LSP's ResourceOperation edits - that means the rename is simply included in the resulting `WorkspaceEdit` and must be handled by the client.
- `dart.enableSnippets` (`bool?`): Whether to include code snippets (such as `class`, `stful`, `switch`) in code completion. When unspecified, snippets will be included.
- `dart.updateImportsOnRename` (`bool?`): Whether to update imports and other directives when files are renamed. When unspecified, imports will be updated if the client supports `willRenameFiles` requests.
## Method Status