85700570f6
Fixes #49241 TEST=ci Change-Id: I6117bf816fc8c4613cce66927f952fef75632725 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248120 Reviewed-by: Alexander Thomas <athom@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Ben Konyi <bkonyi@google.com> Reviewed-by: Nicholas Shahan <nshahan@google.com> Commit-Queue: Alexander Thomas <athom@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
118 lines
3.6 KiB
Dart
118 lines
3.6 KiB
Dart
// Copyright (c) 2021, 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.dart';
|
|
import 'package:analyzer/source/line_info.dart';
|
|
import 'package:test/test.dart';
|
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|
|
|
import 'server_abstract.dart';
|
|
|
|
void main() {
|
|
defineReflectiveSuite(() {
|
|
defineReflectiveTests(SelectionRangeTest);
|
|
});
|
|
}
|
|
|
|
/// Additional tests are in
|
|
///
|
|
/// test/src/computer/selection_range_computer_test.dart
|
|
@reflectiveTest
|
|
class SelectionRangeTest extends AbstractLspAnalysisServerTest {
|
|
Future<void> test_multiple() async {
|
|
final content = '''
|
|
class Foo {
|
|
void a() { /*1*/ }
|
|
void b() { /*2*/ }
|
|
}
|
|
''';
|
|
|
|
await initialize();
|
|
await openFile(mainFileUri, content);
|
|
final lineInfo = LineInfo.fromContent(content);
|
|
|
|
// Send a request for two positions.
|
|
final regions = await getSelectionRanges(mainFileUri, [
|
|
positionFromOffset(content.indexOf('/*1*/'), content),
|
|
positionFromOffset(content.indexOf('/*2*/'), content),
|
|
]);
|
|
expect(regions!.length, equals(2));
|
|
final firstTexts =
|
|
_getSelectionRangeText(lineInfo, content, regions[0]).toList();
|
|
final secondTexts =
|
|
_getSelectionRangeText(lineInfo, content, regions[1]).toList();
|
|
|
|
expect(
|
|
firstTexts,
|
|
equals([
|
|
'{ /*1*/ }',
|
|
'void a() { /*1*/ }',
|
|
content.trim(), // Whole content minus the trailing newline
|
|
]));
|
|
expect(
|
|
secondTexts,
|
|
equals([
|
|
'{ /*2*/ }',
|
|
'void b() { /*2*/ }',
|
|
content.trim(), // Whole content minus the trailing newline
|
|
]));
|
|
}
|
|
|
|
Future<void> test_single() async {
|
|
final content = '''
|
|
class Foo<T> {
|
|
void a(String b) {
|
|
print((1 ^+ 2) * 3);
|
|
}
|
|
}
|
|
''';
|
|
final contentWithoutMarker = withoutMarkers(content);
|
|
|
|
await initialize();
|
|
await openFile(mainFileUri, contentWithoutMarker);
|
|
final lineInfo = LineInfo.fromContent(contentWithoutMarker);
|
|
|
|
// The returned List corresponds to the input list of positions, and not
|
|
// the set of ranges - each range within that list has a (recursive) parent
|
|
// to walk up all ranges for that position.
|
|
final regions =
|
|
await getSelectionRanges(mainFileUri, [positionFromMarker(content)]);
|
|
expect(regions!.length, equals(1)); // Only one position was sent.
|
|
final regionTexts =
|
|
_getSelectionRangeText(lineInfo, contentWithoutMarker, regions.first)
|
|
.toList();
|
|
|
|
expect(
|
|
regionTexts,
|
|
equals([
|
|
'1 + 2',
|
|
'(1 + 2)',
|
|
'(1 + 2) * 3',
|
|
'((1 + 2) * 3)',
|
|
'print((1 + 2) * 3)',
|
|
'print((1 + 2) * 3);',
|
|
'{\n print((1 + 2) * 3);\n }',
|
|
'void a(String b) {\n print((1 + 2) * 3);\n }',
|
|
'class Foo<T> {\n void a(String b) {\n print((1 + 2) * 3);\n }\n}',
|
|
]));
|
|
}
|
|
|
|
Iterable<String> _getSelectionRangeText(
|
|
LineInfo lineInfo, String content, SelectionRange range) sync* {
|
|
yield _rangeOfText(lineInfo, content, range.range);
|
|
final parent = range.parent;
|
|
if (parent != null) {
|
|
yield* _getSelectionRangeText(lineInfo, content, parent);
|
|
}
|
|
}
|
|
|
|
String _rangeOfText(LineInfo lineInfo, String content, Range range) {
|
|
final startPos = range.start;
|
|
final endPos = range.end;
|
|
final start = lineInfo.getOffsetOfLine(startPos.line) + startPos.character;
|
|
final end = lineInfo.getOffsetOfLine(endPos.line) + endPos.character;
|
|
return content.substring(start, end);
|
|
}
|
|
}
|