Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 2c74e62

Browse files
author
Dart CI
committed
Version 2.12.0-113.0.dev
Merge commit 'd86f0e2836d0941776f911dfc86ff444121fd29d' into 'dev'
2 parents a37a4d4 + d86f0e2 commit 2c74e62

File tree

63 files changed

+1428
-347
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1428
-347
lines changed

pkg/analysis_server/doc/api.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
<body>
110110
<h1>Analysis Server API Specification</h1>
111111
<h1 style="color:#999999">Version
112-
1.32.0
112+
1.32.1
113113
</h1>
114114
<p>
115115
This document contains a specification of the API provided by the
@@ -235,6 +235,11 @@ <h3>Enumerations</h3>
235235
the server so clients should ensure unknown values are handled gracefully, either
236236
ignoring the item or treating it with some default/fallback handling.
237237
</p>
238+
<h3>Changelog</h3>
239+
<h4>1.32.1</h4>
240+
<ul>
241+
<li>Added <tt>CompletionSuggestionKind.PACKAGE_NAME</tt> for Pub package name completions in <tt>pubspec.yaml</tt></li>
242+
</ul>
238243
<h3>Domains</h3>
239244
<p>
240245
For convenience, the API is divided into domains. Each domain is specified

pkg/analysis_server/lib/protocol/protocol_constants.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// To regenerate the file, use the script
77
// "pkg/analysis_server/tool/spec/generate_files".
88

9-
const String PROTOCOL_VERSION = '1.32.0';
9+
const String PROTOCOL_VERSION = '1.32.1';
1010

1111
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
1212
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';

pkg/analysis_server/lib/src/lsp/mapping.dart

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,22 @@ String buildSnippetStringWithTabStops(
7474
RegExp(r'[$}\\]'), // Replace any of $ } \
7575
(c) => '\\${c[0]}', // Prefix with a backslash
7676
);
77+
7778
// Snippets syntax is documented in the LSP spec:
78-
// https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/#snippet-syntax
79+
// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax
7980
//
8081
// $1, $2, etc. are used for tab stops and ${1:foo} inserts a placeholder of foo.
8182

8283
final output = [];
8384
var offset = 0;
84-
var tabStopNumber = 1;
85+
86+
// When there's only a single tabstop, it should be ${0} as this is treated
87+
// specially as the final cursor position (if we use 1, the editor will insert
88+
// a 0 at the end of the string which is not what we expect).
89+
// When there are multiple, start with ${1} since these are placeholders the
90+
// user can tab through and the editor-inserted ${0} at the end is expected.
91+
var tabStopNumber = offsetLengthPairs.length <= 2 ? 0 : 1;
92+
8593
for (var i = 0; i < offsetLengthPairs.length; i += 2) {
8694
final pairOffset = offsetLengthPairs[i];
8795
final pairLength = offsetLengthPairs[i + 1];
@@ -852,9 +860,11 @@ lsp.CompletionItem toCompletionItem(
852860
suggestion.defaultArgumentListString,
853861
suggestion.defaultArgumentListTextRanges,
854862
)
855-
: '\${1:}'; // No required params still gets a tabstop in the parens.
863+
: '\${0:}'; // No required params still gets a tabstop in the parens.
856864
insertText += '($functionCallSuffix)';
857-
} else if (suggestion.selectionOffset != 0) {
865+
} else if (suggestion.selectionOffset != 0 &&
866+
// We don't need a tabstop if the selection is the end of the string.
867+
suggestion.selectionOffset != suggestion.completion.length) {
858868
insertTextFormat = lsp.InsertTextFormat.Snippet;
859869
insertText = buildSnippetStringWithTabStops(
860870
suggestion.completion,

pkg/analysis_server/test/lsp/completion_dart_test.dart

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ main() {
145145
final item = res.singleWhere((c) => c.label == 'myFunction(…)');
146146
// With no required params, there should still be parens and a tabstop inside.
147147
expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
148-
expect(item.insertText, equals(r'myFunction(${1:})'));
148+
expect(item.insertText, equals(r'myFunction(${0:})'));
149149
expect(item.textEdit.newText, equals(item.insertText));
150150
expect(
151151
item.textEdit.range,
@@ -170,10 +170,10 @@ main() {
170170
await openFile(mainFileUri, withoutMarkers(content));
171171
final res = await getCompletion(mainFileUri, positionFromMarker(content));
172172
final item = res.singleWhere((c) => c.label == 'min(…)');
173-
// Ensure the snippet does not include the parens/args as it doesn't
174-
// make sense in the show clause. There will still be a trailing tabstop.
175-
expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
176-
expect(item.insertText, equals(r'min${1:}'));
173+
// The insert text should be a simple string with no parens/args and
174+
// no need for snippets.
175+
expect(item.insertTextFormat, isNull);
176+
expect(item.insertText, equals(r'min'));
177177
expect(item.textEdit.newText, equals(item.insertText));
178178
}
179179

@@ -540,13 +540,45 @@ main() {
540540
expect(updated, contains('one: '));
541541
}
542542

543-
Future<void> test_namedArg_snippetStringSelection() async {
543+
Future<void> test_namedArg_snippetStringSelection_endOfString() async {
544544
final content = '''
545545
class A { const A({int one}); }
546546
@A(^)
547547
main() { }
548548
''';
549549

550+
await initialize(
551+
textDocumentCapabilities: withCompletionItemSnippetSupport(
552+
emptyTextDocumentClientCapabilities));
553+
await openFile(mainFileUri, withoutMarkers(content));
554+
final res = await getCompletion(mainFileUri, positionFromMarker(content));
555+
expect(res.any((c) => c.label == 'one: '), isTrue);
556+
final item = res.singleWhere((c) => c.label == 'one: ');
557+
// As the selection is the end of the string, there's no need for a snippet
558+
// here. Since the insert text is also the same as the label, it does not
559+
// need to be provided.
560+
expect(item.insertTextFormat, isNull);
561+
expect(item.insertText, isNull);
562+
expect(item.textEdit.newText, equals('one: '));
563+
expect(
564+
item.textEdit.range,
565+
equals(Range(
566+
start: positionFromMarker(content),
567+
end: positionFromMarker(content))),
568+
);
569+
}
570+
571+
Future<void>
572+
test_namedArgTrailing_snippetStringSelection_insideString() async {
573+
final content = '''
574+
main({int one, int two}) {
575+
main(
576+
^
577+
two: 2,
578+
);
579+
}
580+
''';
581+
550582
await initialize(
551583
textDocumentCapabilities: withCompletionItemSnippetSupport(
552584
emptyTextDocumentClientCapabilities));
@@ -557,8 +589,8 @@ main() {
557589
// Ensure the snippet comes through in the expected format with the expected
558590
// placeholder.
559591
expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
560-
expect(item.insertText, equals(r'one: ${1:}'));
561-
expect(item.textEdit.newText, equals(r'one: ${1:}'));
592+
expect(item.insertText, equals(r'one: ${0:},'));
593+
expect(item.textEdit.newText, equals(r'one: ${0:},'));
562594
expect(
563595
item.textEdit.range,
564596
equals(Range(

pkg/analysis_server/test/lsp/mapping_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class MappingTest extends AbstractLspAnalysisServerTest {
7676

7777
Future<void> test_tabStopsInSnippets_contains() async {
7878
var result = lsp.buildSnippetStringWithTabStops('a, b, c', [3, 1]);
79-
expect(result, equals(r'a, ${1:b}, c'));
79+
expect(result, equals(r'a, ${0:b}, c'));
8080
}
8181

8282
Future<void> test_tabStopsInSnippets_empty() async {
@@ -86,13 +86,13 @@ class MappingTest extends AbstractLspAnalysisServerTest {
8686

8787
Future<void> test_tabStopsInSnippets_endsWith() async {
8888
var result = lsp.buildSnippetStringWithTabStops('a, b', [3, 1]);
89-
expect(result, equals(r'a, ${1:b}'));
89+
expect(result, equals(r'a, ${0:b}'));
9090
}
9191

9292
Future<void> test_tabStopsInSnippets_escape() async {
9393
var result = lsp.buildSnippetStringWithTabStops(
9494
r'te$tstri}ng, te$tstri}ng, te$tstri}ng', [13, 11]);
95-
expect(result, equals(r'te\$tstri\}ng, ${1:te\$tstri\}ng}, te\$tstri\}ng'));
95+
expect(result, equals(r'te\$tstri\}ng, ${0:te\$tstri\}ng}, te\$tstri\}ng'));
9696
}
9797

9898
Future<void> test_tabStopsInSnippets_multiple() async {
@@ -103,6 +103,6 @@ class MappingTest extends AbstractLspAnalysisServerTest {
103103

104104
Future<void> test_tabStopsInSnippets_startsWith() async {
105105
var result = lsp.buildSnippetStringWithTabStops('a, b', [0, 1]);
106-
expect(result, equals(r'${1:a}, b'));
106+
expect(result, equals(r'${0:a}, b'));
107107
}
108108
}

0 commit comments

Comments
 (0)