[analysis_server] Migrate a few more tests to TestCode from old markers
+ tweak indenting to be consistent with other tests. Most of the larger test files are done with this change, and there are around 40 remaining calls to withoutMarkers() spread across around 20 files. Change-Id: Icfa516f7ca869e09822442b02a1b2eafca692b86 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330423 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Phil Quitslund <pquitslund@google.com> Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
committed by
Commit Queue
parent
f4d9c95262
commit
e7eda9a4fc
@@ -4,10 +4,12 @@
|
||||
|
||||
import 'package:analysis_server/lsp_protocol/protocol.dart';
|
||||
import 'package:analysis_server/src/lsp/constants.dart';
|
||||
import 'package:analyzer/src/test_utilities/test_code_format.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../tool/lsp_spec/matchers.dart';
|
||||
import '../utils/test_code_extensions.dart';
|
||||
import 'server_abstract.dart';
|
||||
|
||||
void main() {
|
||||
@@ -27,16 +29,16 @@ class FormatTest extends AbstractLspAnalysisServerTest {
|
||||
}
|
||||
|
||||
Future<List<TextEdit>> expectRangeFormattedContents(
|
||||
Uri uri, String original, String expected) async {
|
||||
final formatEdits = (await formatRange(uri, rangeFromMarkers(original)))!;
|
||||
final formattedContents =
|
||||
applyTextEdits(withoutMarkers(original), formatEdits);
|
||||
Uri uri, TestCode code, String expected) async {
|
||||
final formatEdits = (await formatRange(uri, code.range.range))!;
|
||||
final formattedContents = applyTextEdits(code.code, formatEdits);
|
||||
expect(formattedContents, equals(expected));
|
||||
return formatEdits;
|
||||
}
|
||||
|
||||
Future<void> test_alreadyFormatted() async {
|
||||
const contents = '''void f() {
|
||||
const contents = '''
|
||||
void f() {
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
@@ -159,23 +161,23 @@ ErrorOr<Pair<A, List<B>>> c(
|
||||
|
||||
Future<void> test_formatOnType_simple() async {
|
||||
const contents = '''
|
||||
void f ()
|
||||
{
|
||||
void f ()
|
||||
{
|
||||
|
||||
print('test');
|
||||
^}
|
||||
print('test');
|
||||
^}
|
||||
''';
|
||||
final expected = '''void f() {
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(contents);
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(contents));
|
||||
await openFile(mainFileUri, code.code);
|
||||
|
||||
final formatEdits =
|
||||
(await formatOnType(mainFileUri, positionFromMarker(contents), '}'))!;
|
||||
final formattedContents =
|
||||
applyTextEdits(withoutMarkers(contents), formatEdits);
|
||||
(await formatOnType(mainFileUri, code.position.position, '}'))!;
|
||||
final formattedContents = applyTextEdits(code.code, formatEdits);
|
||||
expect(formattedContents, equals(expected));
|
||||
}
|
||||
|
||||
@@ -185,9 +187,9 @@ ErrorOr<Pair<A, List<B>>> c(
|
||||
const contents = '''
|
||||
void f()
|
||||
{
|
||||
[[ print('test');
|
||||
[! print('test');
|
||||
print('test');
|
||||
]] print('test');
|
||||
!] print('test');
|
||||
}
|
||||
''';
|
||||
final expected = '''
|
||||
@@ -198,9 +200,10 @@ void f()
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(contents);
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(contents));
|
||||
await expectRangeFormattedContents(mainFileUri, contents, expected);
|
||||
await openFile(mainFileUri, code.code);
|
||||
await expectRangeFormattedContents(mainFileUri, code, expected);
|
||||
}
|
||||
|
||||
Future<void> test_formatRange_expandsLeadingWhitespaceToNearestLine() async {
|
||||
@@ -208,9 +211,9 @@ void f()
|
||||
void f()
|
||||
{
|
||||
|
||||
[[ print('test'); // line 2
|
||||
[! print('test'); // line 2
|
||||
print('test'); // line 3
|
||||
print('test'); // line 4]]
|
||||
print('test'); // line 4!]
|
||||
}
|
||||
''';
|
||||
const expected = '''
|
||||
@@ -222,9 +225,10 @@ void f()
|
||||
print('test'); // line 4
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(contents);
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(contents));
|
||||
await expectRangeFormattedContents(mainFileUri, contents, expected);
|
||||
await openFile(mainFileUri, code.code);
|
||||
await expectRangeFormattedContents(mainFileUri, code, expected);
|
||||
}
|
||||
|
||||
Future<void> test_formatRange_invalidRange() async {
|
||||
@@ -234,8 +238,9 @@ void f()
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(contents);
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(contents));
|
||||
await openFile(mainFileUri, code.code);
|
||||
final formatRangeRequest = formatRange(
|
||||
mainFileUri,
|
||||
Range(
|
||||
@@ -254,11 +259,11 @@ main ()
|
||||
print('test');
|
||||
}
|
||||
|
||||
[[main2 ()
|
||||
[!main2 ()
|
||||
{
|
||||
|
||||
print('test');
|
||||
}]]
|
||||
}!]
|
||||
|
||||
main3 ()
|
||||
{
|
||||
@@ -283,9 +288,10 @@ main3 ()
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(contents);
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(contents));
|
||||
await expectRangeFormattedContents(mainFileUri, contents, expected);
|
||||
await openFile(mainFileUri, code.code);
|
||||
await expectRangeFormattedContents(mainFileUri, code, expected);
|
||||
}
|
||||
|
||||
Future<void> test_formatRange_trailingNewline_47702() async {
|
||||
@@ -293,9 +299,9 @@ main3 ()
|
||||
// https://github.com/dart-lang/sdk/issues/47702
|
||||
const contents = '''
|
||||
int a;
|
||||
[[
|
||||
[!
|
||||
int b;
|
||||
]]
|
||||
!]
|
||||
''';
|
||||
final expected = '''
|
||||
int a;
|
||||
@@ -303,13 +309,15 @@ int a;
|
||||
int b;
|
||||
|
||||
''';
|
||||
final code = TestCode.parse(contents);
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(contents));
|
||||
await expectRangeFormattedContents(mainFileUri, contents, expected);
|
||||
await openFile(mainFileUri, code.code);
|
||||
await expectRangeFormattedContents(mainFileUri, code, expected);
|
||||
}
|
||||
|
||||
Future<void> test_invalidSyntax() async {
|
||||
const contents = '''void f(((( {
|
||||
const contents = '''
|
||||
void f(((( {
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
@@ -322,15 +330,18 @@ int b;
|
||||
|
||||
Future<void> test_lineLength() async {
|
||||
const contents = '''
|
||||
void f() =>
|
||||
print(
|
||||
'123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789'
|
||||
);
|
||||
void f() =>
|
||||
print(
|
||||
'123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789'
|
||||
);
|
||||
''';
|
||||
final expectedDefault = '''void f() => print(
|
||||
'123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789');\n''';
|
||||
final expectedLongLines =
|
||||
'''void f() => print('123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789');\n''';
|
||||
final expectedDefault = '''
|
||||
void f() => print(
|
||||
'123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789');
|
||||
''';
|
||||
final expectedLongLines = '''
|
||||
void f() => print('123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789');
|
||||
''';
|
||||
|
||||
// Initialize with config support, supplying an empty config when requested.
|
||||
await provideConfig(
|
||||
@@ -659,7 +670,8 @@ void f() {
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
final expected = '''void f() {
|
||||
final expected = '''
|
||||
void f() {
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
@@ -676,7 +688,8 @@ void f() {
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
final expected = '''void f() {
|
||||
final expected = '''
|
||||
void f() {
|
||||
print('test');
|
||||
}
|
||||
''';
|
||||
@@ -686,13 +699,15 @@ void f() {
|
||||
}
|
||||
|
||||
Future<void> test_validSyntax_withErrors() async {
|
||||
// We should still be able to format syntactically valid code even if it has analysis
|
||||
// errors.
|
||||
const contents = '''void f() {
|
||||
// We should still be able to format syntactically valid code even if it has
|
||||
// analysis errors.
|
||||
const contents = '''
|
||||
void f() {
|
||||
print(a);
|
||||
}
|
||||
''';
|
||||
const expected = '''void f() {
|
||||
const expected = '''
|
||||
void f() {
|
||||
print(a);
|
||||
}
|
||||
''';
|
||||
|
||||
@@ -8,11 +8,13 @@ import 'package:analysis_server/src/lsp/constants.dart';
|
||||
import 'package:analysis_server/src/lsp/semantic_tokens/legend.dart';
|
||||
import 'package:analysis_server/src/protocol/protocol_internal.dart';
|
||||
import 'package:analyzer/src/dart/analysis/experiments.dart';
|
||||
import 'package:analyzer/src/test_utilities/test_code_format.dart';
|
||||
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
|
||||
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../utils/test_code_extensions.dart';
|
||||
import 'server_abstract.dart';
|
||||
|
||||
void main() {
|
||||
@@ -31,35 +33,38 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_annotation() async {
|
||||
final content = '''
|
||||
import 'other_file.dart' as other;
|
||||
import 'other_file.dart' as other;
|
||||
|
||||
@a
|
||||
@A()
|
||||
@A.n()
|
||||
@B(A())
|
||||
@other.C()
|
||||
@other.C.n()
|
||||
void foo() {}
|
||||
@a
|
||||
@A()
|
||||
@A.n()
|
||||
@B(A())
|
||||
@other.C()
|
||||
@other.C.n()
|
||||
void foo() {}
|
||||
|
||||
class A {
|
||||
const A();
|
||||
const A.n();
|
||||
}
|
||||
class A {
|
||||
const A();
|
||||
const A.n();
|
||||
}
|
||||
|
||||
const a = A();
|
||||
const a = A();
|
||||
|
||||
class B {
|
||||
final A a;
|
||||
const B(this.a);
|
||||
}
|
||||
''';
|
||||
class B {
|
||||
final A a;
|
||||
const B(this.a);
|
||||
}
|
||||
''';
|
||||
|
||||
final otherContent = '''
|
||||
class C {
|
||||
const C();
|
||||
const C.n();
|
||||
}
|
||||
''';
|
||||
class C {
|
||||
const C();
|
||||
const C.n();
|
||||
}
|
||||
''';
|
||||
|
||||
final code = TestCode.parse(content);
|
||||
final otherCode = TestCode.parse(otherContent);
|
||||
|
||||
final expectedStart = [
|
||||
_Token('import', SemanticTokenTypes.keyword),
|
||||
@@ -123,8 +128,8 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
final otherFileUri = pathContext.toUri(otherFilePath);
|
||||
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(content));
|
||||
await openFile(otherFileUri, withoutMarkers(otherContent));
|
||||
await openFile(mainFileUri, code.code);
|
||||
await openFile(otherFileUri, otherCode.code);
|
||||
|
||||
final tokens = await getSemanticTokens(mainFileUri);
|
||||
final decoded = _decodeSemanticTokens(content, tokens);
|
||||
@@ -138,13 +143,13 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_class() async {
|
||||
final content = '''
|
||||
/// class docs
|
||||
class MyClass<T> {
|
||||
// class comment
|
||||
}
|
||||
/// class docs
|
||||
class MyClass<T> {
|
||||
// class comment
|
||||
}
|
||||
|
||||
// Trailing comment
|
||||
''';
|
||||
// Trailing comment
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('/// class docs', SemanticTokenTypes.comment,
|
||||
@@ -162,18 +167,18 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_class_constructors() async {
|
||||
final content = '''
|
||||
class MyClass {
|
||||
const MyClass();
|
||||
MyClass.named();
|
||||
factory MyClass.factory() => MyClass();
|
||||
}
|
||||
class MyClass {
|
||||
const MyClass();
|
||||
MyClass.named();
|
||||
factory MyClass.factory() => MyClass();
|
||||
}
|
||||
|
||||
final a = MyClass();
|
||||
final b = MyClass.named();
|
||||
final c = MyClass.factory();
|
||||
final d = MyClass.named;
|
||||
const e = const MyClass();
|
||||
''';
|
||||
final a = MyClass();
|
||||
final b = MyClass.named();
|
||||
final c = MyClass.factory();
|
||||
final d = MyClass.named;
|
||||
const e = const MyClass();
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('class', SemanticTokenTypes.keyword),
|
||||
@@ -241,19 +246,19 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_class_fields() async {
|
||||
final content = '''
|
||||
class MyClass {
|
||||
/// field docs
|
||||
String myField = 'FieldVal';
|
||||
/// static field docs
|
||||
static String myStaticField = 'StaticFieldVal';
|
||||
}
|
||||
class MyClass {
|
||||
/// field docs
|
||||
String myField = 'FieldVal';
|
||||
/// static field docs
|
||||
static String myStaticField = 'StaticFieldVal';
|
||||
}
|
||||
|
||||
void f() {
|
||||
final a = MyClass();
|
||||
print(a.myField);
|
||||
MyClass.myStaticField = 'a';
|
||||
}
|
||||
''';
|
||||
void f() {
|
||||
final a = MyClass();
|
||||
print(a.myField);
|
||||
MyClass.myStaticField = 'a';
|
||||
}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('class', SemanticTokenTypes.keyword),
|
||||
@@ -298,23 +303,23 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_class_getterSetter() async {
|
||||
final content = '''
|
||||
class MyClass {
|
||||
/// getter docs
|
||||
String get myGetter => 'GetterVal';
|
||||
/// setter docs
|
||||
set mySetter(String v) {};
|
||||
/// static getter docs
|
||||
static String get myStaticGetter => 'StaticGetterVal';
|
||||
/// static setter docs
|
||||
static set myStaticSetter(String staticV) {};
|
||||
}
|
||||
class MyClass {
|
||||
/// getter docs
|
||||
String get myGetter => 'GetterVal';
|
||||
/// setter docs
|
||||
set mySetter(String v) {};
|
||||
/// static getter docs
|
||||
static String get myStaticGetter => 'StaticGetterVal';
|
||||
/// static setter docs
|
||||
static set myStaticSetter(String staticV) {};
|
||||
}
|
||||
|
||||
void f() {
|
||||
final a = MyClass();
|
||||
print(a.myGetter);
|
||||
a.mySetter = 'a';
|
||||
}
|
||||
''';
|
||||
void f() {
|
||||
final a = MyClass();
|
||||
print(a.myGetter);
|
||||
a.mySetter = 'a';
|
||||
}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('class', SemanticTokenTypes.keyword),
|
||||
@@ -380,24 +385,24 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_class_method() async {
|
||||
final content = '''
|
||||
class MyClass {
|
||||
/// method docs
|
||||
@override
|
||||
void myMethod() {}
|
||||
/// static method docs
|
||||
static void myStaticMethod() {
|
||||
// static method comment
|
||||
}
|
||||
}
|
||||
class MyClass {
|
||||
/// method docs
|
||||
@override
|
||||
void myMethod() {}
|
||||
/// static method docs
|
||||
static void myStaticMethod() {
|
||||
// static method comment
|
||||
}
|
||||
}
|
||||
|
||||
void f() {
|
||||
final a = MyClass();
|
||||
a.myMethod();
|
||||
MyClass.myStaticMethod();
|
||||
final b = a.myMethod;
|
||||
final c = MyClass.myStaticMethod;
|
||||
}
|
||||
''';
|
||||
void f() {
|
||||
final a = MyClass();
|
||||
a.myMethod();
|
||||
MyClass.myStaticMethod();
|
||||
final b = a.myMethod;
|
||||
final c = MyClass.myStaticMethod;
|
||||
}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('class', SemanticTokenTypes.keyword),
|
||||
@@ -456,14 +461,14 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_dartdoc() async {
|
||||
final content = '''
|
||||
/// before [aaa] after
|
||||
class MyClass {
|
||||
String aaa;
|
||||
}
|
||||
/// before [aaa] after
|
||||
class MyClass {
|
||||
String aaa;
|
||||
}
|
||||
|
||||
/// before [bbb] after
|
||||
int double(int bbb) => bbb * 2;
|
||||
''';
|
||||
/// before [bbb] after
|
||||
int double(int bbb) => bbb * 2;
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('/// before [', SemanticTokenTypes.comment,
|
||||
@@ -500,14 +505,14 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_directives() async {
|
||||
final content = '''
|
||||
import 'package:flutter/material.dart';
|
||||
export 'package:flutter/widgets.dart';
|
||||
import '../file.dart'
|
||||
if (dart.library.io) 'file_io.dart'
|
||||
if (dart.library.html) 'file_html.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
export 'package:flutter/widgets.dart';
|
||||
import '../file.dart'
|
||||
if (dart.library.io) 'file_io.dart'
|
||||
if (dart.library.html) 'file_html.dart';
|
||||
|
||||
library foo;
|
||||
''';
|
||||
library foo;
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('import', SemanticTokenTypes.keyword),
|
||||
@@ -537,8 +542,8 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_extension() async {
|
||||
final content = '''
|
||||
extension A on String {}
|
||||
''';
|
||||
extension A on String {}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('extension', SemanticTokenTypes.keyword),
|
||||
@@ -554,6 +559,7 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
final pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.foo');
|
||||
final pluginAnalyzedFileUri = pathContext.toUri(pluginAnalyzedFilePath);
|
||||
final content = 'CLASS STRING VARIABLE';
|
||||
final code = TestCode.parse(content);
|
||||
|
||||
final expected = [
|
||||
_Token('CLASS', SemanticTokenTypes.class_),
|
||||
@@ -563,7 +569,7 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
];
|
||||
|
||||
await initialize();
|
||||
await openFile(pluginAnalyzedFileUri, withoutMarkers(content));
|
||||
await openFile(pluginAnalyzedFileUri, code.code);
|
||||
|
||||
final pluginResult = plugin.AnalysisHighlightsParams(
|
||||
pluginAnalyzedFilePath,
|
||||
@@ -583,22 +589,23 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_invalidSyntax() async {
|
||||
final content = '''
|
||||
/// class docs
|
||||
class MyClass {
|
||||
// class comment
|
||||
}
|
||||
/// class docs
|
||||
class MyClass {
|
||||
// class comment
|
||||
}
|
||||
|
||||
this is not valid code.
|
||||
this is not valid code.
|
||||
|
||||
/// class docs 2
|
||||
class MyClass2 {
|
||||
// class comment 2
|
||||
}
|
||||
''';
|
||||
/// class docs 2
|
||||
class MyClass2 {
|
||||
// class comment 2
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(content);
|
||||
|
||||
// Expect the correct tokens for the valid code before/after but don't
|
||||
// check the tokens for the invalid code as there are no concrete
|
||||
// expectations for them.
|
||||
// Expect the correct tokens for the valid code before/after but don't
|
||||
// check the tokens for the invalid code as there are no concrete
|
||||
// expectations for them.
|
||||
final expected1 = [
|
||||
_Token('/// class docs', SemanticTokenTypes.comment,
|
||||
[SemanticTokenModifiers.documentation]),
|
||||
@@ -617,7 +624,7 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
];
|
||||
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(content));
|
||||
await openFile(mainFileUri, code.code);
|
||||
|
||||
final tokens = await getSemanticTokens(mainFileUri);
|
||||
final decoded = _decodeSemanticTokens(content, tokens);
|
||||
@@ -632,18 +639,18 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
// "control" keywords should be tagged with a modifier so the client
|
||||
// can color them differently to other keywords.
|
||||
final content = r'''
|
||||
void f() async {
|
||||
var a = new Object();
|
||||
await null;
|
||||
if (false) {
|
||||
print('test');
|
||||
}
|
||||
for (var item in []);
|
||||
switch (1) {
|
||||
case int(:var isEven) when isEven:
|
||||
}
|
||||
}
|
||||
''';
|
||||
void f() async {
|
||||
var a = new Object();
|
||||
await null;
|
||||
if (false) {
|
||||
print('test');
|
||||
}
|
||||
for (var item in []);
|
||||
switch (1) {
|
||||
case int(:var isEven) when isEven:
|
||||
}
|
||||
}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('void', SemanticTokenTypes.keyword,
|
||||
@@ -713,7 +720,8 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
}
|
||||
|
||||
Future<void> test_lastLine_multilineComment() async {
|
||||
final content = '''/**
|
||||
final content = '''
|
||||
/**
|
||||
* Trailing comment
|
||||
*/''';
|
||||
|
||||
@@ -731,11 +739,11 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_local() async {
|
||||
final content = '''
|
||||
void f() {
|
||||
func(String a) => print(a);
|
||||
final funcTearOff = func;
|
||||
}
|
||||
''';
|
||||
void f() {
|
||||
func(String a) => print(a);
|
||||
final funcTearOff = func;
|
||||
}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token(
|
||||
@@ -759,36 +767,36 @@ class SemanticTokensTest extends AbstractLspAnalysisServerTest {
|
||||
}
|
||||
|
||||
Future<void> test_manyBools_bug() async {
|
||||
// Similar to test_manyImports_sortBug, this code triggered inconsistent tokens
|
||||
// for "false" because tokens were sorted incorrectly (because both boolean and
|
||||
// keyword had the same offset and length, which is all that were sorted by).
|
||||
// Similar to test_manyImports_sortBug, this code triggered inconsistent tokens
|
||||
// for "false" because tokens were sorted incorrectly (because both boolean and
|
||||
// keyword had the same offset and length, which is all that were sorted by).
|
||||
final content = '''
|
||||
class MyTestClass {
|
||||
/// test
|
||||
/// test
|
||||
bool test1 = false;
|
||||
/// test
|
||||
/// test
|
||||
bool test1 = false;
|
||||
|
||||
/// test
|
||||
/// test
|
||||
bool test2 = false;
|
||||
/// test
|
||||
/// test
|
||||
bool test2 = false;
|
||||
|
||||
/// test
|
||||
/// test
|
||||
bool test3 = false;
|
||||
/// test
|
||||
/// test
|
||||
bool test3 = false;
|
||||
|
||||
/// test
|
||||
/// test
|
||||
bool test4 = false;
|
||||
/// test
|
||||
/// test
|
||||
bool test4 = false;
|
||||
|
||||
/// test
|
||||
/// test
|
||||
bool test5 = false;
|
||||
/// test
|
||||
/// test
|
||||
bool test5 = false;
|
||||
|
||||
/// test
|
||||
/// test
|
||||
bool test6 = false;
|
||||
/// test
|
||||
/// test
|
||||
bool test6 = false;
|
||||
}
|
||||
''';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('class', SemanticTokenTypes.keyword),
|
||||
@@ -812,12 +820,12 @@ class MyTestClass {
|
||||
}
|
||||
|
||||
Future<void> test_manyImports_sortBug() async {
|
||||
// This test is for a bug where some "import" tokens would not be highlighted
|
||||
// correctly. Imports are made up of a DIRECTIVE token that spans a
|
||||
// BUILT_IN ("import") and LITERAL_STRING. The original code sorted by only
|
||||
// offset when handling overlapping tokens, which for certain lists (such as
|
||||
// the one created for the code below) would result in the BUILTIN coming before
|
||||
// the DIRECTIVE, which resulted in the DIRECTIVE overwriting it.
|
||||
// This test is for a bug where some "import" tokens would not be highlighted
|
||||
// correctly. Imports are made up of a DIRECTIVE token that spans a
|
||||
// BUILT_IN ("import") and LITERAL_STRING. The original code sorted by only
|
||||
// offset when handling overlapping tokens, which for certain lists (such as
|
||||
// the one created for the code below) would result in the BUILTIN coming before
|
||||
// the DIRECTIVE, which resulted in the DIRECTIVE overwriting it.
|
||||
final content = '''
|
||||
import 'dart:async';
|
||||
import 'dart:async';
|
||||
@@ -832,7 +840,7 @@ import 'dart:async';
|
||||
import 'dart:async';
|
||||
import 'dart:async';
|
||||
import 'dart:async';
|
||||
''';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
for (var i = 0; i < 13; i++) ...[
|
||||
@@ -853,7 +861,7 @@ import 'dart:async';
|
||||
* multiple lines
|
||||
*/
|
||||
class MyClass {}
|
||||
''';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('/**\n', SemanticTokenTypes.comment,
|
||||
@@ -878,10 +886,10 @@ class MyClass {}
|
||||
|
||||
Future<void> test_namedArguments() async {
|
||||
final content = '''
|
||||
f({String a}) {
|
||||
f(a: a);
|
||||
}
|
||||
''';
|
||||
f({String a}) {
|
||||
f(a: a);
|
||||
}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('f', SemanticTokenTypes.function,
|
||||
@@ -900,9 +908,9 @@ class MyClass {}
|
||||
|
||||
Future<void> test_never() async {
|
||||
final content = '''
|
||||
Never f() => throw '';
|
||||
Never? g() => throw '';
|
||||
''';
|
||||
Never f() => throw '';
|
||||
Never? g() => throw '';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('Never', SemanticTokenTypes.type),
|
||||
@@ -929,7 +937,7 @@ void f() {
|
||||
<int>[a, b] = [1, 2];
|
||||
var [c, d] = [1, 2];
|
||||
}
|
||||
''';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('void', SemanticTokenTypes.keyword,
|
||||
@@ -965,7 +973,7 @@ void f() {
|
||||
case [var c, == 'a'] when c != null:
|
||||
}
|
||||
}
|
||||
''';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('void', SemanticTokenTypes.keyword,
|
||||
@@ -997,7 +1005,7 @@ void f() {
|
||||
case int(isEven: var isEven) when isEven:
|
||||
}
|
||||
}
|
||||
''';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('void', SemanticTokenTypes.keyword,
|
||||
@@ -1030,7 +1038,7 @@ void f() {
|
||||
case int(:var isEven) when isEven:
|
||||
}
|
||||
}
|
||||
''';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('void', SemanticTokenTypes.keyword,
|
||||
@@ -1056,13 +1064,13 @@ void f() {
|
||||
|
||||
Future<void> test_range() async {
|
||||
final content = '''
|
||||
/// class docs
|
||||
class [[MyClass<T> {
|
||||
// class comment
|
||||
}]]
|
||||
/// class docs
|
||||
class [!MyClass<T> {
|
||||
// class comment
|
||||
}!]
|
||||
|
||||
// Trailing comment
|
||||
''';
|
||||
// Trailing comment
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('MyClass', SemanticTokenTypes.class_,
|
||||
@@ -1075,14 +1083,14 @@ void f() {
|
||||
}
|
||||
|
||||
Future<void> test_range_entireFile() async {
|
||||
final content = '''[[
|
||||
/// class docs
|
||||
class MyClass<T> {
|
||||
// class comment
|
||||
}
|
||||
final content = '''[!
|
||||
/// class docs
|
||||
class MyClass<T> {
|
||||
// class comment
|
||||
}
|
||||
|
||||
// Trailing comment
|
||||
]]''';
|
||||
// Trailing comment
|
||||
!]''';
|
||||
|
||||
final expected = [
|
||||
_Token('/// class docs', SemanticTokenTypes.comment,
|
||||
@@ -1100,21 +1108,21 @@ void f() {
|
||||
|
||||
Future<void> test_range_multilineRegions() async {
|
||||
final content = '''
|
||||
/**
|
||||
* This is my class comment
|
||||
*
|
||||
* [[There are
|
||||
* multiple lines
|
||||
*/
|
||||
class]] MyClass {}
|
||||
''';
|
||||
/**
|
||||
* This is my class comment
|
||||
*
|
||||
* [!There are
|
||||
* multiple lines
|
||||
*/
|
||||
class!] MyClass {}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token(' * There are\n', SemanticTokenTypes.comment,
|
||||
_Token(' * There are\n', SemanticTokenTypes.comment,
|
||||
[SemanticTokenModifiers.documentation]),
|
||||
_Token(' * multiple lines\n', SemanticTokenTypes.comment,
|
||||
_Token(' * multiple lines\n', SemanticTokenTypes.comment,
|
||||
[SemanticTokenModifiers.documentation]),
|
||||
_Token(' */', SemanticTokenTypes.comment,
|
||||
_Token(' */', SemanticTokenTypes.comment,
|
||||
[SemanticTokenModifiers.documentation]),
|
||||
_Token('class', SemanticTokenTypes.keyword),
|
||||
];
|
||||
@@ -1123,14 +1131,14 @@ void f() {
|
||||
}
|
||||
|
||||
Future<void> test_sort_sameOffsets() async {
|
||||
// This code initially (before merging) produces a String token starting at
|
||||
// offset 11 (as it drops out of one interpolated variable) and then a new
|
||||
// Interpolatation token.
|
||||
// This test is to ensure the assertion in `offsetLengthPrioritySort` does
|
||||
// not trigger (as it does if length is ignored, which was a bug).
|
||||
// This code initially (before merging) produces a String token starting at
|
||||
// offset 11 (as it drops out of one interpolated variable) and then a new
|
||||
// Interpolatation token.
|
||||
// This test is to ensure the assertion in `offsetLengthPrioritySort` does
|
||||
// not trigger (as it does if length is ignored, which was a bug).
|
||||
final content = r'''
|
||||
var a = '$s$s';
|
||||
''';
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('var', SemanticTokenTypes.keyword),
|
||||
@@ -1269,24 +1277,24 @@ const string3 = 'unicode \u1234\u123499\u{123456}\u{12345699}';
|
||||
|
||||
Future<void> test_topLevel() async {
|
||||
final content = '''
|
||||
/// strings docs
|
||||
const strings = <String>["test", 'test', r'test', \'''test\'''];
|
||||
/// strings docs
|
||||
const strings = <String>["test", 'test', r'test', \'''test\'''];
|
||||
|
||||
/// func docs
|
||||
func(String a) => print(a);
|
||||
/// func docs
|
||||
func(String a) => print(a);
|
||||
|
||||
/// abc docs
|
||||
bool get abc => true;
|
||||
/// abc docs
|
||||
bool get abc => true;
|
||||
|
||||
final funcTearOff = func;
|
||||
final funcTearOff = func;
|
||||
|
||||
void f() {
|
||||
strings;
|
||||
func;
|
||||
abc;
|
||||
funcTearOff;
|
||||
}
|
||||
''';
|
||||
void f() {
|
||||
strings;
|
||||
func;
|
||||
abc;
|
||||
funcTearOff;
|
||||
}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token('/// strings docs', SemanticTokenTypes.comment,
|
||||
@@ -1338,14 +1346,14 @@ const string3 = 'unicode \u1234\u123499\u{123456}\u{12345699}';
|
||||
// clients other grammars would show through, losing the benefit from having
|
||||
// resolved the code).
|
||||
final content = '''
|
||||
void f() {
|
||||
int a;
|
||||
a.foo().bar.baz();
|
||||
void f() {
|
||||
int a;
|
||||
a.foo().bar.baz();
|
||||
|
||||
dynamic b;
|
||||
b.foo().bar.baz();
|
||||
}
|
||||
''';
|
||||
dynamic b;
|
||||
b.foo().bar.baz();
|
||||
}
|
||||
''';
|
||||
|
||||
final expected = [
|
||||
_Token(
|
||||
@@ -1405,8 +1413,9 @@ const string3 = 'unicode \u1234\u123499\u{123456}\u{12345699}';
|
||||
}
|
||||
|
||||
Future<void> _verifyTokens(String content, List<_Token> expected) async {
|
||||
final code = TestCode.parse(content);
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(content));
|
||||
await openFile(mainFileUri, code.code);
|
||||
|
||||
final tokens = await getSemanticTokens(mainFileUri);
|
||||
final decoded = _decodeSemanticTokens(content, tokens);
|
||||
@@ -1415,12 +1424,12 @@ const string3 = 'unicode \u1234\u123499\u{123456}\u{12345699}';
|
||||
|
||||
Future<void> _verifyTokensInRange(
|
||||
String content, List<_Token> expected) async {
|
||||
final code = TestCode.parse(content);
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(content));
|
||||
await openFile(mainFileUri, code.code);
|
||||
|
||||
final tokens =
|
||||
await getSemanticTokensRange(mainFileUri, rangeFromMarkers(content));
|
||||
final decoded = _decodeSemanticTokens(withoutMarkers(content), tokens);
|
||||
final tokens = await getSemanticTokensRange(mainFileUri, code.range.range);
|
||||
final decoded = _decodeSemanticTokens(code.code, tokens);
|
||||
expect(decoded, equals(expected));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analysis_server/lsp_protocol/protocol.dart';
|
||||
import 'package:analyzer/src/test_utilities/test_code_format.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../utils/test_code_extensions.dart';
|
||||
import 'server_abstract.dart';
|
||||
|
||||
void main() {
|
||||
@@ -29,56 +31,56 @@ class TypeDefinitionTest extends AbstractLspAnalysisServerTest {
|
||||
}
|
||||
|
||||
Future<void> test_currentFile() async {
|
||||
final contents = '''
|
||||
class [[A]] {}
|
||||
final code = TestCode.parse('''
|
||||
class /*[0*/A/*0]*/ {}
|
||||
|
||||
final [[a^]] = A();
|
||||
''';
|
||||
final /*[1*/a^/*1]*/ = A();
|
||||
''');
|
||||
|
||||
final ranges = rangesFromMarkers(contents);
|
||||
final ranges = code.ranges.ranges;
|
||||
final targetRange = ranges[0];
|
||||
final originRange = ranges[1];
|
||||
final result = await _getResult(contents);
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, originRange);
|
||||
expect(result.targetUri, mainFileUri);
|
||||
expect(result.targetSelectionRange, targetRange);
|
||||
expect(result.targetRange, rangeOfString(contents, 'class A {}'));
|
||||
expect(result.targetRange, rangeOfString(code.code, 'class A {}'));
|
||||
}
|
||||
|
||||
Future<void> test_doubleLiteral() async {
|
||||
final contents = '''
|
||||
const a = [[12^.3]];
|
||||
''';
|
||||
final code = TestCode.parse('''
|
||||
const a = [!12^.3!];
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'double');
|
||||
}
|
||||
|
||||
Future<void> test_getter() async {
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
class A {
|
||||
String get aaa => '';
|
||||
}
|
||||
|
||||
void f() {
|
||||
final a = A();
|
||||
print(a.[[a^aa]]);
|
||||
print(a.[!a^aa!]);
|
||||
}
|
||||
''';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_intLiteral() async {
|
||||
final contents = '''
|
||||
const a = [[12^3]];
|
||||
''';
|
||||
final code = TestCode.parse('''
|
||||
const a = [!12^3!];
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'int');
|
||||
}
|
||||
|
||||
@@ -87,163 +89,163 @@ const a = [[12^3]];
|
||||
Future<void> test_location() async {
|
||||
setLocationLinkSupport(false);
|
||||
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
const a^ = 'test string';
|
||||
''';
|
||||
''');
|
||||
|
||||
final result = await _getLocationResult(contents);
|
||||
final result = await _getLocationResult(code);
|
||||
expect(result.uri, sdkCoreUri);
|
||||
_expectNameRange(result.range, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_nonDartFile() async {
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
const a = '^';
|
||||
''';
|
||||
''');
|
||||
|
||||
newFile(pubspecFilePath, withoutMarkers(contents));
|
||||
newFile(pubspecFilePath, code.code);
|
||||
await initialize();
|
||||
final results = await getTypeDefinitionAsLocation(
|
||||
mainFileUri, positionFromMarker(contents));
|
||||
final results =
|
||||
await getTypeDefinitionAsLocation(mainFileUri, code.position.position);
|
||||
expect(results, isEmpty);
|
||||
}
|
||||
|
||||
Future<void> test_otherFile() async {
|
||||
final otherFilePath = join(projectFolderPath, 'lib', 'other.dart');
|
||||
final otherFileUri = pathContext.toUri(otherFilePath);
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
import 'other.dart';
|
||||
|
||||
final [[a^]] = A();
|
||||
''';
|
||||
final [!a^!] = A();
|
||||
''');
|
||||
|
||||
final otherContents = '''
|
||||
class [[A]] {}
|
||||
''';
|
||||
final otherCode = TestCode.parse('''
|
||||
class [!A!] {}
|
||||
''');
|
||||
|
||||
newFile(otherFilePath, withoutMarkers(otherContents));
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
newFile(otherFilePath, otherCode.code);
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
expect(result.targetUri, otherFileUri);
|
||||
expect(result.targetSelectionRange, rangeFromMarkers(otherContents));
|
||||
expect(result.targetRange, rangeOfString(otherContents, 'class A {}'));
|
||||
expect(result.targetSelectionRange, otherCode.range.range);
|
||||
expect(result.targetRange, rangeOfString(otherCode.code, 'class A {}'));
|
||||
}
|
||||
|
||||
Future<void> test_parameter() async {
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
void f(String a) {
|
||||
f([['te^st']]);
|
||||
f([!'te^st'!]);
|
||||
}
|
||||
''';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_parameterName() async {
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
void f({String a}) {
|
||||
f([[a^]]: 'test');
|
||||
f([!a^!]: 'test');
|
||||
}
|
||||
''';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_setter() async {
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
class A {
|
||||
set aaa(String value) {}
|
||||
}
|
||||
|
||||
void f() {
|
||||
final a = A();
|
||||
a.[[a^aa]] = '';
|
||||
a.[!a^aa!] = '';
|
||||
}
|
||||
''';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_stringLiteral() async {
|
||||
final contents = '''
|
||||
const a = [['te^st string']];
|
||||
''';
|
||||
final code = TestCode.parse('''
|
||||
const a = [!'te^st string'!];
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_type() async {
|
||||
final contents = '''
|
||||
[[St^ring]] a = '';
|
||||
''';
|
||||
final code = TestCode.parse('''
|
||||
[!St^ring!] a = '';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_unopenedFile() async {
|
||||
final contents = '''
|
||||
const a = [['^']];
|
||||
''';
|
||||
final code = TestCode.parse('''
|
||||
const a = [!'^'!];
|
||||
''');
|
||||
|
||||
newFile(mainFilePath, withoutMarkers(contents));
|
||||
final result = await _getResult(contents, inOpenFile: false);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
newFile(mainFilePath, code.code);
|
||||
final result = await _getResult(code, inOpenFile: false);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_variableDeclaration() async {
|
||||
final contents = '''
|
||||
const [[a^]] = 'test string';
|
||||
''';
|
||||
final code = TestCode.parse('''
|
||||
const [!a^!] = 'test string';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_variableDeclaration_inferredType() async {
|
||||
final contents = '''
|
||||
var [[a^]] = 'test string';
|
||||
''';
|
||||
final code = TestCode.parse('''
|
||||
var [!a^!] = 'test string';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_variableReference() async {
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
void f() {
|
||||
const a = 'test string';
|
||||
print([[a^]]);
|
||||
print([!a^!]);
|
||||
}
|
||||
''';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
Future<void> test_variableReference_inferredType() async {
|
||||
final contents = '''
|
||||
final code = TestCode.parse('''
|
||||
void f() {
|
||||
var a = 'test string';
|
||||
print([[a^]]);
|
||||
print([!a^!]);
|
||||
}
|
||||
''';
|
||||
''');
|
||||
|
||||
final result = await _getResult(contents);
|
||||
expect(result.originSelectionRange, rangeFromMarkers(contents));
|
||||
final result = await _getResult(code);
|
||||
expect(result.originSelectionRange, code.range.range);
|
||||
_expectSdkCoreType(result, 'String');
|
||||
}
|
||||
|
||||
@@ -284,26 +286,26 @@ void f() {
|
||||
}
|
||||
|
||||
/// Gets the type definition as an LSP Location object.
|
||||
Future<Location> _getLocationResult(String contents) async {
|
||||
Future<Location> _getLocationResult(TestCode code) async {
|
||||
await initialize();
|
||||
await openFile(mainFileUri, withoutMarkers(contents));
|
||||
final results = await getTypeDefinitionAsLocation(
|
||||
mainFileUri, positionFromMarker(contents));
|
||||
await openFile(mainFileUri, code.code);
|
||||
final results =
|
||||
await getTypeDefinitionAsLocation(mainFileUri, code.position.position);
|
||||
return results.single;
|
||||
}
|
||||
|
||||
/// Advertises support for the LSP LocationLink type and gets the type
|
||||
/// definition using that.
|
||||
Future<LocationLink> _getResult(String contents,
|
||||
Future<LocationLink> _getResult(TestCode code,
|
||||
{Uri? fileUri, bool inOpenFile = true}) async {
|
||||
fileUri ??= mainFileUri;
|
||||
await initialize();
|
||||
if (inOpenFile) {
|
||||
await openFile(fileUri, withoutMarkers(contents));
|
||||
await openFile(fileUri, code.code);
|
||||
}
|
||||
final results = await getTypeDefinitionAsLocationLinks(
|
||||
mainFileUri,
|
||||
positionFromMarker(contents),
|
||||
code.position.position,
|
||||
);
|
||||
return results.single;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analysis_server/lsp_protocol/protocol.dart';
|
||||
import 'package:analyzer/src/test_utilities/test_code_format.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../tool/lsp_spec/matchers.dart';
|
||||
import '../utils/test_code_extensions.dart';
|
||||
import 'server_abstract.dart';
|
||||
|
||||
void main() {
|
||||
@@ -19,9 +21,10 @@ void main() {
|
||||
class WorkspaceSymbolsTest extends AbstractLspAnalysisServerTest {
|
||||
Future<void> test_cancellation() async {
|
||||
const content = '''
|
||||
void f() {}
|
||||
''';
|
||||
newFile(mainFilePath, withoutMarkers(content));
|
||||
void f() {}
|
||||
''';
|
||||
final code = TestCode.parse(content);
|
||||
newFile(mainFilePath, code.code);
|
||||
await initialize();
|
||||
|
||||
final symbolsRequest1 = makeRequest(
|
||||
@@ -92,10 +95,11 @@ class WorkspaceSymbolsTest extends AbstractLspAnalysisServerTest {
|
||||
|
||||
Future<void> test_extensions() async {
|
||||
const content = '''
|
||||
extension StringExtensions on String {}
|
||||
extension on String {}
|
||||
''';
|
||||
newFile(mainFilePath, withoutMarkers(content));
|
||||
extension StringExtensions on String {}
|
||||
extension on String {}
|
||||
''';
|
||||
final code = TestCode.parse(content);
|
||||
newFile(mainFilePath, code.code);
|
||||
await initialize();
|
||||
|
||||
final symbols = await getWorkspaceSymbols('S');
|
||||
@@ -112,7 +116,8 @@ class WorkspaceSymbolsTest extends AbstractLspAnalysisServerTest {
|
||||
const content = r'''
|
||||
extension type MyExtensionType(int it) {}
|
||||
''';
|
||||
newFile(mainFilePath, withoutMarkers(content));
|
||||
final code = TestCode.parse(content);
|
||||
newFile(mainFilePath, code.code);
|
||||
await initialize();
|
||||
|
||||
final symbols = await getWorkspaceSymbols('MyExt');
|
||||
@@ -129,7 +134,8 @@ extension type E(int it) {
|
||||
void foo() {}
|
||||
}
|
||||
''';
|
||||
newFile(mainFilePath, withoutMarkers(content));
|
||||
final code = TestCode.parse(content);
|
||||
newFile(mainFilePath, code.code);
|
||||
await initialize();
|
||||
|
||||
final symbols = await getWorkspaceSymbols('foo');
|
||||
@@ -142,14 +148,15 @@ extension type E(int it) {
|
||||
|
||||
Future<void> test_fullMatch() async {
|
||||
const content = '''
|
||||
[[String topLevel = '']];
|
||||
class MyClass {
|
||||
int myField;
|
||||
MyClass(this.myField);
|
||||
myMethod() {}
|
||||
}
|
||||
''';
|
||||
newFile(mainFilePath, withoutMarkers(content));
|
||||
[!String topLevel = ''!];
|
||||
class MyClass {
|
||||
int myField;
|
||||
MyClass(this.myField);
|
||||
myMethod() {}
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(content);
|
||||
newFile(mainFilePath, code.code);
|
||||
await initialize();
|
||||
|
||||
final symbols = await getWorkspaceSymbols('topLevel');
|
||||
@@ -158,23 +165,24 @@ extension type E(int it) {
|
||||
expect(topLevel.kind, equals(SymbolKind.Variable));
|
||||
expect(topLevel.containerName, isNull);
|
||||
expect(topLevel.location.uri, equals(mainFileUri));
|
||||
expect(topLevel.location.range, equals(rangeFromMarkers(content)));
|
||||
expect(topLevel.location.range, equals(code.range.range));
|
||||
|
||||
// Ensure we didn't get some things that definitely do not match.
|
||||
// Ensure we didn't get some things that definitely do not match.
|
||||
expect(symbols.any((s) => s.name.contains('MyClass')), isFalse);
|
||||
expect(symbols.any((s) => s.name.contains('myMethod')), isFalse);
|
||||
}
|
||||
|
||||
Future<void> test_fuzzyMatch() async {
|
||||
const content = '''
|
||||
String topLevel = '';
|
||||
class MyClass {
|
||||
[[int myField]];
|
||||
MyClass(this.myField);
|
||||
myMethod() {}
|
||||
}
|
||||
''';
|
||||
newFile(mainFilePath, withoutMarkers(content));
|
||||
String topLevel = '';
|
||||
class MyClass {
|
||||
[!int myField!];
|
||||
MyClass(this.myField);
|
||||
myMethod() {}
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(content);
|
||||
newFile(mainFilePath, code.code);
|
||||
await initialize();
|
||||
|
||||
// meld should match myField
|
||||
@@ -184,7 +192,7 @@ extension type E(int it) {
|
||||
expect(field.kind, equals(SymbolKind.Field));
|
||||
expect(field.containerName, equals('MyClass'));
|
||||
expect(field.location.uri, equals(mainFileUri));
|
||||
expect(field.location.range, equals(rangeFromMarkers(content)));
|
||||
expect(field.location.range, equals(code.range.range));
|
||||
|
||||
// Ensure we didn't get some things that definitely do not match.
|
||||
expect(symbols.any((s) => s.name.contains('MyClass')), isFalse);
|
||||
@@ -238,19 +246,20 @@ extension type E(int it) {
|
||||
|
||||
Future<void> test_partialMatch() async {
|
||||
const content = '''
|
||||
String topLevel = '';
|
||||
class MyClass {
|
||||
[[int myField]];
|
||||
MyClass(this.myField);
|
||||
[[myMethod() {}]]
|
||||
[[myMethodWithArgs(int a) {}]]
|
||||
}
|
||||
''';
|
||||
newFile(mainFilePath, withoutMarkers(content));
|
||||
String topLevel = '';
|
||||
class MyClass {
|
||||
/*[0*/int myField/*0]*/;
|
||||
MyClass(this.myField);
|
||||
/*[1*/myMethod() {}/*1]*/
|
||||
/*[2*/myMethodWithArgs(int a) {}/*2]*/
|
||||
}
|
||||
''';
|
||||
final code = TestCode.parse(content);
|
||||
newFile(mainFilePath, code.code);
|
||||
await initialize();
|
||||
|
||||
final symbols = await getWorkspaceSymbols('my');
|
||||
final ranges = rangesFromMarkers(content);
|
||||
final ranges = code.ranges.ranges;
|
||||
final fieldRange = ranges[0];
|
||||
final methodRange = ranges[1];
|
||||
final methodWithArgsRange = ranges[2];
|
||||
|
||||
Reference in New Issue
Block a user