diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart index 0da011a1315..8bdc1bdc10e 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart @@ -8,6 +8,8 @@ import 'dart:convert' hide JsonDecoder; +import 'package:collection/collection.dart' show QueueList; + import 'package:analysis_server_client/src/protocol/protocol_internal.dart'; // ignore_for_file: flutter_style_todos @@ -3678,7 +3680,7 @@ class SourceFileEdit implements HasToJson { List edits; SourceFileEdit(this.file, this.fileStamp, {List? edits}) - : edits = edits ?? []; + : edits = edits ?? QueueList(); factory SourceFileEdit.fromJson( JsonDecoder jsonDecoder, String jsonPath, Object? json) { diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_internal.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_internal.dart index e941230ccb7..27c7d668422 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_internal.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_internal.dart @@ -45,7 +45,12 @@ void addEditForSource(SourceFileEdit sourceFileEdit, SourceEdit sourceEdit, index++; } } - edits.insert(index, sourceEdit); + if (index == 0 && edits is Queue) { + var q = edits as Queue; + q.addFirst(sourceEdit); + } else { + edits.insert(index, sourceEdit); + } } /// Adds [edit] to the [FileEdit] for the given [file]. diff --git a/pkg/analysis_server_client/pubspec.yaml b/pkg/analysis_server_client/pubspec.yaml index 38755091a24..80895ebc09a 100644 --- a/pkg/analysis_server_client/pubspec.yaml +++ b/pkg/analysis_server_client/pubspec.yaml @@ -16,6 +16,7 @@ resolution: workspace # Use 'any' constraints here; we get our versions from the DEPS file. dependencies: + collection: any path: any pub_semver: any diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart index 6a3cacdfe26..5e9f448d70f 100644 --- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart +++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart @@ -8,6 +8,8 @@ import 'dart:convert' hide JsonDecoder; +import 'package:collection/collection.dart' show QueueList; + import 'package:analyzer_plugin/src/protocol/protocol_internal.dart'; import 'package:analyzer_plugin/src/utilities/client_uri_converter.dart'; @@ -3759,7 +3761,7 @@ class SourceFileEdit implements HasToJson { List edits; SourceFileEdit(this.file, this.fileStamp, {List? edits}) - : edits = edits ?? []; + : edits = edits ?? QueueList(); factory SourceFileEdit.fromJson( JsonDecoder jsonDecoder, String jsonPath, Object? json, diff --git a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart index 0d9e8727e68..ca90d437352 100644 --- a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart +++ b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart @@ -78,7 +78,12 @@ void addEditForSource(SourceFileEdit sourceFileEdit, SourceEdit sourceEdit, newEdit: sourceEdit, existingEdit: nextEdit); } } - edits.insert(index, sourceEdit); + if (index == 0 && edits is Queue) { + var q = edits as Queue; + q.addFirst(sourceEdit); + } else { + edits.insert(index, sourceEdit); + } } /// Adds [edit] to the [FileEdit] for the given [file]. diff --git a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart index fdb60a04240..c1ab2779506 100644 --- a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart +++ b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart @@ -54,6 +54,12 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { 'TypeHierarchyItem': ['interfaces', 'mixins', 'subclasses'], }; + /// Class members for which the list type should not be the default, + /// but QueueList for performance reasons. + static const Map> _useQueueList = { + 'SourceFileEdit': ['edits'], + }; + /// The disclaimer added to the documentation comment for each of the classes /// that are generated. static const String disclaimer = @@ -461,7 +467,12 @@ class CodegenProtocolVisitor extends DartCodegenVisitor with CodeGenerator { // given, the constructor should populate with the empty list. var fieldType = field.type; if (fieldType is TypeList) { - var defaultValue = '<${dartType(fieldType.itemType)}>[]'; + String defaultValue; + if (_useQueueList[className]?.contains(field.name) ?? false) { + defaultValue = 'QueueList<${dartType(fieldType.itemType)}>()'; + } else { + defaultValue = '<${dartType(fieldType.itemType)}>[]'; + } initializers.add('${field.name} = ${field.name} ?? $defaultValue'); } else { throw Exception("Don't know how to create default field value."); diff --git a/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart b/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart index 2e00137cef1..e13b31497ff 100644 --- a/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart +++ b/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart @@ -45,6 +45,8 @@ class CodegenCommonVisitor extends CodegenProtocolVisitor { void emitImports() { writeln("import 'dart:convert' hide JsonDecoder;"); writeln(); + writeln("import 'package:collection/collection.dart' show QueueList;"); + writeln(); if (forClient) { writeln( "import 'package:analysis_server_client/src/protocol/protocol_internal.dart';");